summaryrefslogtreecommitdiffstats
path: root/kwin/clients/quartz
diff options
context:
space:
mode:
Diffstat (limited to 'kwin/clients/quartz')
-rw-r--r--kwin/clients/quartz/Makefile.am23
-rw-r--r--kwin/clients/quartz/config/Makefile.am16
-rw-r--r--kwin/clients/quartz/config/config.cpp104
-rw-r--r--kwin/clients/quartz/config/config.h47
-rw-r--r--kwin/clients/quartz/quartz.cpp797
-rw-r--r--kwin/clients/quartz/quartz.desktop39
-rw-r--r--kwin/clients/quartz/quartz.h95
7 files changed, 1121 insertions, 0 deletions
diff --git a/kwin/clients/quartz/Makefile.am b/kwin/clients/quartz/Makefile.am
new file mode 100644
index 000000000..d66643ba5
--- /dev/null
+++ b/kwin/clients/quartz/Makefile.am
@@ -0,0 +1,23 @@
+
+INCLUDES = -I$(srcdir)/../../lib $(all_includes)
+
+SUBDIRS = . config
+
+kde_module_LTLIBRARIES = kwin3_quartz.la
+
+kwin3_quartz_la_SOURCES = quartz.cpp
+kwin3_quartz_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
+kwin3_quartz_la_LIBADD = $(LIB_KDEUI) ../../lib/libkdecorations.la
+
+METASOURCES = AUTO
+noinst_HEADERS = quartz.h
+
+lnkdir = $(kde_datadir)/kwin/
+lnk_DATA = quartz.desktop
+
+EXTRA_DIST = $(lnk_DATA)
+
+
+###KMAKE-start (don't edit or delete this block)
+
+###KMAKE-end
diff --git a/kwin/clients/quartz/config/Makefile.am b/kwin/clients/quartz/config/Makefile.am
new file mode 100644
index 000000000..eb64880ee
--- /dev/null
+++ b/kwin/clients/quartz/config/Makefile.am
@@ -0,0 +1,16 @@
+INCLUDES = $(all_includes)
+
+kde_module_LTLIBRARIES = kwin_quartz_config.la
+
+kwin_quartz_config_la_SOURCES = config.cpp
+kwin_quartz_config_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
+kwin_quartz_config_la_LIBADD = $(LIB_KDEUI)
+
+METASOURCES = AUTO
+noinst_HEADERS = config.h
+
+lnkdir = $(kde_datadir)/kwin/
+
+###KMAKE-start (don't edit or delete this block)
+
+###KMAKE-end
diff --git a/kwin/clients/quartz/config/config.cpp b/kwin/clients/quartz/config/config.cpp
new file mode 100644
index 000000000..8c7070b9d
--- /dev/null
+++ b/kwin/clients/quartz/config/config.cpp
@@ -0,0 +1,104 @@
+/*
+ *
+ * This file contains the quartz configuration widget
+ *
+ * Copyright (c) 2001
+ * Karol Szwed <gallium@kde.org>
+ * http://gallium.n3.net/
+ */
+
+#include "config.h"
+#include <kglobal.h>
+#include <qwhatsthis.h>
+#include <klocale.h>
+
+
+extern "C"
+{
+ KDE_EXPORT QObject* allocate_config( KConfig* conf, QWidget* parent )
+ {
+ return(new QuartzConfig(conf, parent));
+ }
+}
+
+
+/* NOTE:
+ * 'conf' is a pointer to the kwindecoration modules open kwin config,
+ * and is by default set to the "Style" group.
+ *
+ * 'parent' is the parent of the QObject, which is a VBox inside the
+ * Configure tab in kwindecoration
+ */
+
+QuartzConfig::QuartzConfig( KConfig* conf, QWidget* parent )
+ : QObject( parent )
+{
+ quartzConfig = new KConfig("kwinquartzrc");
+ KGlobal::locale()->insertCatalogue("kwin_clients");
+ gb = new QVBox( parent );
+ cbColorBorder = new QCheckBox(
+ i18n("Draw window frames using &titlebar colors"), gb );
+ QWhatsThis::add( cbColorBorder,
+ i18n("When selected, the window decoration borders "
+ "are drawn using the titlebar colors; otherwise, they are "
+ "drawn using normal border colors instead.") );
+ cbExtraSmall = new QCheckBox( i18n("Quartz &extra slim"), gb );
+ QWhatsThis::add( cbExtraSmall,
+ i18n("Quartz window decorations with extra-small title bar.") );
+ // Load configuration options
+ load( conf );
+
+ // Ensure we track user changes properly
+ connect( cbColorBorder, SIGNAL(clicked()), this, SLOT(slotSelectionChanged()) );
+ connect( cbExtraSmall, SIGNAL(clicked()), this, SLOT(slotSelectionChanged()) );
+
+ // Make the widgets visible in kwindecoration
+ gb->show();
+}
+
+
+QuartzConfig::~QuartzConfig()
+{
+ delete gb;
+ delete quartzConfig;
+}
+
+
+void QuartzConfig::slotSelectionChanged()
+{
+ emit changed();
+}
+
+
+// Loads the configurable options from the kwinrc config file
+// It is passed the open config from kwindecoration to improve efficiency
+void QuartzConfig::load( KConfig* /*conf*/ )
+{
+ quartzConfig->setGroup("General");
+ bool override = quartzConfig->readBoolEntry( "UseTitleBarBorderColors", true );
+ cbColorBorder->setChecked( override );
+ override = quartzConfig->readBoolEntry( "UseQuartzExtraSlim", false );
+ cbExtraSmall->setChecked( override );
+}
+
+
+// Saves the configurable options to the kwinrc config file
+void QuartzConfig::save( KConfig* /*conf*/ )
+{
+ quartzConfig->setGroup("General");
+ quartzConfig->writeEntry( "UseTitleBarBorderColors", cbColorBorder->isChecked() );
+ quartzConfig->writeEntry( "UseQuartzExtraSlim", cbExtraSmall->isChecked() );
+ // Ensure others trying to read this config get updated
+ quartzConfig->sync();
+}
+
+
+// Sets UI widget defaults which must correspond to style defaults
+void QuartzConfig::defaults()
+{
+ cbColorBorder->setChecked( true );
+ cbExtraSmall->setChecked( false );
+}
+
+#include "config.moc"
+// vim: ts=4
diff --git a/kwin/clients/quartz/config/config.h b/kwin/clients/quartz/config/config.h
new file mode 100644
index 000000000..815cc9644
--- /dev/null
+++ b/kwin/clients/quartz/config/config.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * This file contains the quartz configuration widget
+ *
+ * Copyright (c) 2001
+ * Karol Szwed <gallium@kde.org>
+ * http://gallium.n3.net/
+ */
+
+#ifndef __KDE_QUARTZCONFIG_H
+#define __KDE_QUARTZCONFIG_H
+
+#include <qcheckbox.h>
+#include <qvbox.h>
+#include <kconfig.h>
+
+class QuartzConfig: public QObject
+{
+ Q_OBJECT
+
+ public:
+ QuartzConfig( KConfig* conf, QWidget* parent );
+ ~QuartzConfig();
+
+ // These public signals/slots work similar to KCM modules
+ signals:
+ void changed();
+
+ public slots:
+ void load( KConfig* conf );
+ void save( KConfig* conf );
+ void defaults();
+
+ protected slots:
+ void slotSelectionChanged(); // Internal use
+
+ private:
+ KConfig* quartzConfig;
+ QCheckBox* cbColorBorder;
+ QCheckBox* cbExtraSmall;
+ QVBox* gb;
+};
+
+
+#endif
+
+// vim: ts=4
diff --git a/kwin/clients/quartz/quartz.cpp b/kwin/clients/quartz/quartz.cpp
new file mode 100644
index 000000000..857971780
--- /dev/null
+++ b/kwin/clients/quartz/quartz.cpp
@@ -0,0 +1,797 @@
+/*
+ *
+ * Gallium-Quartz KWin client
+ *
+ * Copyright (C) 2005 Sandro Giessl <sandro@giessl.com>
+ * Copyright 2001
+ * Karol Szwed <gallium@kde.org>
+ * http://gallium.n3.net/
+ *
+ * Based on the KDE default client.
+ *
+ * Includes mini titlebars for ToolWindow Support.
+ * Button positions are now customizable.
+ *
+ */
+
+#include <kconfig.h>
+#include <kdrawutil.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kpixmapeffect.h>
+#include <qbitmap.h>
+#include <qdrawutil.h>
+#include <qimage.h>
+#include <qapplication.h>
+
+#include "quartz.h"
+
+
+namespace Quartz {
+
+static const unsigned char iconify_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00,
+ 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+static const unsigned char close_bits[] = {
+ 0x00, 0x00, 0x86, 0x01, 0xcc, 0x00, 0x78, 0x00, 0x30, 0x00, 0x78, 0x00,
+ 0xcc, 0x00, 0x86, 0x01, 0x00, 0x00, 0x00, 0x00};
+
+static const unsigned char maximize_bits[] = {
+ 0xff, 0x01, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, 0x00, 0x00};
+
+static const unsigned char minmax_bits[] = {
+ 0xfc, 0x00, 0xfc, 0x00, 0x84, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xe1, 0x00,
+ 0x21, 0x00, 0x21, 0x00, 0x3f, 0x00, 0x00, 0x00};
+
+static const unsigned char question_bits[] = {
+ 0x00, 0x00, 0x3c, 0x00, 0x66, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00,
+ 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00};
+
+static const unsigned char pindown_white_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x1f, 0xa0, 0x03,
+ 0xb0, 0x01, 0x30, 0x01, 0xf0, 0x00, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const unsigned char pindown_gray_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
+ 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x80, 0x07, 0xc0, 0x03, 0xe0, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const unsigned char pindown_dgray_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x10, 0x70, 0x20, 0x50, 0x20,
+ 0x48, 0x30, 0xc8, 0x38, 0x08, 0x1f, 0x08, 0x18, 0x10, 0x1c, 0x10, 0x0e,
+ 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const unsigned char pinup_white_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x11,
+ 0x3f, 0x15, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const unsigned char pinup_gray_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x0a, 0xbf, 0x0a, 0x80, 0x15, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const unsigned char pinup_dgray_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x40, 0x31, 0x40, 0x2e,
+ 0x40, 0x20, 0x40, 0x20, 0x7f, 0x2a, 0x40, 0x3f, 0xc0, 0x31, 0xc0, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const unsigned char above_on_bits[] = {
+ 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0x30, 0x00, 0xfc, 0x00, 0x78, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const unsigned char above_off_bits[] = {
+ 0x30, 0x00, 0x78, 0x00, 0xfc, 0x00, 0x30, 0x00, 0xfe, 0x01, 0xfe, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static const unsigned char below_on_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x00, 0xfc, 0x00,
+ 0x30, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0x00, 0x00};
+
+static const unsigned char below_off_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01,
+ 0x30, 0x00, 0xfc, 0x00, 0x78, 0x00, 0x30, 0x00};
+
+static const unsigned char shade_on_bits[] = {
+ 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0x02, 0x01, 0x02, 0x01,
+ 0x02, 0x01, 0x02, 0x01, 0xfe, 0x01, 0x00, 0x00};
+
+static const unsigned char shade_off_bits[] = {
+ 0x00, 0x00, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+
+///////////////////////////////////////////////////////////////////////////
+
+// Titlebar button positions
+bool onAllDesktopsButtonOnLeft = true;
+bool coloredFrame = true;
+bool extraSlim = false;
+
+KPixmap* titleBlocks = NULL;
+KPixmap* ititleBlocks = NULL;
+KPixmap* pinDownPix = NULL;
+KPixmap* pinUpPix = NULL;
+KPixmap* ipinDownPix = NULL;
+KPixmap* ipinUpPix = NULL;
+static int normalTitleHeight;
+static int toolTitleHeight;
+static int borderWidth;
+
+bool quartz_initialized = false;
+QuartzHandler* clientHandler;
+
+///////////////////////////////////////////////////////////////////////////
+
+
+QuartzHandler::QuartzHandler()
+{
+ quartz_initialized = false;
+ readConfig();
+ createPixmaps();
+ quartz_initialized = true;
+}
+
+
+QuartzHandler::~QuartzHandler()
+{
+ quartz_initialized = false;
+ freePixmaps();
+}
+
+
+KDecoration* QuartzHandler::createDecoration( KDecorationBridge* bridge )
+{
+ return new QuartzClient( bridge, this );
+}
+
+
+bool QuartzHandler::reset(unsigned long changed)
+{
+ quartz_initialized = false;
+ freePixmaps();
+ readConfig();
+ createPixmaps();
+ quartz_initialized = true;
+
+ // Do we need to "hit the wooden hammer" ?
+ bool needHardReset = true;
+ if (changed & SettingColors)
+ {
+ needHardReset = false;
+ } else if (changed & SettingButtons) {
+ // handled by KCommonDecoration
+ needHardReset = false;
+ }
+
+ if (needHardReset) {
+ return true;
+ } else {
+ resetDecorations(changed);
+ return false;
+ }
+ return true;
+}
+
+
+bool QuartzHandler::supports( Ability ability )
+{
+ switch( ability )
+ {
+ case AbilityAnnounceButtons:
+ case AbilityButtonMenu:
+ case AbilityButtonOnAllDesktops:
+ case AbilityButtonHelp:
+ case AbilityButtonMinimize:
+ case AbilityButtonMaximize:
+ case AbilityButtonClose:
+ case AbilityButtonAboveOthers:
+ case AbilityButtonBelowOthers:
+ case AbilityButtonShade:
+ case AbilityButtonSpacer:
+ return true;
+ default:
+ return false;
+ };
+}
+
+
+void QuartzHandler::readConfig()
+{
+ KConfig conf("kwinquartzrc");
+ conf.setGroup("General");
+ coloredFrame = conf.readBoolEntry( "UseTitleBarBorderColors", true );
+ extraSlim = conf.readBoolEntry( "UseQuartzExtraSlim", false );
+
+ // A small hack to make the on all desktops button look nicer
+ onAllDesktopsButtonOnLeft = KDecoration::options()->titleButtonsLeft().contains( 'S' );
+ if ( QApplication::reverseLayout() )
+ onAllDesktopsButtonOnLeft = !onAllDesktopsButtonOnLeft;
+ switch(options()->preferredBorderSize(this)) {
+ case BorderLarge:
+ borderWidth = 8;
+ break;
+ case BorderVeryLarge:
+ borderWidth = 12;
+ break;
+ case BorderHuge:
+ borderWidth = 18;
+ break;
+ case BorderVeryHuge:
+ borderWidth = 27;
+ break;
+ case BorderOversized:
+ borderWidth = 40;
+ break;
+ case BorderTiny:
+ case BorderNormal:
+ default:
+ borderWidth = extraSlim?2:4;
+ }
+
+ normalTitleHeight = QFontMetrics(options()->font(true)).height();
+ int nTH_limit=extraSlim?14:18;
+ normalTitleHeight = QFontMetrics(options()->font(true)).height()-(extraSlim?1:0);
+ if (normalTitleHeight < nTH_limit) normalTitleHeight = nTH_limit;
+ if (normalTitleHeight < borderWidth) normalTitleHeight = borderWidth;
+
+ toolTitleHeight = QFontMetrics(options()->font(true, true)).height();
+ if (toolTitleHeight < 12) toolTitleHeight = 12;
+ if (toolTitleHeight < borderWidth) toolTitleHeight = borderWidth;
+}
+
+
+// This does the colour transition magic. (You say "Oh, is that it?")
+// This may be made configurable at a later stage
+void QuartzHandler::drawBlocks( KPixmap *pi, KPixmap &p, const QColor &c1, const QColor &c2 )
+{
+ QPainter px;
+
+ px.begin( pi );
+
+ // Draw a background gradient first
+ KPixmapEffect::gradient(p, c1, c2, KPixmapEffect::HorizontalGradient);
+
+ int factor = (pi->height()-2)/4;
+ int square = factor - (factor+2)/4;
+
+ int x = pi->width() - 5*factor - square;
+ int y = (pi->height() - 4*factor)/2;
+
+ px.fillRect( x, y, square, square, c1.light(120) );
+ px.fillRect( x, y+factor, square, square, c1 );
+ px.fillRect( x, y+2*factor, square, square, c1.light(110) );
+ px.fillRect( x, y+3*factor, square, square, c1 );
+
+ px.fillRect( x+factor, y, square, square, c1.light(110) );
+ px.fillRect( x+factor, y+factor, square, square, c2.light(110) );
+ px.fillRect( x+factor, y+2*factor, square, square, c1.light(120) );
+ px.fillRect( x+factor, y+3*factor, square, square, c2.light(130) );
+
+ px.fillRect( x+2*factor, y+factor, square, square, c1.light(110) );
+ px.fillRect( x+2*factor, y+2*factor, square, square, c2.light(120) );
+ px.fillRect( x+2*factor, y+3*factor, square, square, c2.light(150) );
+
+ px.fillRect( x+3*factor, y, square, square, c1.dark(110) );
+ px.fillRect( x+3*factor, y+2*factor, square, square, c2.light(120) );
+ px.fillRect( x+3*factor, y+3*factor, square, square, c1.dark(120) );
+
+ px.fillRect( x+4*factor, y+factor, square, square, c1.light(110) );
+ px.fillRect( x+4*factor, y+3*factor, square, square, c1.dark(110) );
+
+ px.fillRect( x+5*factor, y+2*factor, square, square, c2.light(120));
+ px.fillRect( x+5*factor, y+3*factor, square, square, c2.light(110) );
+}
+
+
+// This paints the button pixmaps upon loading the style.
+void QuartzHandler::createPixmaps()
+{
+ // Obtain titlebar blend colours, and create the block stuff on pixmaps.
+ QColorGroup g2 = options()->colorGroup(ColorTitleBlend, true);
+ QColor c2 = g2.background();
+ g2 = options()->colorGroup(ColorTitleBar, true );
+ QColor c = g2.background().light(130);
+
+ titleBlocks = new KPixmap();
+ titleBlocks->resize( normalTitleHeight*25/18, normalTitleHeight );
+ drawBlocks( titleBlocks, *titleBlocks, c, c2 );
+
+ g2 = options()->colorGroup(ColorTitleBlend, false);
+ c2 = g2.background();
+ g2 = options()->colorGroup(ColorTitleBar, false );
+ c = g2.background().light(130);
+
+ ititleBlocks = new KPixmap();
+ ititleBlocks->resize( normalTitleHeight*25/18, normalTitleHeight );
+ drawBlocks( ititleBlocks, *ititleBlocks, c, c2 );
+
+ // Set the on all desktops pin pixmaps;
+ QColorGroup g;
+ QPainter p;
+
+ g = options()->colorGroup( onAllDesktopsButtonOnLeft ? ColorTitleBar : ColorTitleBlend, true );
+ c = onAllDesktopsButtonOnLeft ? g.background().light(130) : g.background();
+ g2 = options()->colorGroup( ColorButtonBg, true );
+
+ pinUpPix = new KPixmap();
+ pinUpPix->resize(16, 16);
+ p.begin( pinUpPix );
+ p.fillRect( 0, 0, 16, 16, c);
+ kColorBitmaps( &p, g2, 0, 1, 16, 16, true, pinup_white_bits,
+ pinup_gray_bits, NULL, NULL, pinup_dgray_bits, NULL );
+ p.end();
+
+ pinDownPix = new KPixmap();
+ pinDownPix->resize(16, 16);
+ p.begin( pinDownPix );
+ p.fillRect( 0, 0, 16, 16, c);
+ kColorBitmaps( &p, g2, 0, 1, 16, 16, true, pindown_white_bits,
+ pindown_gray_bits, NULL, NULL, pindown_dgray_bits, NULL );
+ p.end();
+
+
+ // Inactive pins
+ g = options()->colorGroup( onAllDesktopsButtonOnLeft ? ColorTitleBar : ColorTitleBlend, false );
+ c = onAllDesktopsButtonOnLeft ? g.background().light(130) : g.background();
+ g2 = options()->colorGroup( ColorButtonBg, false );
+
+ ipinUpPix = new KPixmap();
+ ipinUpPix->resize(16, 16);
+ p.begin( ipinUpPix );
+ p.fillRect( 0, 0, 16, 16, c);
+ kColorBitmaps( &p, g2, 0, 1, 16, 16, true, pinup_white_bits,
+ pinup_gray_bits, NULL, NULL, pinup_dgray_bits, NULL );
+ p.end();
+
+ ipinDownPix = new KPixmap();
+ ipinDownPix->resize(16, 16);
+ p.begin( ipinDownPix );
+ p.fillRect( 0, 0, 16, 16, c);
+ kColorBitmaps( &p, g2, 0, 1, 16, 16, true, pindown_white_bits,
+ pindown_gray_bits, NULL, NULL, pindown_dgray_bits, NULL );
+ p.end();
+}
+
+
+void QuartzHandler::freePixmaps()
+{
+ delete titleBlocks;
+ delete ititleBlocks;
+
+ // On all desktops pin images
+ delete pinUpPix;
+ delete ipinUpPix;
+ delete pinDownPix;
+ delete ipinDownPix;
+}
+
+
+QValueList< QuartzHandler::BorderSize > QuartzHandler::borderSizes() const
+{ // the list must be sorted
+ return QValueList< BorderSize >() << BorderNormal << BorderLarge <<
+ BorderVeryLarge << BorderHuge << BorderVeryHuge << BorderOversized;
+}
+
+
+QuartzButton::QuartzButton(ButtonType type, QuartzClient *parent, const char *name)
+ : KCommonDecorationButton(type, parent, name)
+{
+ // Eliminate any possible background flicker
+ setBackgroundMode( QWidget::NoBackground );
+
+ deco = 0;
+}
+
+
+QuartzButton::~QuartzButton()
+{
+ delete deco;
+}
+
+void QuartzButton::reset(unsigned long changed)
+{
+ if (changed&DecorationReset || changed&ManualReset || changed&SizeChange || changed&StateChange) {
+ switch (type() ) {
+ case CloseButton:
+ setBitmap(close_bits);
+ break;
+ case HelpButton:
+ setBitmap(question_bits);
+ break;
+ case MinButton:
+ setBitmap(iconify_bits);
+ break;
+ case MaxButton:
+ setBitmap( isOn() ? minmax_bits : maximize_bits );
+ break;
+ case OnAllDesktopsButton:
+ setBitmap(0);
+ break;
+ case ShadeButton:
+ setBitmap( isOn() ? shade_on_bits : shade_off_bits );
+ break;
+ case AboveButton:
+ setBitmap( isOn() ? above_on_bits : above_off_bits );
+ break;
+ case BelowButton:
+ setBitmap( isOn() ? below_on_bits : below_off_bits );
+ break;
+ default:
+ setBitmap(0);
+ break;
+ }
+
+ this->update();
+ }
+}
+
+void QuartzButton::setBitmap(const unsigned char *bitmap)
+{
+ delete deco;
+ deco = 0;
+
+ if (bitmap) {
+ deco = new QBitmap(10, 10, bitmap, true);
+ deco->setMask( *deco );
+ repaint( false );
+ }
+}
+
+void QuartzButton::drawButton(QPainter *p)
+{
+ // Never paint if the pixmaps have not been created
+ if (!quartz_initialized)
+ return;
+
+ QColor c;
+
+ if (isLeft() )
+ c = KDecoration::options()->color(KDecoration::ColorTitleBar, decoration()->isActive()).light(130);
+ else
+ c = KDecoration::options()->color(KDecoration::ColorTitleBlend, decoration()->isActive());
+
+ // Fill the button background with an appropriate color
+ p->fillRect(0, 0, width(), height(), c );
+
+ // If we have a decoration bitmap, then draw that
+ // otherwise we paint a menu button (with mini icon), or a onAllDesktops button.
+ if( deco )
+ {
+ int xOff = (width()-10)/2;
+ int yOff = (height()-10)/2;
+ p->setPen( Qt::black );
+ p->drawPixmap(isDown() ? xOff+2: xOff+1, isDown() ? yOff+2 : yOff+1, *deco);
+ p->setPen( KDecoration::options()->color(KDecoration::ColorButtonBg, decoration()->isActive()).light(150) );
+ p->drawPixmap(isDown() ? xOff+1: xOff, isDown() ? yOff+1 : yOff, *deco);
+ } else
+ {
+ QPixmap btnpix;
+ int Offset = 0;
+
+ if (type() == OnAllDesktopsButton)
+ {
+ if (isDown())
+ Offset = 1;
+
+ // Select the right onAllDesktops button to paint
+ if (decoration()->isActive())
+ btnpix = isOn() ? *pinDownPix : *pinUpPix;
+ else
+ btnpix = isOn() ? *ipinDownPix : *ipinUpPix;
+
+ } else
+ btnpix = decoration()->icon().pixmap( QIconSet::Small, QIconSet::Normal);
+
+ // Shrink the miniIcon for tiny titlebars.
+ if ( height() < 16)
+ {
+ QPixmap tmpPix;
+
+ // Smooth scale the image
+ tmpPix.convertFromImage( btnpix.convertToImage().smoothScale(height(), height()));
+ p->drawPixmap( 0, 0, tmpPix );
+ } else {
+ Offset += (height() - 16)/2;
+ p->drawPixmap( Offset, Offset, btnpix );
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+QuartzClient::QuartzClient(KDecorationBridge* bridge, KDecorationFactory* factory)
+ : KCommonDecoration (bridge, factory)
+{
+}
+
+QString QuartzClient::visibleName() const
+{
+ return i18n("Quartz");
+}
+
+QString QuartzClient::defaultButtonsLeft() const
+{
+ return "M";
+}
+
+QString QuartzClient::defaultButtonsRight() const
+{
+ return "HIAX";
+}
+
+bool QuartzClient::decorationBehaviour(DecorationBehaviour behaviour) const
+{
+ switch (behaviour) {
+ case DB_MenuClose:
+ return false;
+
+ case DB_WindowMask:
+ return false;
+
+ case DB_ButtonHide:
+ return true;
+
+ default:
+ return KCommonDecoration::decorationBehaviour(behaviour);
+ }
+}
+
+int QuartzClient::layoutMetric(LayoutMetric lm, bool respectWindowState, const KCommonDecorationButton *btn) const
+{
+ bool maximized = maximizeMode()==MaximizeFull && !options()->moveResizeMaximizedWindows();
+
+ switch (lm) {
+ case LM_BorderLeft:
+ case LM_BorderRight:
+ case LM_BorderBottom:
+ case LM_TitleEdgeLeft:
+ case LM_TitleEdgeRight:
+ {
+ if (respectWindowState && maximized) {
+ return 0;
+ } else {
+ return borderSize;
+ }
+ }
+
+ case LM_TitleEdgeTop:
+ return borderSize-1;
+
+ case LM_TitleEdgeBottom:
+ return 1;
+
+ case LM_TitleBorderLeft:
+ case LM_TitleBorderRight:
+ return 5;
+
+ case LM_TitleHeight:
+ return titleHeight;
+
+ case LM_ButtonWidth:
+ case LM_ButtonHeight:
+ return titleHeight-2;
+
+ case LM_ButtonSpacing:
+ return 1;
+
+ case LM_ExplicitButtonSpacer:
+ return 3;
+
+ default:
+ return KCommonDecoration::layoutMetric(lm, respectWindowState, btn);
+ }
+}
+
+KCommonDecorationButton *QuartzClient::createButton(ButtonType type)
+{
+ switch (type) {
+ case MenuButton:
+ return new QuartzButton(MenuButton, this, "menu");
+
+ case OnAllDesktopsButton:
+ return new QuartzButton(OnAllDesktopsButton, this, "on_all_desktops");
+
+ case HelpButton:
+ return new QuartzButton(HelpButton, this, "help");
+
+ case MinButton:
+ return new QuartzButton(MinButton, this, "minimize");
+
+ case MaxButton:
+ return new QuartzButton(MaxButton, this, "maximize");
+
+ case CloseButton:
+ return new QuartzButton(CloseButton, this, "close");
+
+ case AboveButton:
+ return new QuartzButton(AboveButton, this, "above");
+
+ case BelowButton:
+ return new QuartzButton(BelowButton, this, "below");
+
+ case ShadeButton:
+ return new QuartzButton(ShadeButton, this, "shade");
+
+ default:
+ return 0;
+ }
+}
+
+
+void QuartzClient::init()
+{
+ // Finally, toolWindows look small
+ if ( isToolWindow() ) {
+ titleHeight = toolTitleHeight;
+ largeButtons = false;
+ }
+ else {
+ titleHeight = normalTitleHeight;
+ largeButtons = true;
+ }
+
+ borderSize = borderWidth;
+
+ KCommonDecoration::init();
+}
+
+void QuartzClient::reset( unsigned long changed )
+{
+ if (changed & SettingColors || changed & SettingFont)
+ {
+ // repaint the whole thing
+ widget()->repaint(false);
+ }
+
+ KCommonDecoration::reset(changed);
+}
+
+
+// Quartz Paint magic goes here.
+void QuartzClient::paintEvent( QPaintEvent* )
+{
+ // Never paint if the pixmaps have not been created
+ if (!quartz_initialized)
+ return;
+
+ const bool maxFull = (maximizeMode()==MaximizeFull) && !options()->moveResizeMaximizedWindows();
+
+ QColorGroup g;
+ QPainter p(widget());
+
+ // Obtain widget bounds.
+ QRect r(widget()->rect());
+ int x = r.x();
+ int y = r.y();
+ int x2 = r.width() - 1;
+ int y2 = r.height() - 1;
+ int w = r.width();
+ int h = r.height();
+
+ // Draw part of the frame that is the title color
+
+ if( coloredFrame )
+ g = options()->colorGroup(ColorTitleBar, isActive());
+ else
+ g = options()->colorGroup(ColorFrame, isActive());
+
+ // Draw outer highlights and lowlights
+ p.setPen( g.light().light(120) );
+ p.drawLine( x, y, x2-1, y );
+ p.drawLine( x, y+1, x, y2-1 );
+ p.setPen( g.dark().light(120) );
+ p.drawLine( x2, y, x2, y2 );
+ p.drawLine( x, y2, x2, y2 );
+
+ // Fill out the border edges
+ QColor frameColor;
+ if ( coloredFrame)
+ frameColor = g.background().light(130);
+ else
+ frameColor = g.background();
+ if (borderSize > 2) {
+ p.fillRect(x+1, y+1, w-2, borderSize-2, frameColor); // top
+ if (!maxFull) {
+ p.fillRect(x+1, y+h-(borderSize-1), w-2, borderSize-2, frameColor); // bottom
+ p.fillRect(x+1, y+borderSize-1, borderSize-1, h-2*(borderSize-1), frameColor); // left
+ p.fillRect(x+w-(borderSize), y+borderSize-1, borderSize-1, h-2*(borderSize-1), frameColor); // right
+ }
+ }
+
+ // Draw a frame around the wrapped widget.
+ p.setPen( g.background() );
+ if (maxFull) {
+ p.drawLine(x+1, y+titleHeight+(borderSize-1), w-2, y+titleHeight+(borderSize-1));
+ } else {
+ p.drawRect( x+(borderSize-1), y+titleHeight+(borderSize-1), w-2*(borderSize-1), h-titleHeight-2*(borderSize-1) );
+ }
+
+ // Drawing this extra line removes non-drawn areas when shaded
+ p.drawLine( x+borderSize, y2-borderSize, x2-borderSize, y2-borderSize);
+
+ // Highlight top corner
+ p.setPen( g.light().light(160) );
+ p.drawPoint( x, y );
+ p.setPen( g.light().light(140) );
+ p.drawPoint( x+1, y );
+ p.drawPoint( x, y+1 );
+
+ // Draw the title bar.
+ // ===================
+ int r_x, r_y, r_x2, r_y2;
+ widget()->rect().coords(&r_x, &r_y, &r_x2, &r_y2);
+ const int titleEdgeLeft = layoutMetric(LM_TitleEdgeLeft);
+ const int titleEdgeTop = layoutMetric(LM_TitleEdgeTop);
+ const int titleEdgeRight = layoutMetric(LM_TitleEdgeRight);
+ const int titleEdgeBottom = layoutMetric(LM_TitleEdgeBottom);
+ const int ttlHeight = layoutMetric(LM_TitleHeight);
+ const int titleEdgeBottomBottom = r_y+titleEdgeTop+ttlHeight+titleEdgeBottom-1;
+ r = QRect(r_x+titleEdgeLeft+buttonsLeftWidth(), r_y+titleEdgeTop,
+ r_x2-titleEdgeRight-buttonsRightWidth()-(r_x+titleEdgeLeft+buttonsLeftWidth()),
+ titleEdgeBottomBottom-(r_y+titleEdgeTop) );
+
+ // Obtain titlebar blend colours
+ QColor c1 = options()->color(ColorTitleBar, isActive() ).light(130);
+ QColor c2 = options()->color(ColorTitleBlend, isActive() );
+
+ // Create a disposable pixmap buffer for the titlebar
+ KPixmap* titleBuffer = new KPixmap;
+ titleBuffer->resize( maxFull?w-2:(w-2*(borderSize-1)), titleHeight );
+
+ QPainter p2( titleBuffer, this );
+
+ // subtract titleBlocks pixmap width and some
+ int rightoffset = r.x()+r.width()-titleBlocks->width()-borderSize;
+
+ p2.fillRect( 0, 0, w, r.height(), c1 );
+ p2.fillRect( rightoffset, 0, maxFull?w-rightoffset:w-rightoffset-2*(borderSize-1), r.height(), c2 );
+
+ // 8 bit displays will be a bit dithered, but they still look ok.
+ if ( isActive() )
+ p2.drawPixmap( rightoffset, 0, *titleBlocks );
+ else
+ p2.drawPixmap( rightoffset, 0, *ititleBlocks );
+
+ // Draw the title text on the pixmap, and with a smaller font
+ // for toolwindows than the default.
+ QFont fnt;
+ if ( largeButtons ) {
+ fnt = options()->font(true, false); // font not small
+ } else {
+ fnt = options()->font(true, true); // font small
+ fnt.setWeight( QFont::Normal ); // and disable bold
+ }
+ p2.setFont( fnt );
+
+ p2.setPen( options()->color(ColorFont, isActive() ));
+ p2.drawText(r.x()+4-borderSize, 0, r.width()-3, r.height(),
+ AlignLeft | AlignVCenter, caption() );
+ p2.end();
+
+ p.drawPixmap( maxFull?1:borderSize-1, borderSize-1, *titleBuffer );
+
+ delete titleBuffer;
+}
+
+}
+
+// Extended KWin plugin interface
+/////////////////////////////////
+extern "C"
+{
+ KDE_EXPORT KDecorationFactory *create_factory()
+ {
+ Quartz::clientHandler = new Quartz::QuartzHandler();
+ return Quartz::clientHandler;
+ }
+}
+
+
+
+#include "quartz.moc"
+// vim: ts=4
+// kate: space-indent off; tab-width 4;
diff --git a/kwin/clients/quartz/quartz.desktop b/kwin/clients/quartz/quartz.desktop
new file mode 100644
index 000000000..30a177973
--- /dev/null
+++ b/kwin/clients/quartz/quartz.desktop
@@ -0,0 +1,39 @@
+[Desktop Entry]
+Name=Quartz
+Name[az]=Kvarts
+Name[be]=Кварц
+Name[bn]=কোয়ার্ট্‌জ
+Name[csb]=Kwarc
+Name[cy]=Cwarts
+Name[eo]=Kvarco
+Name[es]=Cuarzo
+Name[eu]=Kuartzoa
+Name[fa]=کوارتز
+Name[ga]=Grianchloch
+Name[hi]=क्वार्ट्ज
+Name[hr]=Kvarc
+Name[ka]=კვარცი
+Name[kk]=Кварц
+Name[ko]=수정
+Name[lo]=ແບບຄວອທ
+Name[lv]=Kvarcs
+Name[mk]=Кварц
+Name[mt]=Kwartz
+Name[ne]=क्वार्ज
+Name[pl]=Kwarc
+Name[pt_BR]=Quartzo
+Name[ro]=Cuarț
+Name[ru]=Кварц
+Name[rw]=Ibuye
+Name[ta]=குவார்ட்ஸ்
+Name[te]=క్వార్జ్
+Name[tg]=Квартс
+Name[th]=แบบควอทซ์
+Name[tr]=Kuartz
+Name[uk]=Кварц
+Name[uz]=Chaqmoqtosh
+Name[uz@cyrillic]=Чақмоқтош
+Name[ven]=Musuku
+Name[vi]=Thạch anh
+Name[zh_TW]=石英
+X-KDE-Library=kwin3_quartz
diff --git a/kwin/clients/quartz/quartz.h b/kwin/clients/quartz/quartz.h
new file mode 100644
index 000000000..37f3dff6e
--- /dev/null
+++ b/kwin/clients/quartz/quartz.h
@@ -0,0 +1,95 @@
+/*
+ * Gallium-Quartz KWin client
+ *
+ * Copyright (C) 2005 Sandro Giessl <sandro@giessl.com>
+ * Copyright 2001
+ * Karol Szwed <gallium@kde.org>
+ * http://gallium.n3.net/
+ *
+ * Based on the KDE default client.
+ *
+ * Includes mini titlebars for ToolWindow Support.
+ * Button positions are now customizable.
+ *
+ */
+
+#ifndef __KDEGALLIUM_QUARTZ_H
+#define __KDEGALLIUM_QUARTZ_H
+
+#include <qbitmap.h>
+#include <kpixmap.h>
+#include "../../lib/kcommondecoration.h"
+#include "../../lib/kdecorationfactory.h"
+
+class QSpacerItem;
+class QBoxLayout;
+
+namespace Quartz {
+
+class QuartzClient;
+
+class QuartzHandler: public QObject, public KDecorationFactory
+{
+ Q_OBJECT
+ public:
+ QuartzHandler();
+ ~QuartzHandler();
+
+ virtual KDecoration* createDecoration( KDecorationBridge* );
+ virtual bool reset(unsigned long changed);
+ virtual bool supports( Ability ability );
+ virtual QValueList< BorderSize > borderSizes() const;
+
+ private:
+ void readConfig();
+ void createPixmaps();
+ void freePixmaps();
+ void drawBlocks(KPixmap* pi, KPixmap &p, const QColor &c1, const QColor &c2);
+};
+
+
+class QuartzButton : public KCommonDecorationButton
+{
+ public:
+ QuartzButton(ButtonType type, QuartzClient *parent, const char *name);
+ ~QuartzButton();
+ void setBitmap(const unsigned char *bitmap);
+
+ void reset(unsigned long changed);
+
+ protected:
+ void drawButton(QPainter *p);
+
+ QBitmap* deco;
+};
+
+
+class QuartzClient : public KCommonDecoration
+{
+ public:
+ QuartzClient(KDecorationBridge* bridge, KDecorationFactory* factory);
+ ~QuartzClient() {;}
+
+ virtual QString visibleName() const;
+ virtual QString defaultButtonsLeft() const;
+ virtual QString defaultButtonsRight() const;
+ virtual bool decorationBehaviour(DecorationBehaviour behaviour) const;
+ virtual int layoutMetric(LayoutMetric lm, bool respectWindowState = true, const KCommonDecorationButton * = 0) const;
+ virtual KCommonDecorationButton *createButton(ButtonType type);
+
+ virtual void init();
+
+ protected:
+ virtual void reset( unsigned long changed );
+ void paintEvent( QPaintEvent* );
+
+ private:
+ int titleHeight, borderSize;
+ bool largeButtons;
+};
+
+}
+
+#endif
+// vim: ts=4
+// kate: space-indent off; tab-width 4;