summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in.in1
-rw-r--r--src/Makefile.am8
-rw-r--r--src/aquamarine.cpp44
-rw-r--r--src/decorator.cpp1542
-rw-r--r--src/decorator.h249
-rw-r--r--src/defaultDeco.cpp704
-rw-r--r--src/defaultDeco.h127
-rw-r--r--src/defaultShadow.cpp459
-rw-r--r--src/defaultShadow.h66
-rw-r--r--src/libdeco.c2620
-rw-r--r--src/libdeco.h393
-rw-r--r--src/options.cpp168
-rw-r--r--src/options.h174
-rw-r--r--src/switcher.cpp349
-rw-r--r--src/switcher.h68
-rw-r--r--src/utils.cpp532
-rw-r--r--src/utils.h100
-rw-r--r--src/window.cpp3217
-rw-r--r--src/window.h479
19 files changed, 6353 insertions, 4947 deletions
diff --git a/configure.in.in b/configure.in.in
index d23e58c..c5297dd 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -19,6 +19,7 @@ AC_ARG_ENABLE(berylsettings, AC_HELP_STRING([--disable-berylsettings], [disable
AM_CONDITIONAL(include_bs, test "$berylsettings" = "yes")
KDE_PKG_CHECK_MODULES(XCOMPOSITE, "xcomposite",[],AC_MSG_ERROR([xcomposite not found]))
+#KDE_PKG_CHECK_MODULES(DECOLIB, "libberyldecoration",[],AC_MSG_ERROR([libberyldecoration not found]))
if test "$berylsettings" = "yes"; then
KDE_PKG_CHECK_MODULES(BERYLSETTINGS, $BERYL_SETTINGS_REQUIRES,
diff --git a/src/Makefile.am b/src/Makefile.am
index bcfb211..e77ad04 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,15 +8,15 @@ aquamarine_SOURCES = aquamarine.cpp \
utils.cpp \
decorator.cpp \
window.cpp \
- switcher.cpp \
KWinInterface.skel \
options.cpp \
- defaultDeco.cpp \
- defaultShadow.cpp \
- settings.kcfgc
+ settings.kcfgc \
+ libdeco.c
+#aquamarine_LDADD = $(LIB_KDECORE) -lkdecorations $(BERYLSETTINGS_LIBS) $(XCOMPOSITE_LIBS) $(DECOLIB_LIBS)
aquamarine_LDADD = $(LIB_KDECORE) -lkdecorations $(BERYLSETTINGS_LIBS) $(XCOMPOSITE_LIBS)
aquamarine_LDFLAGS = $(all_libraries)
+#KDE_CXXFLAGS = $(BERYLSETTINGS_CFLAGS) $(XCOMPOSITE_CFLAGS) $(DECOLIB_CFLAGS)
KDE_CXXFLAGS = $(BERYLSETTINGS_CFLAGS) $(XCOMPOSITE_CFLAGS)
METASOURCES = AUTO
diff --git a/src/aquamarine.cpp b/src/aquamarine.cpp
index bcc96e3..2920dc1 100644
--- a/src/aquamarine.cpp
+++ b/src/aquamarine.cpp
@@ -3,10 +3,9 @@
*
* Copyright (c) 2006 Dennis Kasprzyk <onestone@beryl-project.org>
* Copyright (c) 2006 Volker Krause <vkrause@kde.org>
+ * Copyright (c) 2006 David Reveman <davidr@novell.com>
*
* Uses code of:
- * Emerald window decorator (www.beryl-project.org)
- * gtk-window-decorator (www.freedesktop.org/wiki/Software/Compiz)
* KWin window manager (www.kde.org)
*
* This program is free software; you can redistribute it and/or modify
@@ -56,7 +55,6 @@ static const KCmdLineOptions options[] = {
int
main (int argc, char **argv)
{
- bool argb_visual = false;
char *display = 0;
Display *dpy = XOpenDisplay (display);
int screen = DefaultScreen (dpy);
@@ -83,39 +81,6 @@ main (int argc, char **argv)
exit (1);
}
-
- Colormap colormap = 0;
- Visual *visual = 0;
- int event_base, error_base;
-
- if (XRenderQueryExtension (dpy, &event_base, &error_base))
- {
- int nvi;
- XVisualInfo templ;
- templ.screen = screen;
- templ.depth = 32;
- templ.c_class = TrueColor;
- XVisualInfo *xvi =
- XGetVisualInfo (dpy,
- VisualScreenMask | VisualDepthMask |
- VisualClassMask, &templ, &nvi);
-
- for (int i = 0; i < nvi; i++)
- {
- XRenderPictFormat *format =
- XRenderFindVisualFormat (dpy, xvi[i].visual);
- if (format->type == PictTypeDirect && format->direct.alphaMask)
- {
- visual = xvi[i].visual;
- colormap =
- XCreateColormap (dpy, RootWindow (dpy, screen), visual,
- AllocNone);
- argb_visual = true;
- break;
- }
- }
- }
-
Bool wmRunning = false;
do
{
@@ -173,12 +138,7 @@ main (int argc, char **argv)
}
} while (!wmRunning);
- Aquamarine::Decorator *app = new Aquamarine::Decorator(dpy, Qt::HANDLE (visual),
- Qt::HANDLE (colormap));
-
- DCOPClient *client = app->dcopClient ();
- client->registerAs ("kwin", false);
- client->setDefaultObject ("KWinInterface");
+ Aquamarine::Decorator *app = new Aquamarine::Decorator();
if (app->isReady ()) {
rv = app->exec ();
diff --git a/src/decorator.cpp b/src/decorator.cpp
index 535684e..7986190 100644
--- a/src/decorator.cpp
+++ b/src/decorator.cpp
@@ -1,29 +1,28 @@
/*
- * Aquamarine the KDE window decorator
- *
- * Copyright (c) 2006 Dennis Kasprzyk <onestone@beryl-project.org>
- * Copyright (c) 2006 Volker Krause <vkrause@kde.org>
- *
- * Uses code of:
- * Emerald window decorator (www.beryl-project.org)
- * gtk-window-decorator (www.freedesktop.org/wiki/Software/Compiz)
- * KWin window manager (www.kde.org)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
+* Aquamarine the KDE window decorator
+*
+* Copyright (c) 2006 Dennis Kasprzyk <onestone@beryl-project.org>
+* Copyright (c) 2006 Volker Krause <vkrause@kde.org>
+* Copyright (c) 2006 David Reveman <davidr@novell.com>
+*
+* Uses code of:
+* KWin window manager (www.kde.org)
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
#include <qglobal.h>
@@ -34,11 +33,14 @@
#include <kglobal.h>
#include <kwinmodule.h>
#include <klocale.h>
+#include <kcommondecoration.h>
#include <kwin.h>
-
+#include <qwidgetlist.h>
#include <qpoint.h>
-#include "switcher.h"
+#include <X11/Xlib.h>
+#include <X11/extensions/Xcomposite.h>
+
#include "decorator.h"
#include "options.h"
#include "utils.h"
@@ -46,755 +48,949 @@
#include <stdio.h>
-#ifdef HAVE_BERYL_SETTINGS
+decor_context_t Aquamarine::Decorator::mDefaultContext;
+decor_shadow_t *Aquamarine::Decorator::mNoBorderShadow = 0;
+decor_shadow_t *Aquamarine::Decorator::mDefaultShadow = 0;
+Aquamarine::PluginManager *Aquamarine::Decorator::mPlugins = 0;
+Aquamarine::Options *Aquamarine::Decorator::mOptions = 0;
+NETRootInfo *Aquamarine::Decorator::mRootInfo;
+WId Aquamarine::Decorator::mActiveId;
+decor_shadow_options_t Aquamarine::Decorator::mShadowOptions;
+
+QSize Aquamarine::Decorator::mDesktop;
+QPoint Aquamarine::Decorator::mViewport;
+QSize Aquamarine::Decorator::mRootSize;
-extern "C" {
-#include <beryl-settings.h>
-}
-#endif
-
-#define GRAVITY_WEST (1 << 0)
-#define GRAVITY_EAST (1 << 1)
-#define GRAVITY_NORTH (1 << 2)
-#define GRAVITY_SOUTH (1 << 3)
-
-#define XX_MASK (1 << 12)
-#define XY_MASK (1 << 13)
-#define YX_MASK (1 << 14)
-#define YY_MASK (1 << 15)
-
-#define CLAMP_HORZ (1 << 0)
-#define CLAMP_VERT (1 << 1)
-
-Aquamarine::PluginManager * Aquamarine::Decorator::m_plugins = 0;
-Aquamarine::Options * Aquamarine::Decorator::m_options = 0;
-QSize
- Aquamarine::Decorator::m_desktop;
-QPoint
- Aquamarine::Decorator::m_viewport;
-QSize
- Aquamarine::Decorator::m_rootSize;
-
-extern Time
- qt_x_time;
-
-struct _cursor
- cursors[3][3] = {
- {C (top_left_corner), C (top_side), C (top_right_corner)},
- {C (left_side), C (left_ptr), C (right_side)},
- {C (bottom_left_corner), C (bottom_side), C (bottom_right_corner)}
+extern Time qt_x_time;
+
+struct _cursor cursors[3][3] = {
+ { C (top_left_corner), C (top_side), C (top_right_corner) },
+ { C (left_side), C (left_ptr), C (right_side) },
+ { C (bottom_left_corner), C (bottom_side), C (bottom_right_corner) }
};
+Aquamarine::PluginManager::PluginManager (KConfig *config): KDecorationPlugins (config)
+{
+ // taken from KWin
+ defaultPlugin = (QPixmap::defaultDepth () > 8) ? "kwin3_plastik" : "kwin3_quartz";
+}
-Aquamarine::PluginManager::PluginManager (KConfig * config):
-KDecorationPlugins (config)
+Aquamarine::Decorator::Decorator (void) : DCOPObject ("KWinInterface"),
+ KApplication (),
+ mConfig (0),
+ mKWinModule (new KWinModule (this, KWinModule::INFO_ALL)),
+ mCompositeWindow (0)
{
- // taken from KWin
- defaultPlugin =
- (QPixmap::defaultDepth () > 8) ? "kwin3_plastik" : "kwin3_quartz";
+ KGlobal::locale()->insertCatalogue("kdelibs");
+ KGlobal::locale()->setActiveCatalogue("aquamarine");
+
+ mReady = false;
+ mRestart = false;
+
+ int event, error;
+
+ DCOPClient *client;
+ int i, j;
+
+ mRootInfo = new NETRootInfo (qt_xdisplay (), 0);
+
+ mActiveId = 0;
+
+ Atoms::init ();
+
+ if (!XDamageQueryExtension (qt_xdisplay (), &event, &error))
+ {
+ fprintf (stderr, "Damage extension is missing on display \"%s\"\n",
+ DisplayString (qt_xdisplay ()));
+ return;
+ }
+
+ mActiveWM = XGetSelectionOwner(qt_xdisplay(),Atoms::wmSn);
+ if (mActiveWM == None)
+ return;
+ XSelectInput (qt_xdisplay(), mActiveWM, StructureNotifyMask);
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs ();
+
+ Time timestamp;
+ int status = decor_acquire_dm_session (qt_xdisplay (), 0, "Aquamarine",
+ args->isSet ("replace"),&timestamp);
+
+ if (status != DECOR_ACQUIRE_STATUS_SUCCESS)
+ {
+ if (status == DECOR_ACQUIRE_STATUS_OTHER_DM_RUNNING)
+ {
+ fprintf (stderr,
+ "Could not acquire decoration manager "
+ "selection on screen %d display \"%s\"\n",
+ 0, DisplayString (qt_xdisplay ()));
+ }
+ else if (status == DECOR_ACQUIRE_STATUS_OTHER_DM_RUNNING)
+ {
+ fprintf (stderr,
+ "Screen %d on display \"%s\" already "
+ "has a decoration manager; try using the "
+ "--replace option to replace the current "
+ "decoration manager.\n",
+ 0, DisplayString (qt_xdisplay ()));
+ }
+ return;
+ }
+
+ decor_set_dm_check_hint (qt_xdisplay (), 0);
+
+ mConfig = new KConfig ("kwinrc");
+ mConfig->setGroup ("Style");
+
+ mOptions = new Aquamarine::Options (mConfig);
+ mPlugins = new PluginManager (mConfig);
+
+ for (i = 0; i < 3; i++)
+ {
+ for (j = 0; j < 3; j++)
+ {
+ if (cursors[i][j].shape != XC_left_ptr)
+ cursors[i][j].cursor =
+ XCreateFontCursor (qt_xdisplay (), cursors[i][j].shape);
+ }
+ }
+
+ client = dcopClient ();
+ client->registerAs ("kwin", false);
+ client->setDefaultObject ("KWinInterface");
+
+ mShadowOptions.shadow_radius = (Settings::drawShadows())?
+ Settings::shadowRadius():0;
+ mShadowOptions.shadow_opacity = Settings::shadowOpacity() / 100.0;
+ mShadowOptions.shadow_offset_x = Settings::shadowOffsetX();
+ mShadowOptions.shadow_offset_y = Settings::shadowOffsetY();
+ mShadowOptions.shadow_color[0] = Settings::shadowColor().red() * 0x101;
+ mShadowOptions.shadow_color[1] = Settings::shadowColor().green() * 0x101;
+ mShadowOptions.shadow_color[2] = Settings::shadowColor().blue() * 0x101;
+ mShadowOptions.shadow_color[3] = 0xffff;
+
+ mCompositeWindow = new QWidget (0, "AquamarineCompositeWidget",
+ Qt::WType_TopLevel | Qt::WStyle_NoBorder |
+ Qt::WX11BypassWM);
+
+ mCompositeWindow->setGeometry (QRect (-ROOT_OFF_X, -ROOT_OFF_Y, 1, 1));
+ mCompositeWindow->show ();
+
+ XCompositeRedirectSubwindows (qt_xdisplay (), mCompositeWindow->winId (),
+ CompositeRedirectManual);
+
+ if (!enableDecorations (timestamp, event))
+ {
+ fprintf (stderr, "Could not enable decorations on display \"%s\"\n",
+ DisplayString (qt_xdisplay ()));
+ return;
+ }
+
+ updateDesktopGeometry ();
+
+ mReady = true;
}
+Aquamarine::Decorator::~Decorator (void)
+{
+ QMap <WId, Aquamarine::Window *>::ConstIterator it;
+
+ for (it = mClients.begin (); it != mClients.end (); it++)
+ delete (*it);
+
+ if (mDecorNormal)
+ delete mDecorNormal;
+ if (mDecorActive)
+ delete mDecorActive;
-Aquamarine::Decorator::Decorator (Display * dpy, Qt::HANDLE visual, Qt::HANDLE colormap):
-DCOPObject ("KWinInterface"),
-KApplication (dpy, visual, colormap),
-m_defDeco (0),
-m_defDecoActive (0),
-m_activeWindow (0),
-m_config (0),
-m_kwinmodule (new KWinModule (this, KWinModule::INFO_ALL)), m_switcher (0)
+ /* XXX: mCompositeWindow is not deleted, some plugins seem to rely on
+ it not being deleted... not sure what to do about this. */
+
+ delete mOptions;
+ delete mPlugins;
+ delete mConfig;
+ delete mKWinModule;
+ delete mRootInfo;
+}
+
+bool Aquamarine::Decorator::enableDecorations (Time timestamp, int damageEvent)
{
-// delete KGlobal::_locale;
-// KGlobal::_locale = new KLocale( "kwin" , NULL );
-// KGlobal::locale()->insertCatalogue("aquamarine");
- KGlobal::locale()->insertCatalogue("kdelibs");
- KGlobal::locale()->setActiveCatalogue("aquamarine");
+ QValueList <WId>::ConstIterator it;
+
+ mDmSnTimestamp = timestamp;
+ mDamageEvent = damageEvent;
+
+ if (!pluginManager ()->loadPlugin (""))
+ return false;
+
+ updateShadow ();
- ready = false;
- m_restart = false;
-
- m_plugins = NULL;
- m_options = NULL;
-
- Atoms::init ();
-
- m_activeWM = XGetSelectionOwner(qt_xdisplay(),Atoms::wm_sn);
- if (m_activeWM == None)
- return;
- XSelectInput (qt_xdisplay(), m_activeWM, StructureNotifyMask);
-
- KCmdLineArgs *
- args = KCmdLineArgs::parsedArgs ();
- bool
- replace = args->isSet ("replace");
- ready = acquireDmSession (qt_xdisplay (), qt_xscreen (), replace);
- if (!ready)
- return;
-
- set_dm_check_hint (qt_xscreen ());
-
- m_config = new KConfig ("kwinrc");
- m_config->setGroup ("Style");
-
- connect (this, SIGNAL (settingsChanged (int)),
- SLOT (slotSettingsChanged (int)));
-
- QString
- decoName;
- if (args->isSet ("deco"))
- decoName = args->getOption ("deco");
- if (!decoName.startsWith ("kwin3_") && !decoName.isEmpty ())
- decoName = "kwin3_" + decoName;
-
- m_options = new Aquamarine::Options (m_config);
- m_plugins = new PluginManager (m_config);
- kdDebug () << "loading plugin: " << decoName << endl;
- bool
- rv = pluginManager ()->loadPlugin (decoName);
- kdDebug () << "plugin loaded: " << rv << endl;
-
- updateDesktopGeometry ();
-
- m_defDeco = new Aquamarine::DefaultDecoration (false);
- m_defDecoActive = new Aquamarine::DefaultDecoration (true);
- m_defShadow = (Settings::drawShadows())? new Aquamarine::DefaultShadow () : NULL;
-
- connect (m_kwinmodule, SIGNAL (windowAdded (WId)),
- SLOT (slotWindowAdded (WId)));
- connect (m_kwinmodule, SIGNAL (windowRemoved (WId)),
- SLOT (slotWindowRemoved (WId)));
- connect (m_kwinmodule, SIGNAL (activeWindowChanged (WId)),
- SLOT (slotActiveWindowChanged (WId)));
- connect (m_kwinmodule,
- SIGNAL (windowChanged (WId, const unsigned long *)),
- SLOT (slotWindowChanged (WId, const unsigned long *)));
-
- QValueList < WId >::ConstIterator it;
- for (it = m_kwinmodule->windows ().begin ();
- it != m_kwinmodule->windows ().end (); ++it)
- {
- slotWindowAdded ((*it));
- }
-
-
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 3; j++)
- {
- if (cursors[i][j].shape != XC_left_ptr)
- cursors[i][j].cursor =
- XCreateFontCursor (qt_xdisplay (), cursors[i][j].shape);
- }
- }
-
- connect( this, SIGNAL(appearanceChanged()), SLOT(reconfigure()) );
+ mDecorNormal = new Aquamarine::Window (mCompositeWindow, qt_xrootwin (),
+ 0, Window::Default);
+ mDecorActive = new Aquamarine::Window (mCompositeWindow, qt_xrootwin (),
+ 0, Window::DefaultActive);
+
+ connect (mKWinModule, SIGNAL (windowAdded (WId)),
+ SLOT (handleWindowAdded (WId)));
+ connect (mKWinModule, SIGNAL (windowRemoved (WId)),
+ SLOT (handleWindowRemoved (WId)));
+ connect (mKWinModule, SIGNAL (activeWindowChanged (WId)),
+ SLOT (handleActiveWindowChanged (WId)));
+ connect (mKWinModule, SIGNAL (windowChanged (WId, const unsigned long *)),
+ SLOT (handleWindowChanged (WId, const unsigned long *)));
+
+ connect (&mIdleTimer, SIGNAL (timeout ()), SLOT (processDamage ()));
+
+ mActiveId = mKWinModule->activeWindow ();
+
+ it = mKWinModule->windows ().begin ();
+ for (; it != mKWinModule->windows ().end (); it++)
+ handleWindowAdded ((*it));
+
+ connect (this, SIGNAL (appearanceChanged ()), SLOT (reconfigure ()));
(void) QApplication::desktop (); // trigger creation of desktop widget
// select for client messages
XSelectInput (qt_xdisplay(), qt_xrootwin (),
- StructureNotifyMask | PropertyChangeMask);
+ StructureNotifyMask | PropertyChangeMask);
+
+ return true;
+}
+
+void Aquamarine::Decorator::updateDefaultShadow (Aquamarine::Window *w)
+{
+ bool uniqueHorzShape, uniqueVertShape;
+
+ if (mDefaultShadow)
+ {
+ decor_shadow_destroy (qt_xdisplay (), mDefaultShadow);
+ mDefaultShadow = NULL;
+ }
+
+ w->getShapeInfo (&uniqueHorzShape, &uniqueVertShape);
+
+ /* only return shadow if decoration doesn't use a unique shape */
+ if (uniqueHorzShape || uniqueVertShape)
+ return;
+
+ mDefaultContext = *w->context ();
+ mDefaultShadow = w->shadow ();
+
+ if (mDefaultShadow)
+ decor_shadow_reference (mDefaultShadow);
+}
+
+void Aquamarine::Decorator::updateAllShadowOptions (void)
+{
+ mShadowOptions.shadow_radius = (Settings::drawShadows())?
+ Settings::shadowRadius():0;
+ mShadowOptions.shadow_opacity = Settings::shadowOpacity() / 100.0;
+ mShadowOptions.shadow_offset_x = Settings::shadowOffsetX();
+ mShadowOptions.shadow_offset_y = Settings::shadowOffsetY();
+ mShadowOptions.shadow_color[0] = Settings::shadowColor().red() * 0x101;
+ mShadowOptions.shadow_color[1] = Settings::shadowColor().green() * 0x101;
+ mShadowOptions.shadow_color[2] = Settings::shadowColor().blue() * 0x101;
}
-Aquamarine::Decorator::~Decorator ()
+void Aquamarine::Decorator::updateShadow (void)
{
- QMap < WId, Aquamarine::Window * >::ConstIterator it;
- for (it = m_windows.begin ();
- it != m_windows.end (); ++it)
- {
- delete (*it);
- }
- delete
- m_defDeco;
- delete
- m_defDecoActive;
- delete m_defShadow;
- delete
- m_options;
- delete
- m_plugins;
- delete
- m_config;
- delete
- m_switcher;
- delete
- m_kwinmodule;
- if (dm_window != None) XDestroyWindow(qt_xdisplay(),dm_window);
- dm_window = None;
+ Display *xdisplay = qt_xdisplay ();
+ Screen *xscreen = ScreenOfDisplay (xdisplay, qt_xscreen ());
+ decor_context_t context;
+
+ if (mDefaultShadow)
+ {
+ decor_shadow_destroy (xdisplay, mDefaultShadow);
+ mDefaultShadow = NULL;
+ }
+
+ if (mNoBorderShadow)
+ decor_shadow_destroy (xdisplay, mNoBorderShadow);
+
+ mNoBorderShadow = decor_shadow_create (xdisplay,
+ xscreen,
+ 1, 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, 0, 0, 0,
+ &mShadowOptions,
+ &context,
+ decor_draw_simple,
+ 0);
+
+ if (mNoBorderShadow)
+ {
+ decor_extents_t extents = { 0, 0, 0, 0 };
+ long data[256];
+ decor_quad_t quads[N_QUADS_MAX];
+ int nQuad;
+ decor_layout_t layout;
+
+ decor_get_default_layout (&context, 1, 1, &layout);
+
+ nQuad = decor_set_lSrStSbS_window_quads (quads, &context, &layout);
+
+ decor_quads_to_property (data, mNoBorderShadow->pixmap,
+ &extents, &extents,
+ 0, 0, quads, nQuad);
+
+ Aquamarine::trapXError ();
+ XChangeProperty (qt_xdisplay (), qt_xrootwin (),
+ Atoms::netWindowDecorBare,
+ XA_INTEGER,
+ 32, PropModeReplace, (unsigned char *) data,
+ BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
+ Aquamarine::popXError ();
+ }
}
-bool
-Aquamarine::Decorator::x11EventFilter (XEvent * xevent)
+void Aquamarine::Decorator::processDamage (void)
{
- WId
- xid = 0;
+ QMap <WId, Aquamarine::Window *>::ConstIterator it;
+ mDecorNormal->processDamage ();
+ mDecorActive->processDamage ();
- switch (xevent->type)
- {
+ for (it = mClients.constBegin (); it != mClients.constEnd (); it++)
+ it.data ()->processDamage ();
+}
+
+bool Aquamarine::Decorator::x11EventFilter (XEvent *xevent)
+{
+ Aquamarine::Window *client;
+ int status;
+
+ switch (xevent->type) {
case MapNotify:
{
- Aquamarine::Window * client = 0;
- if (m_frames.contains (xevent->xmap.window))
- client = m_frames[xevent->xmap.window];
- if (!client)
- break;
- client->setMapping(true);
+ XMapEvent *xme = reinterpret_cast <XMapEvent *> (xevent);
+
+ if (mWindows.contains (xme->window))
+ client = mWindows[xme->window];
+ else if (mDecorNormal->winId () == xme->window)
+ client = mDecorNormal;
+ else if (mDecorActive->winId () == xme->window)
+ client = mDecorActive;
+ else
+ break;
+
+ if (client->handleMap ())
+ {
+ if (!mIdleTimer.isActive ())
+ mIdleTimer.start (0, TRUE);
+ }
break;
}
- case UnmapNotify:
+ case ConfigureNotify:
{
- Aquamarine::Window * client = 0;
- if (m_frames.contains (xevent->xunmap.window))
- client = m_frames[xevent->xunmap.window];
- if (!client)
- break;
- client->setMapping(false);
+ XConfigureEvent *xce = reinterpret_cast <XConfigureEvent *> (xevent);
+
+ if (mFrames.contains (xce->window))
+ mFrames[xce->window]->updateFrame (xce->window);
+
+ if (mWindows.contains (xce->window))
+ client = mWindows[xce->window];
+ else if (mDecorNormal->winId () == xce->window)
+ client = mDecorNormal;
+ else if (mDecorActive->winId () == xce->window)
+ client = mDecorActive;
+ else
+ break;
+
+ if (client->handleConfigure ())
+ {
+ if (!mIdleTimer.isActive ())
+ mIdleTimer.start (0, TRUE);
+ }
break;
}
- case DestroyNotify:
- if (xevent->xdestroywindow.window == m_activeWM)
- {
- m_restart = true;
- KApplication::exit(0);
- }
- break;
- case SelectionRequest:
- handleSelectionRequest (xevent);
- break;
- case SelectionClear:
- if (xevent->xselectionclear.selection == Atoms::dm_sn)
- {
- m_restart = false;
- KApplication::exit(0);
- }
- break;
- case ConfigureNotify:
- {
- XConfigureEvent *
- xce = reinterpret_cast < XConfigureEvent * >(xevent);
- Aquamarine::Window * client = 0;
- if (m_frames.contains (xce->window))
- client = m_frames[xce->window];
- if (!client)
- break;
- client->updateFrame (xce->window);
- }
- case PropertyNotify:
- if (xevent->xproperty.atom == Atoms::net_frame_window)
- {
- xid = xevent->xproperty.window;
- slotWindowAdded (xid);
- }
- if (xevent->xproperty.atom == Atoms::select_window)
- {
- xid = xevent->xproperty.window;
- if (!m_switcher || m_switcher->xid () != xid)
- slotWindowAdded (xid);
- m_switcher->update ();
-
- }
- if (xevent->xproperty.atom == Atoms::net_desktop_geometry
- || xevent->xproperty.atom == Atoms::net_desktop_viewport)
- {
- updateDesktopGeometry ();
- }
- if (xevent->xproperty.atom == Atoms::opacity)
- {
- Aquamarine::Window * client = 0;
- if (m_windows.contains (xevent->xproperty.window))
- client = m_windows[xevent->xproperty.window];
- if (client)
- client->updateOpacity ();
- }
- if (xevent->xproperty.atom == Atoms::brightness)
- {
- Aquamarine::Window * client = 0;
- if (m_windows.contains (xevent->xproperty.window))
- client = m_windows[xevent->xproperty.window];
- if (client)
- client->updateBrightness ();
- }
- if (xevent->xproperty.atom == Atoms::saturation)
- {
- Aquamarine::Window * client = 0;
- if (m_windows.contains (xevent->xproperty.window))
- client = m_windows[xevent->xproperty.window];
- if (client)
- client->updateSaturation ();
- }
- break;
- case EnterNotify:
- {
- XCrossingEvent *
- xce = reinterpret_cast < XCrossingEvent * >(xevent);
- Aquamarine::Window * client = 0;
- if (m_frames.contains (xce->window))
- client = m_frames[xce->window];
- if (!client)
- break;
- client->updateCursor (QPoint (xce->x, xce->y));
- break;
- }
- case LeaveNotify:
- {
- XCrossingEvent *
- xce = reinterpret_cast < XCrossingEvent * >(xevent);
- Aquamarine::Window * client = 0;
- if (m_frames.contains (xce->window))
- client = m_frames[xce->window];
- if (!client)
- break;
- XUndefineCursor (qt_xdisplay (), client->frameId ());
- break;
- }
- case MotionNotify:
- {
- XMotionEvent *
- xme = reinterpret_cast < XMotionEvent * >(xevent);
- Aquamarine::Window * client = 0;
- if (m_frames.contains (xme->window))
- client = m_frames[xme->window];
- if (!client)
+ case DestroyNotify:
+ if (xevent->xdestroywindow.window == mActiveWM)
{
- QMap < WId, Aquamarine::Window * >::ConstIterator it;
- for (it = m_windows.begin ();
- it != m_windows.end (); ++it)
- {
- if ((*it)->decoration()->widget()->handle() == xme->window)
- client = (*it);
- }
+ mRestart = true;
+ KApplication::exit(0);
}
- if (!client)
- break;
- client->updateCursor (QPoint (xme->x, xme->y));
- break;
- }
- case ClientMessage:
- if (xevent->xclient.message_type == Atoms::toolkitActionAtom)
- {
- long action;
-
- action = xevent->xclient.data.l[0];
- if ((Atom)action == Atoms::toolkitActionWindowMenuAtom)
+ break;
+ case SelectionRequest:
+ decor_handle_selection_request (qt_xdisplay (), xevent, mDmSnTimestamp);
+ break;
+ case SelectionClear:
+ status = decor_handle_selection_clear (qt_xdisplay (),
+ xevent, 0);
+ if (status == DECOR_SELECTION_GIVE_UP)
+ KApplication::exit (0);
+ break;
+ case PropertyNotify:
+ if (xevent->xproperty.atom == Atoms::netFrameWindow)
{
- if (m_windows.contains (xevent->xclient.window))
+ handleWindowAdded (xevent->xproperty.window);
+ }
+ else if (xevent->xproperty.atom == Atoms::switchSelectWindow)
{
- QPoint pos;
-
- Aquamarine::Window * client = m_windows[xevent->xclient.window];
-
- if (xevent->xclient.data.l[2])
+ if (!mClients.contains (xevent->xproperty.window))
{
- pos = QPoint (xevent->xclient.data.l[3],
- xevent->xclient.data.l[4]);
+ handleWindowAdded (xevent->xproperty.window);
}
else
{
- pos = client->geometry ().topLeft ();
- }
+ WId id;
- client->showWindowMenu (pos);
+ if (Aquamarine::readWindowProperty (xevent->xproperty.window,
+ Atoms::switchSelectWindow,
+ (long *) &id))
+ mClients[xevent->xproperty.window]->updateSelected (id);
+ }
}
+ else if (xevent->xproperty.atom == Atoms::netWmWindowOpacity)
+ {
+ if (mClients.contains (xevent->xproperty.window))
+ mClients[xevent->xproperty.window]->updateOpacity ();
}
- else if ((Atom)action == Atoms::toolkitActionMainMenuAtom)
+ else if (xevent->xproperty.atom == Atoms::netWmWindowBrightness)
{
- dcopClient ()->send ("kicker",
- "kicker",
- "showKMenu()",
- QByteArray ());
+ if (mClients.contains (xevent->xproperty.window))
+ mClients[xevent->xproperty.window]->updateBrightness ();
}
- else if ((Atom)action == Atoms::toolkitActionRunDialogAtom)
+ else if (xevent->xproperty.atom == Atoms::netWmWindowSaturation)
{
- dcopClient ()->send ("kdesktop",
- "KDesktopIface",
- "popupExecuteCommand()",
- QByteArray ());
+ if (mClients.contains (xevent->xproperty.window))
+ mClients[xevent->xproperty.window]->updateSaturation ();
}
- else if ((Atom)action == Atoms::toolkitActionForceQuitDialogAtom)
+ else if (xevent->xproperty.atom == Atoms::netDesktopGeometry
+ || xevent->xproperty.atom == Atoms::netDesktopViewport)
{
- if (m_windows.contains (xevent->xclient.window))
+ updateDesktopGeometry ();
+ }
+ break;
+ case EnterNotify:
+ {
+ XCrossingEvent *xce = reinterpret_cast <XCrossingEvent *> (xevent);
+ QWidget *widget, *child;
+
+ if (!mFrames.contains (xce->window))
+ break;
+
+ client = mFrames[xce->window];
+
+ widget = client->decoration ()->widget ();
+ child = widget->childAt (xce->x, xce->y, true);
+ if (child)
{
- Time timestamp = xevent->xclient.data.l[1];
+ QEvent qe (QEvent::Enter);
- Aquamarine::Window * client = m_windows[xevent->xclient.window];
+ QApplication::sendEvent (child, &qe);
- if (xevent->xclient.data.l[2])
- client->showKillProcessDialog (timestamp);
- else
- client->hideKillProcessDialog ();
+ client->setActiveChild (child);
+ client->updateCursor (QPoint (xce->x, xce->y));
}
+ break;
+ }
+ case LeaveNotify:
+ {
+ XCrossingEvent *xce = reinterpret_cast <XCrossingEvent *> (xevent);
+
+ if (mFrames.contains (xce->window))
+ {
+ QEvent qe (QEvent::Leave);
+
+ client = mFrames[xce->window];
+
+ QApplication::sendEvent (client->activeChild (), &qe);
+
+ XUndefineCursor (qt_xdisplay (), client->frameId ());
}
+ break;
}
+ case MotionNotify:
+ {
+ XMotionEvent *xme = reinterpret_cast < XMotionEvent * >(xevent);
+ QWidget *widget, *child;
+
+ if (!mFrames.contains (xme->window))
+ break;
+
+ client = mFrames[xme->window];
+
+ widget = client->decoration ()->widget ();
+ child = widget->childAt (xme->x, xme->y, true);
+ if (child)
+ {
+ QPoint qp (xme->x, xme->y);
+
+ if (child != client->activeChild ())
+ {
+ QEvent qee (QEvent::Enter);
+ QEvent qle (QEvent::Leave);
+
+ if (client->activeChild ())
+ QApplication::sendEvent (client->activeChild (), &qle);
+
+ QApplication::sendEvent (child, &qee);
+
+ client->setActiveChild (child);
+ }
+
+ if (widget != child)
+ qp -= QPoint (child->pos ().x (), child->pos ().y ());
+
+ QMouseEvent qme (QEvent::MouseMove, qp, Qt::NoButton, Qt::NoButton);
+
+ QApplication::sendEvent (child, &qme);
+
+ client->updateCursor (QPoint (xme->x, xme->y));
+ }
+ break;
+ }
+ case ButtonPress:
+ case ButtonRelease:
+ {
+ XButtonEvent *xbe = reinterpret_cast <XButtonEvent *>(xevent);
+ QWidget *widget, *child;
+
+ if (!mFrames.contains (xbe->window))
+ break;
+
+ client = mFrames[xbe->window];
+
+ widget = client->decoration ()->widget ();
+ child = widget->childAt (xbe->x, xbe->y, true);
+
+ if (child)
+ {
+ XButtonEvent xbe2 = *xbe;
+
+ xbe2.window = child->winId ();
+ if (widget != child)
+ {
+ xbe2.x = xbe->x - child->pos ().x ();
+ xbe2.y = xbe->y - child->pos ().y ();
+ }
+
+ QApplication::x11ProcessEvent ((XEvent *) &xbe2);
+
+ return true;
+ }
+ break;
+ }
+ case ClientMessage:
+ if (xevent->xclient.message_type == Atoms::toolkitActionAtom)
+ {
+ unsigned long action;
+
+ action = xevent->xclient.data.l[0];
+ if (action == Atoms::toolkitActionWindowMenuAtom)
+ {
+ if (mClients.contains (xevent->xclient.window))
+ {
+ QPoint pos;
+
+ client = mClients[xevent->xclient.window];
+
+ if (xevent->xclient.data.l[2])
+ {
+ pos = QPoint (xevent->xclient.data.l[3],
+ xevent->xclient.data.l[4]);
+ }
+ else
+ {
+ pos = client->clientGeometry ().topLeft ();
+ }
+
+ client->showWindowMenu (pos);
+ }
+ }
+ else if (action == Atoms::toolkitActionMainMenuAtom)
+ {
+ dcopClient ()->send ("kicker",
+ "kicker",
+ "showKMenu()",
+ QByteArray ());
+ }
+ else if (action == Atoms::toolkitActionRunDialogAtom)
+ {
+ dcopClient ()->send ("kdesktop",
+ "KDesktopIface",
+ "popupExecuteCommand()",
+ QByteArray ());
+ }
+ else if (action == Atoms::toolkitActionForceQuitDialogAtom)
+ {
+ if (mClients.contains (xevent->xclient.window))
+ {
+ Time timestamp = xevent->xclient.data.l[1];
+
+ client = mClients[xevent->xclient.window];
+
+ if (xevent->xclient.data.l[2])
+ client->showKillProcessDialog (timestamp);
+ else
+ client->hideKillProcessDialog ();
+ }
+ }
+ }
+ break;
+ default:
+ if (xevent->type == mDamageEvent + XDamageNotify)
+ {
+ XDamageNotifyEvent *xde =
+ reinterpret_cast <XDamageNotifyEvent *>(xevent);
+
+ if (mWindows.contains (xde->drawable))
+ client = mWindows[xde->drawable];
+ else if (mDecorNormal->winId () == xde->drawable)
+ client = mDecorNormal;
+ else if (mDecorActive->winId () == xde->drawable)
+ client = mDecorActive;
+ else
+ break;
+
+ client->addDamageRect (xde->area.x,
+ xde->area.y,
+ xde->area.width,
+ xde->area.height);
+
+ if (client->pixmapId ())
+ {
+ if (!mIdleTimer.isActive ())
+ mIdleTimer.start (0, TRUE);
+ }
+
+ return true;
+ }
break;
- default:
- break;
- }
- return KApplication::x11EventFilter (xevent);
-}
+ }
-WId
-Aquamarine::Decorator::fetchFrame (WId window)
-{
- Atom type;
- int format;
- unsigned long nitems;
- unsigned long bytes_after;
- WId *w;
- WId **ww = &w;
- int err,result;
-
- Aquamarine::trapXError ();
-
- type = None;
- result = XGetWindowProperty (qt_xdisplay (),
- window,
- Atoms::net_frame_window,
- 0, LONG_MAX,
- False, XA_WINDOW, &type, &format, &nitems,
- &bytes_after, (unsigned char **)ww);
- err = Aquamarine::popXError ();
-
- if (err || result != Success)
- return 0;
-
- if (type != XA_WINDOW)
- {
- XFree (w);
- return 0;
- }
-
- WId rv = *w;
- XFree (w);
-
- if (validWindow(rv))
- return rv;
- else
- return 0;
+ return KApplication::x11EventFilter (xevent);
}
void
-Aquamarine::Decorator::reconfigure ()
+Aquamarine::Decorator::reconfigure (void)
{
- kdDebug () << k_funcinfo << endl;
+ unsigned long changed;
Settings::self()->config()->reparseConfiguration();
Settings::self()->readConfig();
- m_config->reparseConfiguration ();
- unsigned long changed = m_options->updateSettings ();
+ updateAllShadowOptions();
- for (QMap < WId, Aquamarine::Window * >::ConstIterator it =
- m_windows.constBegin (); it != m_windows.constEnd (); ++it)
- it.data ()->updateConfig ();
+ mConfig->reparseConfiguration ();
+ changed = mOptions->updateSettings ();
- if (m_defShadow)
- delete m_defShadow;
- m_defShadow = (Settings::drawShadows())? new Aquamarine::DefaultShadow () : NULL;
+ updateShadow ();
-#ifdef HAVE_BERYL_SETTINGS
- beryl_settings_send_reload_signal();
-#endif
+ if (mPlugins->reset (changed))
+ {
+ QMap < WId, Aquamarine::Window * >::ConstIterator it;
- if (m_plugins->reset (changed))
- {
- for (QMap < WId, Aquamarine::Window * >::ConstIterator it =
- m_windows.constBegin (); it != m_windows.constEnd (); ++it)
- it.data ()->reloadDecoration ();
- m_defDeco->reloadDecoration ();
- m_defDecoActive->reloadDecoration ();
- m_plugins->destroyPreviousPlugin ();
- }
-}
+ mDecorNormal->reloadDecoration ();
+ mDecorActive->reloadDecoration ();
-void
-Aquamarine::Decorator::slotSettingsChanged (int)
-{
- kdDebug () << k_funcinfo << endl;
-#ifdef HAVE_BERYL_SETTINGS
- beryl_settings_send_reload_signal();
-#endif
+ for (it = mClients.constBegin (); it != mClients.constEnd (); it++)
+ it.data ()->reloadDecoration ();
+
+ mPlugins->destroyPreviousPlugin ();
+ }
+ else
+ {
+ QMap < WId, Aquamarine::Window * >::ConstIterator it;
+
+ mDecorNormal->updateShadow ();
+ mDecorActive->updateShadow ();
+
+ for (it = mClients.constBegin (); it != mClients.constEnd (); it++)
+ it.data ()->updateShadow ();
+ }
}
void
-Aquamarine::Decorator::slotWindowAdded (WId id)
+Aquamarine::Decorator::handleWindowAdded (WId id)
{
- kdDebug () << k_funcinfo << endl;
- if (!validWindow(id)) return;
- Aquamarine::trapXError ();
- XSelectInput (qt_xdisplay (), id, defaultMask);
- if (Aquamarine::popXError ())
- return;
- if (Aquamarine::readWindowProperty (id, Atoms::select_window, NULL))
- {
- if (!m_switcher)
- m_switcher = new Switcher (id);
- if (m_switcher->xid () != id)
- {
- delete
- m_switcher;
- m_switcher = new Switcher (id);
- }
- return;
- }
- WId frame = fetchFrame (id);
- Aquamarine::Window * client = 0;
- for (QMap < WId, Aquamarine::Window * >::ConstIterator it =
- m_windows.constBegin (); it != m_windows.constEnd (); ++it)
- {
- if (it.data ()->winId () == id)
- {
- return;
- }
- }
-
- KWin::WindowInfo wInfo = KWin::windowInfo (id, NET::WMWindowType, 0);
-
- switch (wInfo.windowType (~0)) {
- case NET::Normal:
- case NET::Dialog:
- case NET::Toolbar:
- case NET::Menu:
- case NET::Utility:
- case NET::Splash:
- /* decorate these window types */
- break;
- default:
- return;
+ QMap <WId, Aquamarine::Window *>::ConstIterator it;
+ Aquamarine::Window *client = 0;
+ WId select, frame = 0;
+ Aquamarine::Window::Type type;
+ unsigned int width, height, border, depth;
+ int x, y;
+ XID root;
+ QWidgetList *widgets;
+
+ /* avoid adding any of our own top level windows */
+ widgets = QApplication::topLevelWidgets ();
+ if (widgets)
+ {
+ for (QWidgetListIt it (*widgets); it.current (); ++it)
+ {
+ if (it.current ()->winId () == id)
+ {
+ delete widgets;
+ return;
+ }
+ }
+
+ delete widgets;
}
+ Aquamarine::trapXError ();
+ XGetGeometry (qt_xdisplay (), id, &root, &x, &y, &width, &height,
+ &border, &depth);
+ if (Aquamarine::popXError ())
+ return;
+
+ Aquamarine::readWindowProperty (id, Atoms::netFrameWindow, (long *) &frame);
+ if (Aquamarine::readWindowProperty (id, Atoms::switchSelectWindow,
+ (long *) &select))
+ {
+ type = Aquamarine::Window::Switcher;
+ }
+ else
+ {
+ KWin::WindowInfo wInfo = KWin::windowInfo (id, NET::WMWindowType, 0);
+
+ switch (wInfo.windowType (~0)) {
+ case NET::Normal:
+ case NET::Dialog:
+ case NET::Toolbar:
+ case NET::Menu:
+ case NET::Utility:
+ case NET::Splash:
+ case NET::Unknown:
+ /* decorate these window types */
+ break;
+ default:
+ return;
+ }
+
+ type = Aquamarine::Window::Normal;
+ }
+
+ Aquamarine::trapXError ();
+ XSelectInput (qt_xdisplay (), id, StructureNotifyMask | PropertyChangeMask);
+ Aquamarine::popXError ();
+
if (frame)
- {
- if (!m_windows.contains (id))
- {
- client = new Aquamarine::Window (id, frame);
- connect( this, SIGNAL(desktopGeometryChanged()), client, SLOT(slotDesktopGeometryChanged()) );
- if (m_kwinmodule->activeWindow () == id)
- {
- if (m_activeWindow)
- m_activeWindow->setActive (false);
- m_activeWindow = client;
- client->setActive(true);
- }
- m_windows.insert (id, client);
- m_frames.insert (frame, client);
- }
- else
- {
- client = m_windows[id];
- m_frames.remove (client->frameId ());
- m_frames.insert (frame, client);
- client->updateFrame (frame);
- }
- }
- else
- {
- if (m_windows.contains (id))
- {
- client = m_windows[id];
- }
- if (client)
- {
- m_windows.remove (client->windowId ());
- m_frames.remove (client->frameId ());
- delete
- client;
- }
- }
+ {
+ if (!mClients.contains (id))
+ {
+ client = new Aquamarine::Window (mCompositeWindow, id, frame, type,
+ x, y,
+ width + border * 2,
+ height + border * 2);
+ connect( this, SIGNAL(desktopGeometryChanged()), client,
+ SLOT(handleDesktopGeometryChanged()) );
+
+ mClients.insert (id, client);
+ mWindows.insert (client->winId (), client);
+ mFrames.insert (frame, client);
+ }
+ else
+ {
+ client = mClients[id];
+ mFrames.remove (client->frameId ());
+ mFrames.insert (frame, client);
+
+ client->updateFrame (frame);
+ }
+ }
+ else if (type == Aquamarine::Window::Switcher)
+ {
+ if (!mClients.contains (id))
+ {
+ client = new Aquamarine::Window (mCompositeWindow, id, 0, type,
+ x, y,
+ width + border * 2,
+ height + border * 2);
+ mClients.insert (id, client);
+ mWindows.insert (client->winId (), client);
+ }
+ }
+ else
+ {
+ if (mClients.contains (id))
+ client = mClients[id];
+
+ if (client)
+ {
+ mClients.remove (client->windowId ());
+ mWindows.remove (client->winId ());
+ mFrames.remove (client->frameId ());
+
+ delete client;
+ }
+ }
}
void
-Aquamarine::Decorator::slotWindowRemoved (WId id)
+Aquamarine::Decorator::handleWindowRemoved (WId id)
{
- kdDebug () << k_funcinfo << endl;
- Aquamarine::Window * window = 0;
- if (m_windows.contains (id))
- {
- window = m_windows[id];
- }
- else if (m_frames.contains (id))
- {
- window = m_frames[id];
- }
- if (window)
- {
- m_windows.remove (window->windowId ());
- m_frames.remove (window->frameId ());
- if (m_activeWindow == window)
- m_activeWindow = 0;
- delete
- window;
- }
- if (m_switcher && m_switcher->xid () == id)
- {
- delete
- m_switcher;
- m_switcher = NULL;
- }
+ Aquamarine::Window *window = 0;
+
+ if (mClients.contains (id))
+ window = mClients[id];
+ else if (mFrames.contains (id))
+ window = mFrames[id];
+
+ if (window)
+ {
+ mClients.remove (window->windowId ());
+ mWindows.remove (window->winId ());
+ mFrames.remove (window->frameId ());
+
+ delete window;
+ }
}
void
-Aquamarine::Decorator::slotActiveWindowChanged (WId id)
+Aquamarine::Decorator::handleActiveWindowChanged (WId id)
{
- kdDebug () << k_funcinfo << endl;
-
- Aquamarine::Window * newActiveWindow = 0;
- if (m_windows.contains (id))
- newActiveWindow = m_windows[id];
-
- if (newActiveWindow && newActiveWindow != m_activeWindow)
- {
- if (m_activeWindow)
- {
- Aquamarine::trapXError ();
- XWindowAttributes
- attr;
- if (XGetWindowAttributes
- (qt_xdisplay (), m_activeWindow->windowId (), &attr)
- && !Aquamarine::popXError ())
- m_activeWindow->setActive (false);
- }
- newActiveWindow->setActive (true);
- }
- m_activeWindow = newActiveWindow;
+ if (id != mActiveId)
+ {
+ Aquamarine::Window *newActiveWindow = 0;
+ Aquamarine::Window *oldActiveWindow = 0;
+
+ if (mClients.contains (id))
+ newActiveWindow = mClients[id];
+
+ if (mClients.contains (mActiveId))
+ oldActiveWindow = mClients[mActiveId];
+
+ mActiveId = id;
+
+ if (oldActiveWindow)
+ oldActiveWindow->handleActiveChange ();
+
+ if (newActiveWindow)
+ newActiveWindow->handleActiveChange ();
+ }
}
void
-Aquamarine::Decorator::slotWindowChanged (WId id,
- const unsigned long *properties)
+Aquamarine::Decorator::handleWindowChanged (WId id,
+ const unsigned long *properties)
{
- Aquamarine::Window * client = 0;
- if (m_windows.contains (id))
- client = m_windows[id];
-
- if (properties[0] & NET::WMName)
- {
- if (client)
- client->updateName ();
- }
- if (properties[0] & NET::WMState)
- {
- if (client)
- client->updateState ();
- }
- if (properties[0] & NET::WMIcon)
- {
- if (client)
- client->updateIcons ();
- }
- if (properties[0] & NET::WMGeometry)
- {
- if (m_switcher && m_switcher->xid () == id)
- m_switcher->updateGeometry ();
- if (client)
- client->updateWindowGeometry ();
- }
+ Aquamarine::Window *client;
+
+ if (!mClients.contains (id))
+ return;
+
+ client = mClients[id];
+
+ if (properties[0] & NET::WMName)
+ client->updateName ();
+ if (properties[0] & NET::WMState)
+ client->updateState ();
+ if (properties[0] & NET::WMIcon)
+ client->updateIcons ();
+ if (properties[0] & NET::WMGeometry)
+ client->updateWindowGeometry ();
}
void
-Aquamarine::Decorator::sendClientMessage (WId w, Atom a, Atom protocol,
- long data1, long data2, long data3)
+Aquamarine::Decorator::sendClientMessage (WId eventWid,
+ WId wid,
+ Atom atom,
+ Atom value,
+ long data1,
+ long data2,
+ long data3)
{
- XEvent ev;
- long mask;
-
- memset (&ev, 0, sizeof (ev));
- ev.xclient.type = ClientMessage;
- ev.xclient.window = w;
- ev.xclient.message_type = a;
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = protocol;
- ev.xclient.data.l[1] = qt_x_time;
- ev.xclient.data.l[2] = data1;
- ev.xclient.data.l[3] = data2;
- ev.xclient.data.l[4] = data3;
- mask = 0L;
- if (w == qt_xrootwin ())
- mask = SubstructureRedirectMask;
- XSendEvent (qt_xdisplay (), w, False, mask, &ev);
+ XEvent ev;
+ long mask = 0;
+
+ memset (&ev, 0, sizeof (ev));
+
+ ev.xclient.type = ClientMessage;
+ ev.xclient.window = wid;
+ ev.xclient.message_type = atom;
+ ev.xclient.format = 32;
+
+ ev.xclient.data.l[0] = value;
+ ev.xclient.data.l[1] = qt_x_time;
+ ev.xclient.data.l[2] = data1;
+ ev.xclient.data.l[3] = data2;
+ ev.xclient.data.l[4] = data3;
+
+ if (eventWid == qt_xrootwin ())
+ mask = SubstructureRedirectMask | SubstructureNotifyMask;
+
+ Aquamarine::trapXError ();
+ XSendEvent (qt_xdisplay (), eventWid, false, mask, &ev);
+ Aquamarine::popXError ();
}
-void
-Aquamarine::Decorator::updateDesktopGeometry ()
+void Aquamarine::Decorator::updateDesktopGeometry ()
{
- int x, y;
- unsigned int width, height, border, depth;
- ::Window root;
- XGetGeometry (qt_xdisplay (), qt_xrootwin (), &root, &x, &y, &width,
- &height, &border, &depth);
- m_rootSize = QSize (width, height);
-
- int
- num_val;
- void *
- values =
- readXProperty (qt_xrootwin (), Atoms::net_desktop_geometry,
- XA_CARDINAL, &num_val);
-
- if (values)
- {
- unsigned long *
- val = (unsigned long *)values;
- m_desktop = QSize (val[0], val[1]);
- XFree (val);
- }
- else
- {
- m_desktop = QSize (m_rootSize.width (), m_rootSize.height ());
- }
- values =
- readXProperty (qt_xrootwin (), Atoms::net_desktop_viewport,
- XA_CARDINAL, &num_val);
-
- if (values)
- {
- unsigned long *
- val = (unsigned long *)values;
- m_viewport = QPoint (val[0], val[1]);
- XFree (val);
- }
- else
- {
- m_viewport = QPoint (0, 0);
- }
-
- emit desktopGeometryChanged();
+ int x, y;
+ unsigned int width, height, border, depth;
+ ::Window root;
+ XGetGeometry (qt_xdisplay (), qt_xrootwin (), &root, &x, &y, &width,
+ &height, &border, &depth);
+ mRootSize = QSize (width, height);
+
+ int num_val;
+ void *values = readXProperty (qt_xrootwin (), Atoms::netDesktopGeometry,
+ XA_CARDINAL, &num_val);
+
+ if (values)
+ {
+ unsigned long *
+ val = (unsigned long *)values;
+ mDesktop = QSize (val[0], val[1]);
+ XFree (val);
+ }
+ else
+ {
+ mDesktop = QSize (mRootSize.width (), mRootSize.height ());
+ }
+ values = readXProperty (qt_xrootwin (), Atoms::netDesktopViewport,
+ XA_CARDINAL, &num_val);
+
+ if (values)
+ {
+ unsigned long *val = (unsigned long *)values;
+ mViewport = QPoint (val[0], val[1]);
+ XFree (val);
+ }
+ else
+ {
+ mViewport = QPoint (0, 0);
+ }
+
+ emit desktopGeometryChanged();
}
-int
-Aquamarine::Decorator::onViewport (QPoint pos)
+
+int Aquamarine::Decorator::onViewport (QPoint pos)
{
- return (((pos.y () +
- m_viewport.y ()) / m_rootSize.height ()) * (m_desktop.width () /
- m_rootSize.
- width ())) +
- ((pos.x () + m_viewport.x ()) / m_rootSize.width ()) + 1;
+ return (((pos.y () +
+ mViewport.y ()) / mRootSize.height ()) * (mDesktop.width () /
+ mRootSize.
+ width ())) +
+ ((pos.x () + mViewport.x ()) / mRootSize.width ()) + 1;
}
-QSize
-Aquamarine::Decorator::viewports ()
+QSize Aquamarine::Decorator::viewports ()
{
- return QSize ((m_desktop.width () / m_rootSize.width ()),
- (m_desktop.height () / m_rootSize.height ()));
+ return QSize ((mDesktop.width () / mRootSize.width ()),
+ (mDesktop.height () / mRootSize.height ()));
}
-void
-Aquamarine::Decorator::moveToViewport (WId id, int vp)
+void Aquamarine::Decorator::moveToViewport (WId id, int vp)
{
- int x, y;
- unsigned int width, height, border, depth;
- ::Window root;
- XGetGeometry (qt_xdisplay (), id, &root, &x, &y, &width, &height, &border,
- &depth);
- if (vp <= 0) vp+= (m_desktop.width () / m_rootSize.width ()) * (m_desktop.height () / m_rootSize.height ());
- vp = ((vp - 1) % ((m_desktop.width () / m_rootSize.width ()) * (m_desktop.height () / m_rootSize.height ()))) + 1;
- int
- offsetX = m_rootSize.width () * ((vp - 1) % viewports ().width ());
- int
- offsetY = m_rootSize.height () * ((vp - 1) / viewports ().width ());
- XMoveWindow (qt_xdisplay (), id, x + offsetX - m_viewport.x (),
- y + offsetY - m_viewport.y ());
+ int x, y;
+ unsigned int width, height, border, depth;
+ ::Window root;
+ XGetGeometry (qt_xdisplay (), id, &root, &x, &y, &width, &height, &border,
+ &depth);
+ if (vp <= 0) vp+= (mDesktop.width () / mRootSize.width ()) * (mDesktop.height () / mRootSize.height ());
+ vp = ((vp - 1) % ((mDesktop.width () / mRootSize.width ()) * (mDesktop.height () / mRootSize.height ()))) + 1;
+ int offsetX = mRootSize.width () * ((vp - 1) % viewports ().width ());
+ int offsetY = mRootSize.height () * ((vp - 1) / viewports ().width ());
+ XMoveWindow (qt_xdisplay (), id, x + offsetX - mViewport.x (),
+ y + offsetY - mViewport.y ());
}
diff --git a/src/decorator.h b/src/decorator.h
index a3a3c76..646c773 100644
--- a/src/decorator.h
+++ b/src/decorator.h
@@ -3,10 +3,9 @@
*
* Copyright (c) 2006 Dennis Kasprzyk <onestone@beryl-project.org>
* Copyright (c) 2006 Volker Krause <vkrause@kde.org>
+ * Copyright (c) 2006 David Reveman <davidr@novell.com>
*
* Uses code of:
- * Emerald window decorator (www.beryl-project.org)
- * gtk-window-decorator (www.freedesktop.org/wiki/Software/Compiz)
* KWin window manager (www.kde.org)
*
* This program is free software; you can redistribute it and/or modify
@@ -25,12 +24,8 @@
*
*/
-#ifndef AQUAMARINE_DECORATOR_H
-#define AQUAMARINE_DECORATOR_H
-
-#ifdef HAVE_CONFIG_H
-# include "../config.h"
-#endif
+#ifndef _DECORATOR_H
+#define _DECORATOR_H
#include <kapplication.h>
@@ -38,132 +33,166 @@
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
+#include <qtimer.h>
+
#include <fixx11h.h>
#include <kconfig.h>
#include <kdecoration_plugins_p.h>
#include <kdecoration_p.h>
+#include <netwm.h>
+
+//#include <beryl-decoration.h>
+#include "libdeco.h"
#include "window.h"
-#include "defaultDeco.h"
-#include "defaultShadow.h"
#include "KWinInterface.h"
-#define C(name) { 0, XC_ ## name }
+#define ROOT_OFF_X 8192
+#define ROOT_OFF_Y 8192
-#define DECOR_INTERFACE_VERSION 20061011
+#define C(name) { 0, XC_ ## name }
-struct _cursor
-{
- Cursor cursor;
+struct _cursor {
+ Cursor cursor;
unsigned int shape;
};
+extern struct _cursor cursors[3][3];
+
class KConfig;
class KWinModule;
-
-
-static const long defaultMask = StructureNotifyMask | PropertyChangeMask;
-
namespace Aquamarine
{
-
class Options;
- class Switcher;
-
- class PluginManager:public KDecorationPlugins
- {
- public:
- PluginManager (KConfig * config);
- virtual bool provides (Requirement)
- {
- return false;
- }
- };
-
-
- class Decorator:public KApplication, public KWinInterface
- {
- Q_OBJECT public:
- Decorator (Display * dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap =
- 0);
- ~Decorator ();
-
- bool isReady ()
- {
- return ready;
- }
- bool x11EventFilter (XEvent *);
-
- static PluginManager *pluginManager ()
- {
- return m_plugins;
- }
- static Aquamarine::Options * options ()
- {
- return m_options;
- }
- static void sendClientMessage (WId w, Atom a, Atom protocol,
- long data1 = 0, long data2 =
- 0, long data3 = 0);
-
- static int onViewport (QPoint pos);
- static QSize viewports ();
- static void moveToViewport (WId id, int vp);
-
- bool restart () const
- {
- return m_restart;
- }
-
- public slots:
- void reconfigure ();
-
- signals:
- void desktopGeometryChanged();
-
- private:
- WId fetchFrame (WId window);
- void updateDesktopGeometry ();
-
- private slots:
- void slotWindowAdded (WId id);
- void slotWindowRemoved (WId id);
- void slotActiveWindowChanged (WId id);
- void slotWindowChanged (WId id, const unsigned long *properties);
- void slotSettingsChanged (int category);
-
- private:
-
- bool ready;
-
- Aquamarine::DefaultDecoration * m_defDeco;
- Aquamarine::DefaultDecoration * m_defDecoActive;
- Aquamarine::DefaultShadow * m_defShadow;
-
- QMap < WId, Aquamarine::Window * >m_windows;
- QMap < WId, Aquamarine::Window * >m_frames;
- Aquamarine::Window * m_activeWindow;
-
- KConfig *m_config;
-
- static PluginManager *m_plugins;
- static Aquamarine::Options * m_options;
-
- KWinModule *m_kwinmodule;
-
- Switcher *m_switcher;
+ class PluginManager: public KDecorationPlugins
+ {
+ public:
+ PluginManager (KConfig *config);
+ virtual bool provides (Requirement)
+ {
+ return false;
+ }
+ };
- static QSize m_desktop;
- static QPoint m_viewport;
- static QSize m_rootSize;
- WId m_activeWM;
- bool m_restart;
+ class Decorator: public KApplication, public KWinInterface
+ {
+ Q_OBJECT public:
+
+ Decorator (void);
+ ~Decorator (void);
+
+ static NETRootInfo *rootInfo (void)
+ {
+ return mRootInfo;
+ }
+ static PluginManager *pluginManager (void)
+ {
+ return mPlugins;
+ }
+ static Aquamarine::Options *options (void)
+ {
+ return mOptions;
+ }
+ static WId activeId (void)
+ {
+ return mActiveId;
+ }
+ static decor_shadow_options_t *shadowOptions (void)
+ {
+ return &mShadowOptions;
+ }
+ static decor_shadow_t *defaultWindowShadow (decor_context_t *context)
+ {
+ if (!mDefaultShadow)
+ return NULL;
+
+ *context = mDefaultContext;
+ return mDefaultShadow;
+ }
+ static void sendClientMessage (WId eventWid,
+ WId wid,
+ Atom atom,
+ Atom value,
+ long data1 = 0,
+ long data2 = 0,
+ long data3 = 0);
+ static void updateDefaultShadow (Aquamarine::Window *w);
+
+ bool enableDecorations (Time timestamp, int damageEvent);
+ bool x11EventFilter (XEvent *xevent);
+
+ static int onViewport (QPoint pos);
+ static QSize viewports ();
+ static void moveToViewport (WId id, int vp);
+
+ bool isReady ()
+ {
+ return mReady;
+ }
+
+ bool restart () const
+ {
+ return mRestart;
+ }
+
+ public slots:
+
+ void reconfigure (void);
+
+ signals:
+ void desktopGeometryChanged();
+
+ private:
+
+ WId fetchFrame (WId window);
+ void updateShadow (void);
+ void updateAllShadowOptions (void);
+ void updateDesktopGeometry ();
+
+ private slots:
+
+ void handleWindowAdded (WId id);
+ void handleWindowRemoved (WId id);
+ void handleActiveWindowChanged (WId id);
+ void handleWindowChanged (WId id,
+ const unsigned long *properties);
+ void processDamage (void);
+
+ private:
+
+ static PluginManager *mPlugins;
+ static Aquamarine::Options *mOptions;
+ static decor_context_t mDefaultContext;
+ static decor_shadow_t *mDefaultShadow;
+ static decor_shadow_t *mNoBorderShadow;
+ static decor_shadow_options_t mShadowOptions;
+ static NETRootInfo *mRootInfo;
+ static WId mActiveId;
+
+ Aquamarine::Window *mDecorNormal;
+ Aquamarine::Window *mDecorActive;
+ QMap <WId, Aquamarine::Window *>mClients;
+ QMap <WId, Aquamarine::Window *>mFrames;
+ QMap <WId, Aquamarine::Window *>mWindows;
+ KConfig *mConfig;
+ Time mDmSnTimestamp;
+ int mDamageEvent;
+ QTimer mIdleTimer;
+ KWinModule *mKWinModule;
+ QWidget *mCompositeWindow;
+
+ static QSize mDesktop;
+ static QPoint mViewport;
+ static QSize mRootSize;
+
+ WId mActiveWM;
+ bool mRestart;
+ bool mReady;
};
-
}
#endif
diff --git a/src/defaultDeco.cpp b/src/defaultDeco.cpp
deleted file mode 100644
index 3f8bad5..0000000
--- a/src/defaultDeco.cpp
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * Aquamarine the KDE window decorator
- *
- * Copyright (c) 2006 Dennis Kasprzyk <onestone@beryl-project.org>
- * Copyright (c) 2006 Volker Krause <vkrause@kde.org>
- *
- * Uses code of:
- * Emerald window decorator (www.beryl-project.org)
- * gtk-window-decorator (www.freedesktop.org/wiki/Software/Compiz)
- * KWin window manager (www.kde.org)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "defaultDeco.h"
-#include "decorator.h"
-#include "options.h"
-#include "utils.h"
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/Xcomposite.h>
-#include <X11/extensions/shape.h>
-
-#include <fixx11h.h>
-
-#include <kdebug.h>
-#include <kglobal.h>
-#include <kglobalsettings.h>
-#include <klocale.h>
-#include <kiconloader.h>
-#include <kdecoration.h>
-#include <kwin.h>
-#include <klocale.h>
-
-
-#include <qapplication.h>
-#include <qlayout.h>
-#include <qevent.h>
-#include <qpainter.h>
-#include <qobjectlist.h>
-#include <qwidget.h>
-#include <qstring.h>
-#include <qtimer.h>
-#include <qcursor.h>
-#include <qpopupmenu.h>
-
-#define GRAVITY_WEST (1 << 0)
-#define GRAVITY_EAST (1 << 1)
-#define GRAVITY_NORTH (1 << 2)
-#define GRAVITY_SOUTH (1 << 3)
-
-#define XX_MASK (1 << 12)
-#define XY_MASK (1 << 13)
-#define YX_MASK (1 << 14)
-#define YY_MASK (1 << 15)
-
-#define CLAMP_HORZ (1 << 0)
-#define CLAMP_VERT (1 << 1)
-
-#define WM_MOVERESIZE_SIZE_TOPLEFT 0
-#define WM_MOVERESIZE_SIZE_TOP 1
-#define WM_MOVERESIZE_SIZE_TOPRIGHT 2
-#define WM_MOVERESIZE_SIZE_RIGHT 3
-#define WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
-#define WM_MOVERESIZE_SIZE_BOTTOM 5
-#define WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
-#define WM_MOVERESIZE_SIZE_LEFT 7
-#define WM_MOVERESIZE_MOVE 8
-#define WM_MOVERESIZE_SIZE_KEYBOARD 9
-#define WM_MOVERESIZE_MOVE_KEYBOARD 10
-
-extern Atom net_window_decor;
-extern Atom net_wm_moveresize;
-
-extern Atom wm_protocols;
-extern Atom wm_delete_window;
-extern Atom wm_take_focus;
-extern Atom net_wm_context_help;
-extern Atom net_wm_ping;
-extern Atom net_wm_take_activity;
-
-extern struct _cursor cursors[3][3];
-
-Aquamarine::DefaultDecoration::DefaultDecoration (bool active):
-m_active (active),
-m_deco (0)
-{
-
-
- m_icons =
- QIconSet (KGlobal::iconLoader ()->
- loadIcon ("xapp", KIcon::NoGroup, 16),
- KGlobal::iconLoader ()->loadIcon ("xapp",
- KIcon::NoGroup, 32));
-
- m_name = QString ("");
-
- m_geometry = QRect (50, 50, 200, 100);
-
- setWState (Qt::WState_Visible);
-
- createDecoration ();
-}
-
-Aquamarine::DefaultDecoration::~DefaultDecoration ()
-{
- delete
- m_deco;
-
- Atom my_atom = XInternAtom (qt_xdisplay (), "_NET_WINDOW_DECOR_NORMAL", FALSE);
- if (m_active)
- my_atom = XInternAtom (qt_xdisplay (), "_NET_WINDOW_DECOR_ACTIVE", FALSE);
-
- Aquamarine::trapXError ();
- XDeleteProperty (qt_xdisplay (), qt_xrootwin (), my_atom);
- Aquamarine::popXError ();
-}
-
-
-
-bool
-Aquamarine::DefaultDecoration::isActive () const
-{
- return m_active;
-}
-
-bool
-Aquamarine::DefaultDecoration::isCloseable () const
-{
- return false;
-}
-
-bool
-Aquamarine::DefaultDecoration::isMaximizable () const
-{
- return false;
-}
-
-KDecoration::MaximizeMode Aquamarine::DefaultDecoration::maximizeMode () const
-{
- return MaximizeRestore;
-}
-
-bool
-Aquamarine::DefaultDecoration::isMinimizable () const
-{
- return false;
-}
-
-bool
-Aquamarine::DefaultDecoration::providesContextHelp () const
-{
- return false;
-}
-
-int
-Aquamarine::DefaultDecoration::desktop () const
-{
- return 1;
-}
-
-bool
-Aquamarine::DefaultDecoration::isModal () const
-{
- return false;
-}
-
-bool
-Aquamarine::DefaultDecoration::isShadeable () const
-{
- return false;
-}
-
-bool
-Aquamarine::DefaultDecoration::isShade () const
-{
- return false;
-}
-
-bool
-Aquamarine::DefaultDecoration::isSetShade () const
-{
- return isShade ();
-}
-
-bool
-Aquamarine::DefaultDecoration::keepAbove () const
-{
- return false;
-}
-
-bool
-Aquamarine::DefaultDecoration::keepBelow () const
-{
- return false;
-}
-
-bool
-Aquamarine::DefaultDecoration::isMovable () const
-{
- return false;
-}
-
-NET::WindowType Aquamarine::DefaultDecoration::windowType (unsigned long) const
-{
- return NET::Normal;
-}
-
-bool
-Aquamarine::DefaultDecoration::isResizable () const
-{
- return false;
-}
-
-QIconSet
-Aquamarine::DefaultDecoration::icon () const
-{
- return m_icons;
-}
-
-QString
-Aquamarine::DefaultDecoration::caption () const
-{
- return m_name;
-}
-
-void
-Aquamarine::DefaultDecoration::showWindowMenu (QPoint)
-{
-}
-
-void
-Aquamarine::DefaultDecoration::showWindowMenu (const QRect &)
-{
-}
-
-void
-Aquamarine::DefaultDecoration::processMousePressEvent (QMouseEvent *)
-{
-}
-
-void
-Aquamarine::DefaultDecoration::performWindowOperation (WindowOperation)
-{
-}
-
-void
-Aquamarine::DefaultDecoration::setMask (const QRegion &, int)
-{
-}
-
-bool
-Aquamarine::DefaultDecoration::isPreview () const
-{
- return false;
-}
-
-QRect
-Aquamarine::DefaultDecoration::geometry () const
-{
- if (m_deco)
- {
- int
- top,
- bottom,
- left,
- right;
- m_deco->borders (left, right, top, bottom);
- return QRect (0, 0, m_geometry.width () + left + right,
- m_geometry.height () + top + bottom);
- }
- return m_geometry;
-}
-
-QRect
-Aquamarine::DefaultDecoration::iconGeometry () const
-{
- return QRect ();
-}
-
-QRegion
-Aquamarine::DefaultDecoration::unobscuredRegion (const QRegion & r) const
-{
- return r;
-}
-
-QWidget *
-Aquamarine::DefaultDecoration::workspaceWidget () const
-{
- return 0;
-}
-
-WId
-Aquamarine::DefaultDecoration::windowId () const
-{
- return qt_xrootwin();
-}
-
-void
-Aquamarine::DefaultDecoration::closeWindow ()
-{
-}
-
-void
-Aquamarine::DefaultDecoration::maximize (MaximizeMode)
-{
-}
-
-void
-Aquamarine::DefaultDecoration::minimize ()
-{
-}
-
-void
-Aquamarine::DefaultDecoration::showContextHelp ()
-{
-}
-
-void
-Aquamarine::DefaultDecoration::titlebarDblClickOperation ()
-{
-}
-
-void
-Aquamarine::DefaultDecoration::setDesktop (int)
-{
-}
-
-void
-Aquamarine::DefaultDecoration::setKeepBelow (bool)
-{
-}
-
-void
-Aquamarine::DefaultDecoration::setKeepAbove (bool)
-{
-}
-
-void
-Aquamarine::DefaultDecoration::setShade (bool)
-{
-}
-
-void
-Aquamarine::DefaultDecoration::titlebarMouseWheelOperation (int)
-{
-}
-
-int
-Aquamarine::DefaultDecoration::currentDesktop () const
-{
- return 1;
-}
-
-QWidget *
-Aquamarine::DefaultDecoration::initialParentWidget () const
-{
- return const_cast < DefaultDecoration * >(this);
-}
-
-Qt::WFlags Aquamarine::DefaultDecoration::initialWFlags () const
-{
- return 0;
-}
-
-void
-Aquamarine::DefaultDecoration::helperShowHide (bool)
-{
-}
-
-void
-Aquamarine::DefaultDecoration::grabXServer (bool)
-{
-}
-
-void
-Aquamarine::DefaultDecoration::createDecoration ()
-{
- if (m_deco)
- return;
- KDecoration *
- deco = Decorator::pluginManager ()->createDecoration (this);
- deco->init ();
- m_deco = deco;
-
- resizeDecoration ( true );
- grabChildWidgets ();
- updateWindowProperties ();
-}
-
-void
-Aquamarine::DefaultDecoration::resizeDecoration ( bool force )
-{
- int
- top,
- bottom,
- left,
- right;
- m_deco->borders (left, right, top, bottom);
- move (m_geometry.x() - left, m_geometry.y() - top);
- if (!force && m_qpixmap.width () == (m_geometry.width () + left + right)
- && m_qpixmap.height () == (m_geometry.height () + top + bottom))
- return;
-
- if (m_qpixmap.isNull ())
- m_qpixmap =
- QPixmap (m_geometry.width () + left + right,
- m_geometry.height () + top + bottom);
- else
- m_qpixmap.resize (m_geometry.width () + left + right,
- m_geometry.height () + top + bottom);
- resize (m_geometry.width () + left + right,
- m_geometry.height () + top + bottom);
- QPainter::redirect (m_deco->widget (), &m_qpixmap);
- m_deco->
- resize (QSize
- (m_geometry.width () + left + right,
- m_geometry.height () + top + bottom));
- m_deco->widget ()->setShown (true);
-
-}
-
-void
-Aquamarine::DefaultDecoration::updateWindowProperties ()
-{
- Atom my_atom = XInternAtom (qt_xdisplay (), "_NET_WINDOW_DECOR_NORMAL", FALSE);
- if (m_active)
- my_atom = XInternAtom (qt_xdisplay (), "_NET_WINDOW_DECOR_ACTIVE", FALSE);
-
- Pixmap m_pixmap = m_qpixmap.handle ();
-
- int top, bottom, left, right;
- m_deco->borders (left, right, top, bottom);
-
- int
- w_w = m_geometry.width ();
- int
- w_h = m_geometry.height ();
-
- long
- mdata[256];
-
- long *
- data = mdata;
-
- *data++ = 0;
- memcpy (data++, &m_pixmap, sizeof (m_pixmap));
-
- *data++ = left;
- *data++ = right;
- *data++ = top;
- *data++ = bottom;
-
- *data++ = left;
- *data++ = right;
- *data++ = top;
- *data++ = bottom;
-
- *data++ = 0;
- *data++ = 0;
-
- // TOP LEFT
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_NORTH | GRAVITY_WEST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = -left;
- *data++ = -top;
- *data++ = 0;
- *data++ = 0;
- *data++ = left;
- *data++ = top;
- *data++ = 0;
- *data++ = 0;
-
- // TOP RIGHT
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_EAST) << 0) |
- ((GRAVITY_NORTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = 0;
- *data++ = -top;
- *data++ = right;
- *data++ = 0;
- *data++ = right;
- *data++ = top;
- *data++ = left + w_w;
- *data++ = 0;
-
- // BOTTOM LEFT
- *data++ =
- ((GRAVITY_SOUTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_WEST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = -left;
- *data++ = 0;
- *data++ = 0;
- *data++ = bottom;
- *data++ = left;
- *data++ = bottom;
- *data++ = 0;
- *data++ = w_h + top;
-
- // BOTTOM RIGHT
- *data++ =
- ((GRAVITY_SOUTH | GRAVITY_EAST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = 0;
- *data++ = 0;
- *data++ = right;
- *data++ = bottom;
- *data++ = right;
- *data++ = bottom;
- *data++ = left + w_w;
- *data++ = w_h + top;
-
- // TOP CENTER
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_NORTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = 0;
- *data++ = -top;
- *data++ = 0;
- *data++ = 0;
- *data++ = w_w;
- *data++ = top;
- *data++ = left;
- *data++ = 0;
-
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_NORTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (CLAMP_HORZ << 10) | (YY_MASK);
-
- *data++ = w_w;
- *data++ = -top;
- *data++ = 0;
- *data++ = 0;
- *data++ = SHRT_MAX;
- *data++ = top;
- *data++ = left + w_w;
- *data++ = 0;
-
- // BOTTOM CENTER
- *data++ =
- ((GRAVITY_SOUTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- *data++ = bottom;
- *data++ = w_w;
- *data++ = bottom;
- *data++ = left;
- *data++ = w_h + top;
-
- *data++ =
- ((GRAVITY_SOUTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (CLAMP_HORZ << 10) | (YY_MASK);
-
- *data++ = w_w;
- *data++ = 0;
- *data++ = 0;
- *data++ = bottom;
- *data++ = SHRT_MAX;
- *data++ = bottom;
- *data++ = left + w_w;
- *data++ = w_h + top;
-
- //LEFT
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_WEST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = -left;
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- *data++ = left;
- *data++ = w_h;
- *data++ = 0;
- *data++ = top;
-
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_WEST) << 4) |
- (0 << 8) | (CLAMP_VERT << 10) | (XX_MASK);
-
- *data++ = -left;
- *data++ = w_h;
- *data++ = 0;
- *data++ = 0;
- *data++ = left;
- *data++ = SHRT_MAX;
- *data++ = 0;
- *data++ = top + w_h;
-
- //RIGHT
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_EAST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = 0;
- *data++ = 0;
- *data++ = right;
- *data++ = 0;
- *data++ = right;
- *data++ = w_h;
- *data++ = w_w + left;
- *data++ = top;
-
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_EAST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (CLAMP_VERT << 10) | (XX_MASK);
-
- *data++ = 0;
- *data++ = w_h;
- *data++ = right;
- *data++ = 0;
- *data++ = right;
- *data++ = SHRT_MAX;
- *data++ = w_w + left;
- *data++ = top + w_h;
-
- Aquamarine::trapXError ();
- XChangeProperty (qt_xdisplay (), qt_xrootwin(),
- my_atom,
- XA_INTEGER,
- 32, PropModeReplace, (unsigned char *)mdata,
- 12 + (12 * 9));
- Aquamarine::popXError ();
- XSync (qt_xdisplay (), FALSE);
-}
-
-void
-Aquamarine::DefaultDecoration::grabChildWidgets ()
-{
- if (!m_deco)
- return;
-
- QPaintEvent *
- e = new QPaintEvent (m_deco->widget ()->rect (), false);
- QApplication::sendEvent (m_deco->widget (), e);
-
- QPainter * p = 0;
-
- p = new QPainter (&m_qpixmap);
-
- QRegion childs;
-
- const QObjectList * children = m_deco->widget ()->children ();
- if (children)
- {
- QObjectListIt it (*children);
- QObject * child;
- while ((child = it.current ()) != 0)
- {
- ++it;
- if (child->isWidgetType ())
- {
- QWidget * wid = static_cast < QWidget * >(child);
- childs += wid->rect ();
- QPixmap pix = QPixmap::grabWidget (wid);
- p->drawPixmap (wid->pos (), pix);
- }
- }
- }
- delete p;
-}
-
-void
-Aquamarine::DefaultDecoration::reloadDecoration ()
-{
- delete m_deco;
- m_deco = 0;
- createDecoration ();
-}
diff --git a/src/defaultDeco.h b/src/defaultDeco.h
deleted file mode 100644
index 8b97429..0000000
--- a/src/defaultDeco.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Aquamarine the KDE window decorator
- *
- * Copyright (c) 2006 Dennis Kasprzyk <onestone@beryl-project.org>
- * Copyright (c) 2006 Volker Krause <vkrause@kde.org>
- *
- * Uses code of:
- * Emerald window decorator (www.beryl-project.org)
- * gtk-window-decorator (www.freedesktop.org/wiki/Software/Compiz)
- * KWin window manager (www.kde.org)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef AQUAMARINE_DEFAULT_H
-#define AQUAMARINE_DEFAULT_H
-
-#include <kdecoration_p.h>
-
-#include <qpixmap.h>
-#include <qwidget.h>
-
-#include "utils.h"
-#include "options.h"
-
-class KDecoration;
-class QPopupMenu;
-
-namespace Aquamarine
-{
-
- class DefaultDecoration:public QWidget, public KDecorationBridge
- {
- Q_OBJECT public:
-
- public:
- DefaultDecoration (bool active);
- ~DefaultDecoration ();
-
- // KDecorationBridge methods
- virtual bool isActive () const;
- virtual bool isCloseable () const;
- virtual bool isMaximizable () const;
- virtual MaximizeMode maximizeMode () const;
- virtual bool isMinimizable () const;
- virtual bool providesContextHelp () const;
- virtual int desktop () const;
- virtual bool isModal () const;
- virtual bool isShadeable () const;
- virtual bool isShade () const;
- virtual bool isSetShade () const;
- virtual bool keepAbove () const;
- virtual bool keepBelow () const;
- virtual bool isMovable () const;
- virtual bool isResizable () const;
- virtual NET::
- WindowType windowType (unsigned long supported_types) const;
- virtual QIconSet icon () const;
- virtual QString caption () const;
- virtual void processMousePressEvent (QMouseEvent *);
- virtual void showWindowMenu (const QRect &);
- virtual void showWindowMenu (QPoint);
- virtual void performWindowOperation (WindowOperation);
- virtual void setMask (const QRegion &, int);
- virtual bool isPreview () const;
- virtual QRect geometry () const;
- virtual QRect iconGeometry () const;
- virtual QRegion unobscuredRegion (const QRegion & r) const;
- virtual QWidget *workspaceWidget () const;
- virtual WId windowId () const;
- virtual void closeWindow ();
- virtual void maximize (MaximizeMode mode);
- virtual void minimize ();
- virtual void showContextHelp ();
- virtual void setDesktop (int desktop);
- virtual void titlebarDblClickOperation ();
- virtual void titlebarMouseWheelOperation (int delta);
- virtual void setShade (bool set);
- virtual void setKeepAbove (bool);
- virtual void setKeepBelow (bool);
-
- virtual int currentDesktop () const;
- virtual QWidget *initialParentWidget () const;
- virtual Qt::WFlags initialWFlags () const;
- virtual void helperShowHide (bool);
- virtual void grabXServer (bool grab);
-
- void reloadDecoration ();
-
- private:
- void createDecoration ();
- void resizeDecoration ( bool force = false );
-
- private slots:
- void grabChildWidgets ();
- void updateWindowProperties ();
-
- private:
-
- // window properties
- QRect m_geometry;
- bool m_active;
- QString m_name;
- QIconSet m_icons;
-
- // decoration stuff
- KDecoration *m_deco;
- QPixmap m_qpixmap;
-
- };
-
-}
-
-#endif
diff --git a/src/defaultShadow.cpp b/src/defaultShadow.cpp
deleted file mode 100644
index d44b437..0000000
--- a/src/defaultShadow.cpp
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Aquamarine the KDE window decorator
- *
- * Copyright (c) 2006 Dennis Kasprzyk <onestone@beryl-project.org>
- * Copyright (c) 2006 Volker Krause <vkrause@kde.org>
- *
- * Uses code of:
- * Emerald window decorator (www.beryl-project.org)
- * gtk-window-decorator (www.freedesktop.org/wiki/Software/Compiz)
- * KWin window manager (www.kde.org)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "defaultShadow.h"
-#include "decorator.h"
-#include "utils.h"
-#include "settings.h"
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/Xrender.h>
-
-#include <math.h>
-
-#include <fixx11h.h>
-
-#include <kglobal.h>
-
-#define BERYL_ADVANCED_DECORATION_VERSION 10121980
-
-#define GRAVITY_WEST (1 << 0)
-#define GRAVITY_EAST (1 << 1)
-#define GRAVITY_NORTH (1 << 2)
-#define GRAVITY_SOUTH (1 << 3)
-
-#define XX_MASK (1 << 12)
-#define XY_MASK (1 << 13)
-#define YX_MASK (1 << 14)
-#define YY_MASK (1 << 15)
-
-#define CLAMP_HORZ (1 << 0)
-#define CLAMP_VERT (1 << 1)
-
-Aquamarine::DefaultShadow::DefaultShadow ()
-{
-
- double op = Settings::shadowOpacity() / 100.0;
- op *= 0xffff;
-
- m_sradius = Settings::shadowRadius();
- QColor color = Settings::shadowColor();
- m_scolor[0] = short((color.red() / 256.0) * 0xffff);
- m_scolor[1] = short((color.green() / 256.0) * 0xffff);
- m_scolor[2] = short((color.blue() / 256.0) * 0xffff);
- m_scolor[3] = short(op);
-
- // shifted shadows do not work now
- /*
- int offX = Settings::shadowOffsetX();
- int offY = Settings::shadowOffsetY();
- offX = KMAX(-m_sradius,KMIN(m_sradius,offX));
- offY = KMAX(-m_sradius,KMIN(m_sradius,offY));
- */
- int offX = 0;
- int offY = 0;
-
- m_soffset.setCoords(-m_sradius + offX,-m_sradius + offY,
- m_sradius + offX,m_sradius + offY);
-
- m_qpixmap = QPixmap(20 + m_soffset.width(),20 + m_soffset.height());
-
- renderShadow();
- updateWindowProperties();
-
-}
-
-Aquamarine::DefaultShadow::~DefaultShadow ()
-{
- Aquamarine::trapXError ();
- XDeleteProperty (qt_xdisplay (), qt_xrootwin (),
- XInternAtom (qt_xdisplay (), "_NET_WINDOW_DECOR_BARE", FALSE));
- Aquamarine::popXError ();
-}
-
-
-
-
-void
-Aquamarine::DefaultShadow::updateWindowProperties ()
-{
-
- Pixmap pix = m_qpixmap.handle();
-
- int otop = -m_soffset.top();
- int obottom = m_soffset.bottom();
- int oleft = -m_soffset.left();
- int oright = m_soffset.right();
-
- int num = 8;
-
- long mdata[256];
-
- long *data = mdata;
-
- *data++ = BERYL_ADVANCED_DECORATION_VERSION;
-
- memcpy (data++, &pix, sizeof (pix));
-
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
-
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
-
- *data++ = 0;
- *data++ = 0;
-
- *data++ = 0;
- *data++ = (unsigned short)((Settings::activeOpacity() / 100.0) * 0xffff);
- *data++ = (unsigned short)((Settings::activeOpacity() / 100.0) * 0xffff);
-
- // TOP LEFT
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_NORTH | GRAVITY_WEST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = -oleft;
- *data++ = -otop;
- *data++ = 0;
- *data++ = 0;
- *data++ = oleft;
- *data++ = otop;
- *data++ = 0;
- *data++ = 0;
-
- // TOP RIGHT
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_EAST) << 0) |
- ((GRAVITY_NORTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = 0;
- *data++ = -otop;
- *data++ = oright;
- *data++ = 0;
- *data++ = oright;
- *data++ = otop;
- *data++ = oleft + 20;
- *data++ = 0;
-
- // BOTTOM LEFT
- *data++ =
- ((GRAVITY_SOUTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_WEST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = -oleft;
- *data++ = 0;
- *data++ = 0;
- *data++ = obottom;
- *data++ = oleft;
- *data++ = obottom;
- *data++ = 0;
- *data++ = 20 + otop;
-
- // BOTTOM RIGHT
- *data++ =
- ((GRAVITY_SOUTH | GRAVITY_EAST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (0 << 10) | (XX_MASK) | (YY_MASK);
-
- *data++ = 0;
- *data++ = 0;
- *data++ = oright;
- *data++ = obottom;
- *data++ = oright;
- *data++ = obottom;
- *data++ = oleft + 20;
- *data++ = 20 + otop;
-
- // TOP CENTER
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_NORTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (CLAMP_HORZ << 10) | (YY_MASK);
-
- *data++ = 0;
- *data++ = -otop;
- *data++ = 0;
- *data++ = 0;
- *data++ = SHRT_MAX;
- *data++ = otop;
- *data++ = oleft;
- *data++ = 0;
-
- // BOTTOM CENTER
-
- *data++ =
- ((GRAVITY_SOUTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (CLAMP_HORZ << 10) | (YY_MASK);
-
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- *data++ = obottom;
- *data++ = SHRT_MAX;
- *data++ = obottom;
- *data++ = oleft;
- *data++ = 20 + otop;
-
- //LEFT
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_WEST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_WEST) << 4) |
- (0 << 8) | (CLAMP_VERT << 10) | (XX_MASK);
-
- *data++ = -oleft;
- *data++ = 0;
- *data++ = 0;
- *data++ = 0;
- *data++ = oleft;
- *data++ = SHRT_MAX;
- *data++ = 0;
- *data++ = otop;
-
- //RIGHT
-
- *data++ =
- ((GRAVITY_NORTH | GRAVITY_EAST) << 0) |
- ((GRAVITY_SOUTH | GRAVITY_EAST) << 4) |
- (0 << 8) | (CLAMP_VERT << 10) | (XX_MASK);
-
- *data++ = 0;
- *data++ = 0;
- *data++ = oright;
- *data++ = 0;
- *data++ = oright;
- *data++ = SHRT_MAX;
- *data++ = 20 + oleft;
- *data++ = otop;
-
- Aquamarine::trapXError ();
- XChangeProperty (qt_xdisplay (), qt_xrootwin (),
- XInternAtom (qt_xdisplay (), "_NET_WINDOW_DECOR_BARE", FALSE),
- XA_INTEGER,
- 32, PropModeReplace, (unsigned char *)mdata,
- 15 + (num * 9));
- Aquamarine::popXError ();
- XSync (qt_xdisplay (), FALSE);
-}
-
-
-#if INT_MAX != LONG_MAX
-/* XRenderSetPictureFilter used to be broken on LP64. This
- * works with either the broken or fixed version.
- */
-static void
-XRenderSetPictureFilter_wrapper (Display *dpy,
- Picture picture,
- char *filter,
- XFixed *params,
- int nparams)
-{
- Aquamarine::trapXError ();
- XRenderSetPictureFilter (dpy, picture, filter, params, nparams);
- XSync (dpy, False);
- if (Aquamarine::popXError ())
- {
- long *long_params = new long[nparams];
- int i;
-
- for (i = 0; i < nparams; i++)
- long_params[i] = params[i];
-
- XRenderSetPictureFilter (dpy, picture, filter,
- (XFixed *) long_params, nparams);
- delete long_params;
- }
-}
-
-#define XRenderSetPictureFilter XRenderSetPictureFilter_wrapper
-#endif
-
-#define SIGMA(r) ((r) / 2.0)
-#define ALPHA(r) (r)
-
-void Aquamarine::DefaultShadow::renderShadow ()
-{
-
-
- QPixmap qRegPix(20, 20, 32);
- QPixmap qTmpPix(20 + m_soffset.width(), 20, 32);
- qRegPix.fill( QColor(0, ((m_scolor[3] >> 8) << 24) + 0xffffff));
-
- XFixed *params;
- int n_params = 0;
- int size;
-
- params = createGaussianKernel (&size);
-
- n_params = size + 2;
- size = size / 2;
-
- params[0] = (n_params - 2) << 16;
- params[1] = 1 << 16;
-
- XRenderPictFormat *format;
- format = XRenderFindStandardFormat (qt_xdisplay(), PictStandardARGB32);
-
- char *filter = NULL;
- XFilters* filters = XRenderQueryFilters (qt_xdisplay(), qRegPix.handle());
- if (filters)
- {
- int i;
-
- for (i = 0; i < filters->nfilter; i++)
- {
- if (strcmp (filters->filter[i], FilterConvolution) == 0)
- {
- filter = (char *) FilterConvolution;
- break;
- }
- }
-
- XFree (filters);
- }
- if (!filter)
- return;
-
- static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
-
- Picture fill = XRenderCreateSolidFill (qt_xdisplay(), &white);
- Picture src = XRenderCreatePicture(qt_xdisplay(), qRegPix.handle(), format, 0, NULL);
- Picture tmp = XRenderCreatePicture(qt_xdisplay(), qTmpPix.handle(), format, 0, NULL);
- Picture dst = XRenderCreatePicture(qt_xdisplay(), m_qpixmap.handle(), format, 0, NULL);
-
- setPictureTransform(src,size,0);
- XRenderSetPictureFilter (qt_xdisplay(), src, filter, params, n_params);
- XRenderComposite (qt_xdisplay(), PictOpSrc, fill, src, tmp, 0, 0, 0, 0, 0, 0, 20 + m_soffset.width(), 20);
-
- XRenderFreePicture (qt_xdisplay(), fill);
-
- params[0] = 1 << 16;
- params[1] = (n_params - 2) << 16;
-
- XRenderFreePicture (qt_xdisplay(), src);
- XRenderColor color = { m_scolor[0], m_scolor[1], m_scolor[2], 0xffff };
-
- src = XRenderCreateSolidFill (qt_xdisplay(), &color);
-
- setPictureTransform(tmp,0,size);
- XRenderSetPictureFilter (qt_xdisplay(), tmp, filter, params, n_params);
-
- XRenderComposite (qt_xdisplay(), PictOpSrc, src, tmp, dst, 0, 0, 0, 0, 0, 0, 20 + m_soffset.width(), 20 + m_soffset.height());
-
- XRenderFreePicture (qt_xdisplay(), src);
- XRenderFreePicture (qt_xdisplay(), tmp);
- XRenderFreePicture (qt_xdisplay(), dst);
-
- delete params;
-}
-
-XFixed *Aquamarine::DefaultShadow::createGaussianKernel (int *r_size)
-{
- double sigma = m_sradius / 2.0;
- double alpha = m_sradius;
- double radius = m_sradius;
-
- XFixed *params;
- double *amp, scale, x_scale, fx, sum;
- int size, half_size, x, i, n;
-
- scale = 1.0f / (2.0f * M_PI * sigma * sigma);
- half_size = int(alpha + 0.5f);
-
- if (half_size == 0)
- half_size = 1;
-
- size = half_size * 2 + 1;
- x_scale = 2.0f * radius / size;
-
- if (size < 3)
- return NULL;
-
- n = size;
-
- amp = new double[n];
- if (!amp)
- return NULL;
-
- n += 2;
-
- params = new XFixed[n];
- if (!params)
- return NULL;
-
- i = 0;
- sum = 0.0f;
-
- for (x = 0; x < size; x++)
- {
- fx = x_scale * (x - half_size);
-
- amp[i] = scale * exp ((-1.0f * (fx * fx)) / (2.0f * sigma * sigma));
-
- sum += amp[i];
-
- i++;
- }
-
- /* normalize */
- if (sum != 0.0)
- sum = 1.0 / sum;
-
- params[0] = params[1] = 0;
-
- for (i = 2; i < n; i++)
- params[i] = XDoubleToFixed (amp[i - 2] * sum);
-
- delete amp;
-
- *r_size = size;
-
- return params;
-}
-
-void Aquamarine::DefaultShadow::setPictureTransform (Picture p, int dx, int dy)
-{
- XTransform transform = {
- {
- { 1 << 16, 0, -dx << 16 },
- { 0, 1 << 16, -dy << 16 },
- { 0, 0, 1 << 16 },
- }
- };
-
- XRenderSetPictureTransform (qt_xdisplay(), p, &transform);
-}
-
diff --git a/src/defaultShadow.h b/src/defaultShadow.h
deleted file mode 100644
index 45b7d80..0000000
--- a/src/defaultShadow.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Aquamarine the KDE window decorator
- *
- * Copyright (c) 2006 Dennis Kasprzyk <onestone@beryl-project.org>
- * Copyright (c) 2006 Volker Krause <vkrause@kde.org>
- *
- * Uses code of:
- * Emerald window decorator (www.beryl-project.org)
- * gtk-window-decorator (www.freedesktop.org/wiki/Software/Compiz)
- * KWin window manager (www.kde.org)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef AQUAMARINE_SHADOW_H
-#define AQUAMARINE_SHADOW_H
-
-#include <qpixmap.h>
-
-#include <X11/extensions/Xrender.h>
-
-#include "utils.h"
-#include "options.h"
-
-namespace Aquamarine
-{
-
- class DefaultShadow
- {
-
- public:
- DefaultShadow ();
- ~DefaultShadow ();
-
- private:
- void renderShadow ();
- void updateWindowProperties ();
- XFixed *createGaussianKernel (int *r_size);
- void setPictureTransform (Picture p, int dx, int dy);
-
- private:
-
- QPixmap m_qpixmap;
-
- // shadow
- QRect m_soffset;
- int m_sradius;
- short m_scolor[4];
- };
-
-}
-
-#endif
diff --git a/src/libdeco.c b/src/libdeco.c
new file mode 100644
index 0000000..a5d96e3
--- /dev/null
+++ b/src/libdeco.c
@@ -0,0 +1,2620 @@
+/*
+ * Copyright © 2006 Novell, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "libdeco.h"
+
+#include <X11/Xatom.h>
+#include <X11/Xregion.h>
+
+int
+decor_version (void)
+{
+ return DECOR_INTERFACE_VERSION;
+}
+
+/*
+ decoration property
+ -------------------
+
+ data[0] = version
+
+ data[1] = pixmap
+
+ data[2] = input left
+ data[3] = input right
+ data[4] = input top
+ data[5] = input bottom
+
+ data[6] = input left when maximized
+ data[7] = input right when maximized
+ data[8] = input top when maximized
+ data[9] = input bottom when maximized
+
+ data[10] = min width
+ data[11] = min height
+
+ flags
+
+ 1st to 4nd bit p1 gravity, 5rd to 8th bit p2 gravity,
+ 9rd and 10th bit alignment, 11rd and 12th bit clamp,
+ 13th bit XX, 14th bit XY, 15th bit YX, 16th bit YY.
+
+ data[11 + n * 9 + 1] = flags
+ data[11 + n * 9 + 2] = p1 x
+ data[11 + n * 9 + 3] = p1 y
+ data[11 + n * 9 + 4] = p2 x
+ data[11 + n * 9 + 5] = p2 y
+ data[11 + n * 9 + 6] = widthMax
+ data[11 + n * 9 + 7] = heightMax
+ data[11 + n * 9 + 8] = x0
+ data[11 + n * 9 + 9] = y0
+ */
+void
+decor_quads_to_property (long *data,
+ Pixmap pixmap,
+ decor_extents_t *input,
+ decor_extents_t *max_input,
+ int min_width,
+ int min_height,
+ decor_quad_t *quad,
+ int nQuad)
+{
+ *data++ = DECOR_INTERFACE_VERSION;
+
+ memcpy (data++, &pixmap, sizeof (Pixmap));
+
+ *data++ = input->left;
+ *data++ = input->right;
+ *data++ = input->top;
+ *data++ = input->bottom;
+
+ *data++ = max_input->left;
+ *data++ = max_input->right;
+ *data++ = max_input->top;
+ *data++ = max_input->bottom;
+
+ *data++ = min_width;
+ *data++ = min_height;
+
+ while (nQuad--)
+ {
+ *data++ =
+ (quad->p1.gravity << 0) |
+ (quad->p2.gravity << 4) |
+ (quad->align << 8) |
+ (quad->clamp << 10) |
+ (quad->m.xx ? XX_MASK : 0) |
+ (quad->m.xy ? XY_MASK : 0) |
+ (quad->m.yx ? YX_MASK : 0) |
+ (quad->m.yy ? YY_MASK : 0);
+
+ *data++ = quad->p1.x;
+ *data++ = quad->p1.y;
+ *data++ = quad->p2.x;
+ *data++ = quad->p2.y;
+ *data++ = quad->max_width;
+ *data++ = quad->max_height;
+ *data++ = quad->m.x0;
+ *data++ = quad->m.y0;
+
+ quad++;
+ }
+}
+
+int
+decor_property_get_version (long *data)
+{
+ return (int) *data;
+}
+
+int
+decor_property_to_quads (long *data,
+ int size,
+ Pixmap *pixmap,
+ decor_extents_t *input,
+ decor_extents_t *max_input,
+ int *min_width,
+ int *min_height,
+ decor_quad_t *quad)
+{
+ int i, n, flags;
+
+ if (size < BASE_PROP_SIZE + QUAD_PROP_SIZE)
+ return 0;
+
+ if (decor_property_get_version (data) != decor_version ())
+ return 0;
+
+ data++;
+
+ memcpy (pixmap, data++, sizeof (Pixmap));
+
+ input->left = *data++;
+ input->right = *data++;
+ input->top = *data++;
+ input->bottom = *data++;
+
+ max_input->left = *data++;
+ max_input->right = *data++;
+ max_input->top = *data++;
+ max_input->bottom = *data++;
+
+ *min_width = *data++;
+ *min_height = *data++;
+
+ n = (size - BASE_PROP_SIZE) / QUAD_PROP_SIZE;
+
+ for (i = 0; i < n; i++)
+ {
+ flags = *data++;
+
+ quad->p1.gravity = (flags >> 0) & 0xf;
+ quad->p2.gravity = (flags >> 4) & 0xf;
+
+ quad->align = (flags >> 8) & 0x3;
+ quad->clamp = (flags >> 10) & 0x3;
+
+ quad->m.xx = (flags & XX_MASK) ? 1.0f : 0.0f;
+ quad->m.xy = (flags & XY_MASK) ? 1.0f : 0.0f;
+ quad->m.yx = (flags & YX_MASK) ? 1.0f : 0.0f;
+ quad->m.yy = (flags & YY_MASK) ? 1.0f : 0.0f;
+
+ quad->p1.x = *data++;
+ quad->p1.y = *data++;
+ quad->p2.x = *data++;
+ quad->p2.y = *data++;
+
+ quad->max_width = *data++;
+ quad->max_height = *data++;
+
+ quad->m.x0 = *data++;
+ quad->m.y0 = *data++;
+
+ quad++;
+ }
+
+ return n;
+}
+
+int
+decor_set_vert_quad_row (decor_quad_t *q,
+ int top,
+ int top_corner,
+ int bottom,
+ int bottom_corner,
+ int left,
+ int right,
+ int gravity,
+ int height,
+ int splitY,
+ int splitGravity,
+ double x0,
+ double y0,
+ int rotation)
+{
+ int nQuad = 0;
+
+ q->p1.x = left;
+ q->p1.y = -top;
+ q->p1.gravity = gravity | GRAVITY_NORTH;
+ q->p2.x = right;
+ q->p2.y = splitY;
+ q->p2.gravity = gravity | splitGravity;
+ q->max_width = SHRT_MAX;
+ q->max_height = top + top_corner;
+ q->align = ALIGN_TOP;
+ q->clamp = CLAMP_VERT;
+ q->m.x0 = x0;
+ q->m.y0 = y0;
+
+ if (rotation)
+ {
+ q->m.xx = 0.0;
+ q->m.xy = 1.0;
+ q->m.yx = 1.0;
+ q->m.yy = 0.0;
+ }
+ else
+ {
+ q->m.xx = 1.0;
+ q->m.xy = 0.0;
+ q->m.yx = 0.0;
+ q->m.yy = 1.0;
+ }
+
+ q++; nQuad++;
+
+ q->p1.x = left;
+ q->p1.y = top_corner;
+ q->p1.gravity = gravity | GRAVITY_NORTH;
+ q->p2.x = right;
+ q->p2.y = -bottom_corner;
+ q->p2.gravity = gravity | GRAVITY_SOUTH;
+ q->max_width = SHRT_MAX;
+ q->max_height = SHRT_MAX;
+ q->align = 0;
+ q->clamp = CLAMP_VERT;
+
+ if (rotation)
+ {
+ q->m.xx = 0.0;
+ q->m.xy = 0.0;
+ q->m.yx = 1.0;
+ q->m.yy = 0.0;
+ q->m.x0 = x0 + top + top_corner;
+ q->m.y0 = y0;
+ }
+ else
+ {
+ q->m.xx = 1.0;
+ q->m.xy = 0.0;
+ q->m.yx = 0.0;
+ q->m.yy = 0.0;
+ q->m.x0 = x0;
+ q->m.y0 = y0 + top + top_corner;
+ }
+
+ q++; nQuad++;
+
+ q->p1.x = left;
+ q->p1.y = splitY;
+ q->p1.gravity = gravity | splitGravity;
+ q->p2.x = right;
+ q->p2.y = bottom;
+ q->p2.gravity = gravity | GRAVITY_SOUTH;
+ q->max_width = SHRT_MAX;
+ q->max_height = bottom_corner + bottom;
+ q->align = ALIGN_BOTTOM;
+ q->clamp = CLAMP_VERT;
+
+ if (rotation)
+ {
+ q->m.xx = 0.0;
+ q->m.xy = 1.0;
+ q->m.yx = 1.0;
+ q->m.yy = 0.0;
+ q->m.x0 = x0 + height;
+ q->m.y0 = y0;
+ }
+ else
+ {
+ q->m.xx = 1.0;
+ q->m.xy = 0.0;
+ q->m.yx = 0.0;
+ q->m.yy = 1.0;
+ q->m.x0 = x0;
+ q->m.y0 = y0 + height;
+ }
+
+ nQuad++;
+
+ return nQuad;
+}
+
+int
+decor_set_horz_quad_line (decor_quad_t *q,
+ int left,
+ int left_corner,
+ int right,
+ int right_corner,
+ int top,
+ int bottom,
+ int gravity,
+ int width,
+ int splitX,
+ int splitGravity,
+ double x0,
+ double y0)
+{
+ int nQuad = 0;
+
+ q->p1.x = -left;
+ q->p1.y = top;
+ q->p1.gravity = gravity | GRAVITY_WEST;
+ q->p2.x = splitX;
+ q->p2.y = bottom;
+ q->p2.gravity = gravity | splitGravity;
+ q->max_width = left + left_corner;
+ q->max_height = SHRT_MAX;
+ q->align = ALIGN_LEFT;
+ q->clamp = 0;
+ q->m.xx = 1.0;
+ q->m.xy = 0.0;
+ q->m.yx = 0.0;
+ q->m.yy = 1.0;
+ q->m.x0 = x0;
+ q->m.y0 = y0;
+
+ q++; nQuad++;
+
+ q->p1.x = left_corner;
+ q->p1.y = top;
+ q->p1.gravity = gravity | GRAVITY_WEST;
+ q->p2.x = -right_corner;
+ q->p2.y = bottom;
+ q->p2.gravity = gravity | GRAVITY_EAST;
+ q->max_width = SHRT_MAX;
+ q->max_height = SHRT_MAX;
+ q->align = 0;
+ q->clamp = 0;
+ q->m.xx = 0.0;
+ q->m.xy = 0.0;
+ q->m.yx = 0.0;
+ q->m.yy = 1.0;
+ q->m.x0 = x0 + left + left_corner;
+ q->m.y0 = y0;
+
+ q++; nQuad++;
+
+ q->p1.x = splitX;
+ q->p1.y = top;
+ q->p1.gravity = gravity | splitGravity;
+ q->p2.x = right;
+ q->p2.y = bottom;
+ q->p2.gravity = gravity | GRAVITY_EAST;
+ q->max_width = right_corner + right;
+ q->max_height = SHRT_MAX;
+ q->align = ALIGN_RIGHT;
+ q->clamp = 0;
+ q->m.xx = 1.0;
+ q->m.xy = 0.0;
+ q->m.yx = 0.0;
+ q->m.yy = 1.0;
+ q->m.x0 = x0 + width;
+ q->m.y0 = y0;
+
+ nQuad++;
+
+ return nQuad;
+}
+
+int
+decor_set_lSrS_window_quads (decor_quad_t *q,
+ decor_context_t *c,
+ decor_layout_t *l)
+{
+ int lh, rh, splitY, n, nQuad = 0;
+
+ splitY = (c->top_corner_space - c->bottom_corner_space) / 2;
+
+ if (l->rotation)
+ {
+ lh = l->left.x2 - l->left.x1;
+ rh = l->right.x2 - l->right.x1;
+ }
+ else
+ {
+ lh = l->left.y2 - l->left.y1;
+ rh = l->right.y2 - l->right.y1;
+ }
+
+ /* left quads */
+ n = decor_set_vert_quad_row (q,
+ 0,
+ c->top_corner_space,
+ 0,
+ c->bottom_corner_space,
+ -c->left_space,
+ 0,
+ GRAVITY_WEST,
+ lh,
+ splitY,
+ 0,
+ l->left.x1,
+ l->left.y1,
+ l->rotation);
+
+ q += n; nQuad += n;
+
+ /* right quads */
+ n = decor_set_vert_quad_row (q,
+ 0,
+ c->top_corner_space,
+ 0,
+ c->bottom_corner_space,
+ 0,
+ c->right_space,
+ GRAVITY_EAST,
+ rh,
+ splitY,
+ 0,
+ l->right.x1,
+ l->right.y1,
+ l->rotation);
+
+ nQuad += n;
+
+ return nQuad;
+}
+
+int
+decor_set_lSrStSbS_window_quads (decor_quad_t *q,
+ decor_context_t *c,
+ decor_layout_t *l)
+{
+ int splitX, n, nQuad = 0;
+
+ splitX = (c->left_corner_space - c->right_corner_space) / 2;
+
+ /* top quads */
+ n = decor_set_horz_quad_line (q,
+ c->left_space,
+ c->left_corner_space,
+ c->right_space,
+ c->right_corner_space,
+ -c->top_space,
+ 0,
+ GRAVITY_NORTH,
+ l->top.x2 - l->top.x1,
+ splitX,
+ 0,
+ l->top.x1,
+ l->top.y1);
+
+ q += n; nQuad += n;
+
+ n = decor_set_lSrS_window_quads (q, c, l);
+
+ q += n; nQuad += n;
+
+ /* bottom quads */
+ n = decor_set_horz_quad_line (q,
+ c->left_space,
+ c->left_corner_space,
+ c->right_space,
+ c->right_corner_space,
+ 0,
+ c->bottom_space,
+ GRAVITY_SOUTH,
+ l->bottom.x2 - l->bottom.x1,
+ splitX,
+ 0,
+ l->bottom.x1,
+ l->bottom.y1);
+
+ nQuad += n;
+
+ return nQuad;
+}
+
+int
+decor_set_lSrStXbS_window_quads (decor_quad_t *q,
+ decor_context_t *c,
+ decor_layout_t *l,
+ int top_stretch_offset)
+{
+ int splitX, n, nQuad = 0;
+ int top_left, top_right;
+
+ splitX = (c->left_corner_space - c->right_corner_space) / 2;
+
+ top_left = top_stretch_offset;
+ top_right = l->top.x2 - l->top.x1 -
+ c->left_space - c->right_space - top_left - 1;
+
+ /* top quads */
+ n = decor_set_horz_quad_line (q,
+ c->left_space,
+ top_left,
+ c->right_space,
+ top_right,
+ -c->top_space,
+ 0,
+ GRAVITY_NORTH,
+ l->top.x2 - l->top.x1,
+ -top_right,
+ GRAVITY_EAST,
+ l->top.x1,
+ l->top.y1);
+
+ q += n; nQuad += n;
+
+ n = decor_set_lSrS_window_quads (q, c, l);
+
+ q += n; nQuad += n;
+
+ /* bottom quads */
+ n = decor_set_horz_quad_line (q,
+ c->left_space,
+ c->left_corner_space,
+ c->right_space,
+ c->right_corner_space,
+ 0,
+ c->bottom_space,
+ GRAVITY_SOUTH,
+ l->bottom.x2 - l->bottom.x1,
+ splitX,
+ 0,
+ l->bottom.x1,
+ l->bottom.y1);
+
+ nQuad += n;
+
+ return nQuad;
+}
+
+int
+decor_set_lSrStSbX_window_quads (decor_quad_t *q,
+ decor_context_t *c,
+ decor_layout_t *l,
+ int bottom_stretch_offset)
+{
+ int splitX, n, nQuad = 0;
+ int bottom_left, bottom_right;
+
+ splitX = (c->left_corner_space - c->right_corner_space) / 2;
+
+ bottom_left = bottom_stretch_offset;
+ bottom_right = l->bottom.x2 - l->bottom.x1 -
+ c->left_space - c->right_space - bottom_left - 1;
+
+ /* top quads */
+ n = decor_set_horz_quad_line (q,
+ c->left_space,
+ c->left_corner_space,
+ c->right_space,
+ c->right_corner_space,
+ -c->top_space,
+ 0,
+ GRAVITY_NORTH,
+ l->top.x2 - l->top.x1,
+ splitX,
+ 0,
+ l->top.x1,
+ l->top.y1);
+
+ q += n; nQuad += n;
+
+ n = decor_set_lSrS_window_quads (q, c, l);
+
+ q += n; nQuad += n;
+
+ /* bottom quads */
+ n = decor_set_horz_quad_line (q,
+ c->left_space,
+ bottom_left,
+ c->right_space,
+ bottom_right,
+ 0,
+ c->bottom_space,
+ GRAVITY_SOUTH,
+ l->bottom.x2 - l->bottom.x1,
+ -bottom_right,
+ GRAVITY_EAST,
+ l->bottom.x1,
+ l->bottom.y1);
+
+ nQuad += n;
+
+ return nQuad;
+}
+
+int
+decor_set_lXrXtXbX_window_quads (decor_quad_t *q,
+ decor_context_t *c,
+ decor_layout_t *l,
+ int left_stretch_offset,
+ int right_stretch_offset,
+ int top_stretch_offset,
+ int bottom_stretch_offset)
+{
+ int lh, rh, n, nQuad = 0;
+ int left_top, left_bottom;
+ int right_top, right_bottom;
+ int top_left, top_right;
+ int bottom_left, bottom_right;
+
+ top_left = top_stretch_offset;
+ top_right = l->top.x2 - l->top.x1 -
+ c->left_space - c->right_space - top_left - 1;
+
+ bottom_left = bottom_stretch_offset;
+ bottom_right = l->bottom.x2 - l->bottom.x1 -
+ c->left_space - c->right_space - bottom_left - 1;
+
+ if (l->rotation)
+ {
+ lh = l->left.x2 - l->left.x1;
+ rh = l->right.x2 - l->right.x1;
+ }
+ else
+ {
+ lh = l->left.y2 - l->left.y1;
+ rh = l->right.y2 - l->right.y1;
+ }
+
+ left_top = left_stretch_offset;
+ left_bottom = lh - left_top - 1;
+
+ right_top = right_stretch_offset;
+ right_bottom = rh - right_top - 1;
+
+
+ /* top quads */
+ n = decor_set_horz_quad_line (q,
+ c->left_space,
+ top_left,
+ c->right_space,
+ top_right,
+ -c->top_space,
+ 0,
+ GRAVITY_NORTH,
+ l->top.x2 - l->top.x1,
+ -top_right,
+ GRAVITY_EAST,
+ l->top.x1,
+ l->top.y1);
+
+ q += n; nQuad += n;
+
+ /* left quads */
+ n = decor_set_vert_quad_row (q,
+ 0,
+ left_top,
+ 0,
+ left_bottom,
+ -c->left_space,
+ 0,
+ GRAVITY_WEST,
+ lh,
+ -left_bottom,
+ GRAVITY_SOUTH,
+ l->left.x1,
+ l->left.y1,
+ l->rotation);
+
+ q += n; nQuad += n;
+
+ /* right quads */
+ n = decor_set_vert_quad_row (q,
+ 0,
+ right_top,
+ 0,
+ right_bottom,
+ 0,
+ c->right_space,
+ GRAVITY_EAST,
+ rh,
+ -right_bottom,
+ GRAVITY_SOUTH,
+ l->right.x1,
+ l->right.y1,
+ l->rotation);
+
+ q += n; nQuad += n;
+
+ /* bottom quads */
+ n = decor_set_horz_quad_line (q,
+ c->left_space,
+ bottom_left,
+ c->right_space,
+ bottom_right,
+ 0,
+ c->bottom_space,
+ GRAVITY_SOUTH,
+ l->bottom.x2 - l->bottom.x1,
+ -bottom_right,
+ GRAVITY_EAST,
+ l->bottom.x1,
+ l->bottom.y1);
+
+ nQuad += n;
+
+ return nQuad;
+}
+
+#if INT_MAX != LONG_MAX
+
+static int errors;
+
+static int
+error_handler (Display *xdisplay,
+ XErrorEvent *event)
+{
+ errors++;
+ return 0;
+}
+
+/* XRenderSetPictureFilter used to be broken on LP64. This
+ * works with either the broken or fixed version.
+ */
+static void
+XRenderSetPictureFilter_wrapper (Display *dpy,
+ Picture picture,
+ char *filter,
+ XFixed *params,
+ int nparams)
+{
+ int (*old) (Display *, XErrorEvent *);
+
+ errors = 0;
+
+ old = XSetErrorHandler (error_handler);
+
+ XRenderSetPictureFilter (dpy, picture, filter, params, nparams);
+ XSync (dpy, False);
+
+ XSetErrorHandler (old);
+
+ if (errors)
+ {
+ long *long_params = malloc (sizeof (long) * nparams);
+ int i;
+
+ for (i = 0; i < nparams; i++)
+ long_params[i] = params[i];
+
+ XRenderSetPictureFilter (dpy, picture, filter,
+ (XFixed *) long_params, nparams);
+ free (long_params);
+ }
+}
+
+#define XRenderSetPictureFilter XRenderSetPictureFilter_wrapper
+#endif
+
+static void
+set_picture_transform (Display *xdisplay,
+ Picture p,
+ int dx,
+ int dy)
+{
+ XTransform transform = {
+ {
+ { 1 << 16, 0, -dx << 16 },
+ { 0, 1 << 16, -dy << 16 },
+ { 0, 0, 1 << 16 },
+ }
+ };
+
+ XRenderSetPictureTransform (xdisplay, p, &transform);
+}
+
+static void
+set_picture_clip (Display *xdisplay,
+ Picture p,
+ int width,
+ int height,
+ int clipX1,
+ int clipY1,
+ int clipX2,
+ int clipY2)
+{
+ XRectangle clip[4];
+
+ clip[0].x = 0;
+ clip[0].y = 0;
+ clip[0].width = width;
+ clip[0].height = clipY1;
+
+ clip[1].x = 0;
+ clip[1].y = clipY2;
+ clip[1].width = width;
+ clip[1].height = height - clipY2;
+
+ clip[2].x = 0;
+ clip[2].y = clipY1;
+ clip[2].width = clipX1;
+ clip[2].height = clipY2 - clipY1;
+
+ clip[3].x = clipX2;
+ clip[3].y = clipY1;
+ clip[3].width = width - clipX2;
+ clip[3].height = clipY2 - clipY1;
+
+ XRenderSetPictureClipRectangles (xdisplay, p, 0, 0, clip, 4);
+}
+
+static void
+set_no_picture_clip (Display *xdisplay,
+ Picture p)
+{
+ XRectangle clip;
+
+ clip.x = 0;
+ clip.y = 0;
+ clip.width = SHRT_MAX;
+ clip.height = SHRT_MAX;
+
+ XRenderSetPictureClipRectangles (xdisplay, p, 0, 0, &clip, 1);
+}
+
+static XFixed *
+create_gaussian_kernel (double radius,
+ double sigma,
+ double alpha,
+ int *r_size)
+{
+ XFixed *params;
+ double *amp, scale, x_scale, fx, sum;
+ int size, half_size, x, i, n;
+
+ scale = 1.0f / (2.0f * M_PI * sigma * sigma);
+ half_size = alpha + 0.5f;
+
+ if (half_size == 0)
+ half_size = 1;
+
+ size = half_size * 2 + 1;
+ x_scale = 2.0f * radius / size;
+
+ if (size < 3)
+ return NULL;
+
+ n = size;
+
+ amp = malloc (sizeof (double) * n);
+ if (!amp)
+ return NULL;
+
+ n += 2;
+
+ params = malloc (sizeof (XFixed) * n);
+ if (!params)
+ {
+ free (amp);
+ return NULL;
+ }
+
+ i = 0;
+ sum = 0.0f;
+
+ for (x = 0; x < size; x++)
+ {
+ fx = x_scale * (x - half_size);
+
+ amp[i] = scale * exp ((-1.0f * (fx * fx)) / (2.0f * sigma * sigma));
+
+ sum += amp[i];
+
+ i++;
+ }
+
+ /* normalize */
+ if (sum != 0.0)
+ sum = 1.0 / sum;
+
+ params[0] = params[1] = 0;
+
+ for (i = 2; i < n; i++)
+ params[i] = XDoubleToFixed (amp[i - 2] * sum);
+
+ free (amp);
+
+ *r_size = size;
+
+ return params;
+}
+
+#define SIGMA(r) ((r) / 2.0)
+#define ALPHA(r) (r)
+
+decor_shadow_t *
+decor_shadow_create (Display *xdisplay,
+ Screen *screen,
+ int width,
+ int height,
+ int left,
+ int right,
+ int top,
+ int bottom,
+ int solid_left,
+ int solid_right,
+ int solid_top,
+ int solid_bottom,
+ decor_shadow_options_t *opt,
+ decor_context_t *c,
+ decor_draw_func_t draw,
+ void *closure)
+{
+ static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
+ XRenderPictFormat *format;
+ Pixmap pixmap;
+ Picture src, dst, tmp;
+ XFixed opacity, *params;
+ XFilters *filters;
+ char *filter = NULL;
+ int size, n_params = 0;
+ XRenderColor color;
+ int shadow_offset_x;
+ int shadow_offset_y;
+ Pixmap d_pixmap;
+ int d_width;
+ int d_height;
+ Window xroot = screen->root;
+ decor_shadow_t *shadow;
+ int clipX1, clipY1, clipX2, clipY2;
+
+ shadow = malloc (sizeof (decor_shadow_t));
+ if (!shadow)
+ return NULL;
+
+ shadow->ref_count = 1;
+
+ shadow->pixmap = 0;
+ shadow->picture = 0;
+ shadow->width = 0;
+ shadow->height = 0;
+
+ shadow_offset_x = opt->shadow_offset_x;
+ shadow_offset_y = opt->shadow_offset_y;
+
+ /* compute a gaussian convolution kernel */
+ params = create_gaussian_kernel (opt->shadow_radius,
+ SIGMA (opt->shadow_radius),
+ ALPHA (opt->shadow_radius),
+ &size);
+ if (!params)
+ shadow_offset_x = shadow_offset_y = size = 0;
+
+ if (opt->shadow_radius <= 0.0 &&
+ shadow_offset_x == 0 &&
+ shadow_offset_y == 0)
+ size = 0;
+
+ n_params = size + 2;
+ size = size / 2;
+
+ c->extents.left = left;
+ c->extents.right = right;
+ c->extents.top = top;
+ c->extents.bottom = bottom;
+
+ c->left_space = left + size - shadow_offset_x;
+ c->right_space = right + size + shadow_offset_x;
+ c->top_space = top + size - shadow_offset_y;
+ c->bottom_space = bottom + size + shadow_offset_y;
+
+ c->left_space = MAX (left, c->left_space);
+ c->right_space = MAX (right, c->right_space);
+ c->top_space = MAX (top, c->top_space);
+ c->bottom_space = MAX (bottom, c->bottom_space);
+
+ c->left_corner_space = MAX (1, size - solid_left + shadow_offset_x);
+ c->right_corner_space = MAX (1, size - solid_right - shadow_offset_x);
+ c->top_corner_space = MAX (1, size - solid_top + shadow_offset_y);
+ c->bottom_corner_space = MAX (1, size - solid_bottom - shadow_offset_y);
+
+ width = MAX (width, c->left_corner_space + c->right_corner_space);
+ height = MAX (height, c->top_corner_space + c->bottom_corner_space);
+
+ width = MAX (1, width);
+ height = MAX (1, height);
+
+ d_width = c->left_space + width + c->right_space;
+ d_height = c->top_space + height + c->bottom_space;
+
+ /* all pixmaps are ARGB32 */
+ format = XRenderFindStandardFormat (xdisplay, PictStandardARGB32);
+
+ /* no shadow */
+ if (size <= 0)
+ {
+ if (params)
+ free (params);
+
+ return shadow;
+ }
+
+ pixmap = XCreatePixmap (xdisplay, xroot, d_width, d_height, 32);
+ if (!pixmap)
+ {
+ free (params);
+ return shadow;
+ }
+
+ /* query server for convolution filter */
+ filters = XRenderQueryFilters (xdisplay, pixmap);
+ if (filters)
+ {
+ int i;
+
+ for (i = 0; i < filters->nfilter; i++)
+ {
+ if (strcmp (filters->filter[i], FilterConvolution) == 0)
+ {
+ filter = (char *) FilterConvolution;
+ break;
+ }
+ }
+
+ XFree (filters);
+ }
+
+ if (!filter)
+ {
+ XFreePixmap (xdisplay, pixmap);
+ free (params);
+
+ return shadow;
+ }
+
+ /* create pixmap for temporary decorations */
+ d_pixmap = XCreatePixmap (xdisplay, xroot, d_width, d_height, 32);
+ if (!d_pixmap)
+ {
+ XFreePixmap (xdisplay, pixmap);
+ free (params);
+
+ return shadow;
+ }
+
+ src = XRenderCreateSolidFill (xdisplay, &white);
+ dst = XRenderCreatePicture (xdisplay, d_pixmap, format, 0, NULL);
+ tmp = XRenderCreatePicture (xdisplay, pixmap, format, 0, NULL);
+
+ /* draw decoration */
+ (*draw) (xdisplay, d_pixmap, dst, d_width, d_height, c, closure);
+
+ /* first pass */
+ params[0] = (n_params - 2) << 16;
+ params[1] = 1 << 16;
+
+ clipX1 = c->left_space + size;
+ clipY1 = c->top_space + size;
+ clipX2 = d_width - c->right_space - size;
+ clipY2 = d_height - c->bottom_space - size;
+
+ if (clipX1 < clipX2 && clipY1 < clipY2)
+ set_picture_clip (xdisplay, tmp, d_width, d_height,
+ clipX1, clipY1, clipX2, clipY2);
+
+ set_picture_transform (xdisplay, dst, shadow_offset_x, 0);
+ XRenderSetPictureFilter (xdisplay, dst, filter, params, n_params);
+ XRenderComposite (xdisplay,
+ PictOpSrc,
+ src,
+ dst,
+ tmp,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ d_width, d_height);
+
+ set_no_picture_clip (xdisplay, tmp);
+
+ XRenderFreePicture (xdisplay, src);
+
+ /* second pass */
+ params[0] = 1 << 16;
+ params[1] = (n_params - 2) << 16;
+
+ opacity = XDoubleToFixed (opt->shadow_opacity);
+ if (opacity < (1 << 16))
+ {
+ /* apply opacity as shadow color if less than 1.0 */
+ color.red = (opt->shadow_color[0] * opacity) >> 16;
+ color.green = (opt->shadow_color[1] * opacity) >> 16;
+ color.blue = (opt->shadow_color[2] * opacity) >> 16;
+ color.alpha = opacity;
+
+ opacity = 1 << 16;
+ }
+ else
+ {
+ /* shadow color */
+ color.red = opt->shadow_color[0];
+ color.green = opt->shadow_color[1];
+ color.blue = opt->shadow_color[2];
+ color.alpha = 0xffff;
+ }
+
+ src = XRenderCreateSolidFill (xdisplay, &color);
+
+ clipX1 = c->left_space;
+ clipY1 = c->top_space;
+ clipX2 = d_width - c->right_space;
+ clipY2 = d_height - c->bottom_space;
+
+ if (clipX1 < clipX2 && clipY1 < clipY2)
+ set_picture_clip (xdisplay, dst, d_width, d_height,
+ clipX1, clipY1, clipX2, clipY2);
+
+ set_picture_transform (xdisplay, tmp, 0, shadow_offset_y);
+ XRenderSetPictureFilter (xdisplay, tmp, filter, params, n_params);
+ XRenderComposite (xdisplay,
+ PictOpSrc,
+ src,
+ tmp,
+ dst,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ d_width, d_height);
+
+ set_no_picture_clip (xdisplay, dst);
+
+ XRenderFreePicture (xdisplay, src);
+
+ if (opacity != (1 << 16))
+ {
+ XFixed p[3];
+
+ p[0] = 1 << 16;
+ p[1] = 1 << 16;
+ p[2] = opacity;
+
+ if (clipX1 < clipX2 && clipY1 < clipY2)
+ set_picture_clip (xdisplay, tmp, d_width, d_height,
+ clipX1, clipY1, clipX2, clipY2);
+
+ /* apply opacity */
+ set_picture_transform (xdisplay, dst, 0, 0);
+ XRenderSetPictureFilter (xdisplay, dst, filter, p, 3);
+ XRenderComposite (xdisplay,
+ PictOpSrc,
+ dst,
+ None,
+ tmp,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ d_width, d_height);
+
+ XFreePixmap (xdisplay, d_pixmap);
+ shadow->pixmap = pixmap;
+ }
+ else
+ {
+ XFreePixmap (xdisplay, pixmap);
+ shadow->pixmap = d_pixmap;
+ }
+
+ XRenderFreePicture (xdisplay, tmp);
+ XRenderFreePicture (xdisplay, dst);
+
+ shadow->picture = XRenderCreatePicture (xdisplay, shadow->pixmap,
+ format, 0, NULL);
+
+ shadow->width = d_width;
+ shadow->height = d_height;
+
+ free (params);
+
+ return shadow;
+}
+
+void
+decor_shadow_destroy (Display *xdisplay,
+ decor_shadow_t *shadow)
+{
+ shadow->ref_count--;
+ if (shadow->ref_count)
+ return;
+
+ if (shadow->picture)
+ XRenderFreePicture (xdisplay, shadow->picture);
+
+ if (shadow->pixmap)
+ XFreePixmap (xdisplay, shadow->pixmap);
+
+ free (shadow);
+}
+
+void
+decor_shadow_reference (decor_shadow_t *shadow)
+{
+ shadow->ref_count++;
+}
+
+void
+decor_draw_simple (Display *xdisplay,
+ Pixmap pixmap,
+ Picture picture,
+ int width,
+ int height,
+ decor_context_t *c,
+ void *closure)
+{
+ static XRenderColor clear = { 0x0000, 0x0000, 0x0000, 0x0000 };
+ static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
+
+ XRenderFillRectangle (xdisplay, PictOpSrc, picture, &clear,
+ 0,
+ 0,
+ width,
+ height);
+ XRenderFillRectangle (xdisplay, PictOpSrc, picture, &white,
+ c->left_space - c->extents.left,
+ c->top_space - c->extents.top,
+ width - c->left_space - c->right_space +
+ c->extents.left + c->extents.right,
+ height - c->top_space - c->bottom_space +
+ c->extents.top + c->extents.bottom);
+}
+
+void
+decor_get_default_layout (decor_context_t *c,
+ int width,
+ int height,
+ decor_layout_t *layout)
+{
+ width = MAX (width, c->left_corner_space + c->right_corner_space);
+ height = MAX (height, c->top_corner_space + c->bottom_corner_space);
+
+ width += c->left_space + c->right_space;
+
+ layout->top.x1 = 0;
+ layout->top.y1 = 0;
+ layout->top.x2 = width;
+ layout->top.y2 = c->top_space;
+ layout->top.pad = 0;
+
+ layout->left.x1 = 0;
+ layout->left.y1 = c->top_space;
+ layout->left.x2 = c->left_space;
+ layout->left.y2 = c->top_space + height;
+ layout->left.pad = 0;
+
+ layout->right.x1 = width - c->right_space;
+ layout->right.y1 = c->top_space;
+ layout->right.x2 = width;
+ layout->right.y2 = c->top_space + height;
+ layout->right.pad = 0;
+
+ layout->bottom.x1 = 0;
+ layout->bottom.y1 = height + c->top_space;
+ layout->bottom.x2 = width;
+ layout->bottom.y2 = height + c->top_space + c->bottom_space;
+ layout->bottom.pad = 0;
+
+ layout->width = width;
+ layout->height = height + c->top_space + c->bottom_space;
+
+ layout->rotation = 0;
+}
+
+void
+decor_get_best_layout (decor_context_t *c,
+ int width,
+ int height,
+ decor_layout_t *layout)
+{
+ int y;
+
+ /* use default layout when no left and right extents */
+ if (c->extents.left == 0 && c->extents.right == 0)
+ {
+ decor_get_default_layout (c, width, 1, layout);
+ return;
+ }
+
+ width = MAX (width, c->left_corner_space + c->right_corner_space);
+ height = MAX (height, c->top_corner_space + c->bottom_corner_space);
+
+ width += c->left_space + c->right_space;
+
+ if (width >= (height + 2))
+ {
+ int max;
+
+ layout->width = width;
+
+ layout->top.x1 = 0;
+ layout->top.y1 = 0;
+ layout->top.x2 = width;
+ layout->top.y2 = c->top_space;
+
+ y = c->top_space;
+
+ max = MAX (c->left_space, c->right_space);
+ if (max < height)
+ {
+ layout->rotation = 1;
+
+ y += 2;
+
+ layout->top.pad = PAD_BOTTOM;
+ layout->bottom.pad = PAD_TOP;
+ layout->left.pad = PAD_TOP | PAD_BOTTOM | PAD_LEFT | PAD_RIGHT;
+ layout->right.pad = PAD_TOP | PAD_BOTTOM | PAD_LEFT | PAD_RIGHT;
+
+ layout->left.x1 = 1;
+ layout->left.y1 = y;
+ layout->left.x2 = 1 + height;
+ layout->left.y2 = y + c->left_space;
+
+ if ((height + 2) <= (width / 2))
+ {
+ layout->right.x1 = height + 3;
+ layout->right.y1 = y;
+ layout->right.x2 = height + 3 + height;
+ layout->right.y2 = y + c->right_space;
+
+ y += max + 2;
+ }
+ else
+ {
+ y += c->left_space + 2;
+
+ layout->right.x1 = 1;
+ layout->right.y1 = y;
+ layout->right.x2 = 1 + height;
+ layout->right.y2 = y + c->right_space;
+
+ y += c->right_space + 2;
+ }
+ }
+ else
+ {
+ layout->top.pad = 0;
+ layout->bottom.pad = 0;
+ layout->left.pad = 0;
+ layout->right.pad = 0;
+
+ layout->left.x1 = 0;
+ layout->left.y1 = y;
+ layout->left.x2 = c->left_space;
+ layout->left.y2 = y + height;
+
+ layout->right.x1 = width - c->right_space;
+ layout->right.y1 = y;
+ layout->right.x2 = width;
+ layout->right.y2 = y + height;
+
+ y += height;
+ }
+
+ layout->bottom.x1 = 0;
+ layout->bottom.y1 = y;
+ layout->bottom.x2 = width;
+ layout->bottom.y2 = y + c->bottom_space;
+
+ y += c->bottom_space;
+ }
+ else
+ {
+ layout->rotation = 1;
+
+ layout->left.pad = PAD_TOP | PAD_BOTTOM | PAD_LEFT | PAD_RIGHT;
+ layout->right.pad = PAD_TOP | PAD_BOTTOM | PAD_LEFT | PAD_RIGHT;
+
+ layout->top.x1 = 0;
+ layout->top.y1 = 0;
+ layout->top.x2 = width;
+ layout->top.y2 = c->top_space;
+
+ if (((width * 2) + 3) <= (height + 2))
+ {
+ layout->width = height + 2;
+
+ layout->top.pad = PAD_BOTTOM | PAD_RIGHT;
+ layout->bottom.pad = PAD_TOP | PAD_BOTTOM | PAD_RIGHT | PAD_LEFT;
+
+ layout->bottom.x1 = width + 2;
+ layout->bottom.y1 = 1;
+ layout->bottom.x2 = width + 2 + width;
+ layout->bottom.y2 = 1 + c->bottom_space;
+
+ y = MAX (c->top_space, 1 + c->bottom_space) + 2;
+
+ layout->left.x1 = 1;
+ layout->left.y1 = y;
+ layout->left.x2 = 1 + height;
+ layout->left.y2 = y + c->left_space;
+
+ y += c->left_space + 2;
+
+ layout->right.x1 = 1;
+ layout->right.y1 = y;
+ layout->right.x2 = 1 + height;
+ layout->right.y2 = y + c->right_space;
+
+ y += c->right_space;
+ }
+ else
+ {
+ layout->width = height + 2;
+
+ layout->top.pad = PAD_BOTTOM | PAD_RIGHT;
+ layout->bottom.pad = PAD_TOP | PAD_RIGHT;
+
+ y = c->top_space + 2;
+
+ layout->left.x1 = 1;
+ layout->left.y1 = y;
+ layout->left.x2 = 1 + height;
+ layout->left.y2 = y + c->left_space;
+
+ y += c->left_space + 2;
+
+ layout->right.x1 = 1;
+ layout->right.y1 = y;
+ layout->right.x2 = 1 + height;
+ layout->right.y2 = y + c->right_space;
+
+ y += c->right_space + 2;
+
+ layout->bottom.x1 = 0;
+ layout->bottom.y1 = y;
+ layout->bottom.x2 = width;
+ layout->bottom.y2 = y + c->bottom_space;
+
+ y += c->bottom_space;
+ }
+ }
+
+ layout->height = y;
+}
+
+static XTransform xident = {
+ {
+ { 1 << 16, 0, 0 },
+ { 0, 1 << 16, 0 },
+ { 0, 0, 1 << 16 },
+ }
+};
+
+void
+decor_fill_picture_extents_with_shadow (Display *xdisplay,
+ decor_shadow_t *shadow,
+ decor_context_t *context,
+ Picture picture,
+ decor_layout_t *layout)
+{
+ int w, h, x2, y2, left, right, top, bottom, width, height;
+
+ if (!shadow->picture)
+ return;
+
+ width = layout->top.x2 - layout->top.x1;
+ if (layout->rotation)
+ height = layout->left.x2 - layout->left.x1;
+ else
+ height = layout->left.y2 - layout->left.y1;
+
+ height += context->top_space + context->bottom_space;
+
+ left = context->left_space + context->left_corner_space;
+ right = context->right_space + context->right_corner_space;
+ top = context->top_space + context->top_corner_space;
+ bottom = context->bottom_space + context->bottom_corner_space;
+
+ if (width - left - right < 0)
+ {
+ left = width / 2;
+ right = width - left;
+ }
+
+ if (height - top - bottom < 0)
+ {
+ top = height / 2;
+ bottom = height - top;
+ }
+
+ w = width - left - right;
+ h = height - top - bottom;
+
+ x2 = width - right;
+ y2 = height - bottom;
+
+ /* top left */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ 0, 0,
+ 0, 0,
+ layout->top.x1, layout->top.y1,
+ left, context->top_space);
+
+ /* top right */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ shadow->width - right, 0,
+ 0, 0,
+ layout->top.x2 - right, layout->top.y1,
+ right, context->top_space);
+
+ /* bottom left */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ 0, shadow->height - context->bottom_space,
+ 0, 0,
+ layout->bottom.x1, layout->bottom.y1,
+ left, context->bottom_space);
+
+ /* bottom right */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ shadow->width - right,
+ shadow->height - context->bottom_space,
+ 0, 0,
+ layout->bottom.x2 - right, layout->bottom.y1,
+ right, context->bottom_space);
+
+ if (w > 0)
+ {
+ int sw = shadow->width - left - right;
+ int sx = left;
+
+ if (sw != w)
+ {
+ XTransform t = {
+ {
+ { (sw << 16) / w, 0, left << 16 },
+ { 0, 1 << 16, 0 },
+ { 0, 0, 1 << 16 },
+ }
+ };
+
+ sx = 0;
+
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &t);
+ }
+
+ /* top */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ sx, 0,
+ 0, 0,
+ layout->top.x1 + left, layout->top.y1,
+ w, context->top_space);
+
+ /* bottom */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ sx, shadow->height - context->bottom_space,
+ 0, 0,
+ layout->bottom.x1 + left, layout->bottom.y1,
+ w, context->bottom_space);
+
+ if (sw != w)
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &xident);
+ }
+
+ if (layout->rotation)
+ {
+ XTransform t = {
+ {
+ { 0, 1 << 16, 0 },
+ { 1 << 16, 0, 0 },
+ { 0, 0, 1 << 16 }
+ }
+ };
+
+ t.matrix[1][2] = context->top_space << 16;
+
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &t);
+
+ /* left top */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ 0, 0,
+ 0, 0,
+ layout->left.x1,
+ layout->left.y1,
+ top - context->top_space, context->left_space);
+
+ t.matrix[0][2] = (shadow->width - context->right_space) << 16;
+
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &t);
+
+ /* right top */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ 0, 0,
+ 0, 0,
+ layout->right.x1,
+ layout->right.y1,
+ top - context->top_space, context->right_space);
+
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &xident);
+ }
+ else
+ {
+ /* left top */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ 0, context->top_space,
+ 0, 0,
+ layout->left.x1, layout->left.y1,
+ context->left_space, top - context->top_space);
+
+ /* right top */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ shadow->width - context->right_space,
+ context->top_space,
+ 0, 0,
+ layout->right.x1, layout->right.y1,
+ context->right_space, top - context->top_space);
+ }
+
+ if (layout->rotation)
+ {
+ XTransform t = {
+ {
+ { 0, 1 << 16, 0 },
+ { 1 << 16, 0, 0 },
+ { 0, 0, 1 << 16 }
+ }
+ };
+
+ t.matrix[1][2] = (shadow->height - bottom) << 16;
+
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &t);
+
+ /* left bottom */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ 0, 0,
+ 0, 0,
+ layout->left.x2 - (bottom - context->bottom_space),
+ layout->left.y1,
+ bottom - context->bottom_space, context->left_space);
+
+ t.matrix[0][2] = (shadow->width - context->right_space) << 16;
+
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &t);
+
+ /* right bottom */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ 0, 0,
+ 0, 0,
+ layout->right.x2 - (bottom - context->bottom_space),
+ layout->right.y1,
+ bottom - context->bottom_space, context->right_space);
+
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &xident);
+ }
+ else
+ {
+ /* left bottom */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ 0, shadow->height - bottom,
+ 0, 0,
+ layout->left.x1,
+ layout->left.y2 - (bottom - context->bottom_space),
+ context->left_space, bottom - context->bottom_space);
+
+ /* right bottom */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ shadow->width - context->right_space,
+ shadow->height - bottom,
+ 0, 0,
+ layout->right.x1,
+ layout->right.y2 - (bottom - context->bottom_space),
+ context->right_space, bottom - context->bottom_space);
+ }
+
+ if (h > 0)
+ {
+ int sh = shadow->height - top - bottom;
+
+ if (layout->rotation)
+ {
+ XTransform t = {
+ {
+ { 0, 1 << 16, 0 },
+ { (sh << 16) / h, 0, 0 },
+ { 0, 0, 1 << 16 }
+ }
+ };
+
+ t.matrix[1][2] = top << 16;
+
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &t);
+
+ /* left */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ 0, 0,
+ 0, 0,
+ layout->left.x1 + (top - context->top_space),
+ layout->left.y1,
+ h, context->left_space);
+
+ t.matrix[0][2] = (shadow->width - context->right_space) << 16;
+
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &t);
+
+ /* right */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ 0, 0,
+ 0, 0,
+ layout->right.x1 + (top - context->top_space),
+ layout->right.y1,
+ h, context->right_space);
+
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &xident);
+
+ }
+ else
+ {
+ int sy = top;
+
+ if (sh != h)
+ {
+ XTransform t = {
+ {
+ { 1 << 16, 0, 0 },
+ { 0, (sh << 16) / h, top << 16 },
+ { 0, 0, 1 << 16 },
+ }
+ };
+
+ sy = 0;
+
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &t);
+ }
+
+ /* left */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ 0, sy,
+ 0, 0,
+ layout->left.x1,
+ layout->left.y1 + (top - context->top_space),
+ context->left_space, h);
+
+ /* right */
+ XRenderComposite (xdisplay, PictOpSrc, shadow->picture, 0, picture,
+ shadow->width - context->right_space, sy,
+ 0, 0,
+ layout->right.x2 - context->right_space,
+ layout->right.y1 + (top - context->top_space),
+ context->right_space, h);
+
+ if (sh != h)
+ XRenderSetPictureTransform (xdisplay, shadow->picture, &xident);
+ }
+ }
+}
+
+static void
+_decor_pad_border_picture (Display *xdisplay,
+ Picture dst,
+ decor_box_t *box)
+{
+ int x1, y1, x2, y2;
+
+ x1 = box->x1;
+ y1 = box->y1;
+ x2 = box->x2;
+ y2 = box->y2;
+
+ if (box->pad & PAD_TOP)
+ {
+ XRenderComposite (xdisplay, PictOpSrc, dst, None, dst,
+ x1, y1,
+ 0, 0,
+ x1, y1 - 1,
+ x2 - x1, 1);
+
+ y1--;
+ }
+
+ if (box->pad & PAD_BOTTOM)
+ {
+ XRenderComposite (xdisplay, PictOpSrc, dst, None, dst,
+ x1, y2 - 1,
+ 0, 0,
+ x1, y2,
+ x2 - x1, 1);
+
+ y2++;
+ }
+
+ if (box->pad & PAD_LEFT)
+ {
+ XRenderComposite (xdisplay, PictOpSrc, dst, None, dst,
+ x1, y1,
+ 0, 0,
+ x1 - 1, y1,
+ 1, y2 - y1);
+ }
+
+ if (box->pad & PAD_RIGHT)
+ {
+ XRenderComposite (xdisplay, PictOpSrc, dst, None, dst,
+ x2 - 1, y1,
+ 0, 0,
+ x2, y1,
+ 1, y2 - y1);
+ }
+}
+
+#ifndef HAVE_XRENDER_0_9_3
+/* XRenderCreateLinearGradient and XRenderCreateRadialGradient used to be
+ * broken. Flushing Xlib's output buffer before calling one of these
+ * functions will avoid this specific issue.
+ */
+static Picture
+XRenderCreateLinearGradient_wrapper (Display *xdisplay,
+ const XLinearGradient *gradient,
+ const XFixed *stops,
+ const XRenderColor *colors,
+ int nStops)
+{
+ XFlush (xdisplay);
+
+ return XRenderCreateLinearGradient (xdisplay, gradient,
+ stops, colors, nStops);
+}
+
+static Picture
+XRenderCreateRadialGradient_wrapper (Display *xdisplay,
+ const XRadialGradient *gradient,
+ const XFixed *stops,
+ const XRenderColor *colors,
+ int nStops)
+{
+ XFlush (xdisplay);
+
+ return XRenderCreateRadialGradient (xdisplay, gradient,
+ stops, colors, nStops);
+}
+
+#define XRenderCreateLinearGradient XRenderCreateLinearGradient_wrapper
+#define XRenderCreateRadialGradient XRenderCreateRadialGradient_wrapper
+#endif
+
+static void
+_decor_blend_horz_border_picture (Display *xdisplay,
+ decor_context_t *context,
+ Picture src,
+ int xSrc,
+ int ySrc,
+ Picture dst,
+ decor_layout_t *layout,
+ Region region,
+ unsigned short alpha,
+ int shade_alpha,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ int dy,
+ int direction)
+{
+ XRenderColor color[3] = {
+ { 0xffff, 0xffff, 0xffff, 0xffff },
+ { alpha, alpha, alpha, alpha }
+ };
+ int op = PictOpSrc;
+ int left, right;
+
+ left = context->extents.left;
+ right = context->extents.right;
+
+ XOffsetRegion (region, x1, y1);
+ XRenderSetPictureClipRegion (xdisplay, dst, region);
+ XOffsetRegion (region, -x1, -y1);
+
+ if (alpha != 0xffff)
+ {
+ op = PictOpIn;
+
+ if (shade_alpha)
+ {
+ static XFixed stop[2] = { 0, 1 << 16 };
+ XTransform transform = {
+ {
+ { 1 << 16, 0, 0 },
+ { 0, 1 << 16, 0 },
+ { 0, 0, 1 << 16 }
+ }
+ };
+ Picture grad;
+ XLinearGradient linear;
+ XRadialGradient radial;
+ XRenderPictureAttributes attrib;
+
+ attrib.repeat = RepeatPad;
+
+ radial.inner.x = 0;
+ radial.inner.y = 0;
+ radial.inner.radius = 0;
+ radial.outer.x = 0;
+ radial.outer.y = 0;
+
+ /* left */
+ radial.outer.radius = left << 16;
+
+ grad = XRenderCreateRadialGradient (xdisplay,
+ &radial,
+ stop,
+ color,
+ 2);
+
+ transform.matrix[1][1] = (left << 16) / dy;
+ transform.matrix[0][2] = -left << 16;
+
+ if (direction < 0)
+ transform.matrix[1][2] = -left << 16;
+
+ XRenderSetPictureTransform (xdisplay, grad, &transform);
+ XRenderChangePicture (xdisplay, grad, CPRepeat, &attrib);
+
+ XRenderComposite (xdisplay, PictOpSrc, grad, None, dst,
+ 0, 0,
+ 0, 0,
+ x1, y1,
+ left, dy);
+
+ XRenderFreePicture (xdisplay, grad);
+
+ /* middle */
+ linear.p1.x = 0;
+ linear.p2.x = 0;
+
+ if (direction > 0)
+ {
+ linear.p1.y = 0;
+ linear.p2.y = dy << 16;
+ }
+ else
+ {
+ linear.p1.y = dy << 16;
+ linear.p2.y = 0;
+ }
+
+ grad = XRenderCreateLinearGradient (xdisplay,
+ &linear,
+ stop,
+ color,
+ 2);
+
+ XRenderChangePicture (xdisplay, grad, CPRepeat, &attrib);
+
+ XRenderComposite (xdisplay, PictOpSrc, grad, None, dst,
+ 0, 0,
+ 0, 0,
+ x1 + left, y1,
+ (x2 - x1) - left - right, dy);
+
+ XRenderFreePicture (xdisplay, grad);
+
+ /* right */
+ radial.outer.radius = right << 16;
+
+ grad = XRenderCreateRadialGradient (xdisplay,
+ &radial,
+ stop,
+ color,
+ 2);
+
+ transform.matrix[1][1] = (right << 16) / dy;
+ transform.matrix[0][2] = 1 << 16;
+
+ if (direction < 0)
+ transform.matrix[1][2] = -right << 16;
+
+ XRenderSetPictureTransform (xdisplay, grad, &transform);
+ XRenderChangePicture (xdisplay, grad, CPRepeat, &attrib);
+
+ XRenderComposite (xdisplay, PictOpSrc, grad, None, dst,
+ 0, 0,
+ 0, 0,
+ x2 - right, y1,
+ right, dy);
+
+ XRenderFreePicture (xdisplay, grad);
+ }
+ else
+ {
+ XRenderFillRectangle (xdisplay, PictOpSrc, dst, &color[1],
+ x1, y1, x2 - x1, y2 - y1);
+ }
+ }
+
+ XRenderComposite (xdisplay, op, src, None, dst,
+ xSrc, ySrc,
+ 0, 0,
+ x1, y1,
+ x2 - x1, y2 - y1);
+
+ set_no_picture_clip (xdisplay, dst);
+}
+
+void
+decor_blend_top_border_picture (Display *xdisplay,
+ decor_context_t *context,
+ Picture src,
+ int xSrc,
+ int ySrc,
+ Picture dst,
+ decor_layout_t *layout,
+ Region region,
+ unsigned short alpha,
+ int shade_alpha)
+{
+ int left, right, top;
+ int x1, y1, x2, y2;
+
+ left = context->extents.left;
+ right = context->extents.right;
+ top = context->extents.top;
+
+ x1 = layout->top.x1 + context->left_space - left;
+ y1 = layout->top.y1 + context->top_space - top;
+ x2 = layout->top.x2 - context->right_space + right;
+ y2 = layout->top.y2;
+
+ _decor_blend_horz_border_picture (xdisplay,
+ context,
+ src,
+ xSrc,
+ ySrc,
+ dst,
+ layout,
+ region,
+ alpha,
+ shade_alpha,
+ x1,
+ y1,
+ x2,
+ y2,
+ top,
+ -1);
+
+ _decor_pad_border_picture (xdisplay, dst, &layout->top);
+}
+
+void
+decor_blend_bottom_border_picture (Display *xdisplay,
+ decor_context_t *context,
+ Picture src,
+ int xSrc,
+ int ySrc,
+ Picture dst,
+ decor_layout_t *layout,
+ Region region,
+ unsigned short alpha,
+ int shade_alpha)
+{
+ int left, right, bottom;
+ int x1, y1, x2, y2;
+
+ left = context->extents.left;
+ right = context->extents.right;
+ bottom = context->extents.bottom;
+
+ x1 = layout->bottom.x1 + context->left_space - left;
+ y1 = layout->bottom.y1;
+ x2 = layout->bottom.x2 - context->right_space + right;
+ y2 = layout->bottom.y1 + bottom;
+
+ _decor_blend_horz_border_picture (xdisplay,
+ context,
+ src,
+ xSrc,
+ ySrc,
+ dst,
+ layout,
+ region,
+ alpha,
+ shade_alpha,
+ x1,
+ y1,
+ x2,
+ y2,
+ bottom,
+ 1);
+
+ _decor_pad_border_picture (xdisplay, dst, &layout->bottom);
+}
+
+static void
+_decor_blend_vert_border_picture (Display *xdisplay,
+ decor_context_t *context,
+ Picture src,
+ int xSrc,
+ int ySrc,
+ Picture dst,
+ decor_layout_t *layout,
+ Region region,
+ unsigned short alpha,
+ int shade_alpha,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ int direction)
+{
+ XRenderColor color[3] = {
+ { 0xffff, 0xffff, 0xffff, 0xffff },
+ { alpha, alpha, alpha, alpha }
+ };
+ int op = PictOpSrc;
+
+ if (layout->rotation)
+ {
+ Region rotated_region;
+ XRectangle rect;
+ BoxPtr pBox = region->rects;
+ int nBox = region->numRects;
+
+ rotated_region = XCreateRegion ();
+
+ while (nBox--)
+ {
+ rect.x = x1 + pBox->y1;
+ rect.y = y1 + pBox->x1;
+ rect.width = pBox->y2 - pBox->y1;
+ rect.height = pBox->x2 - pBox->x1;
+
+ XUnionRectWithRegion (&rect, rotated_region, rotated_region);
+
+ pBox++;
+ }
+
+ XRenderSetPictureClipRegion (xdisplay, dst, rotated_region);
+ XDestroyRegion (rotated_region);
+ }
+ else
+ {
+ XOffsetRegion (region, x1, y1);
+ XRenderSetPictureClipRegion (xdisplay, dst, region);
+ XOffsetRegion (region, -x1, -y1);
+ }
+
+ if (alpha != 0xffff)
+ {
+ op = PictOpIn;
+
+ if (shade_alpha)
+ {
+ static XFixed stop[2] = { 0, 1 << 16 };
+ Picture grad;
+ XLinearGradient linear;
+ XRenderPictureAttributes attrib;
+
+ attrib.repeat = RepeatPad;
+
+ if (layout->rotation)
+ {
+ linear.p1.x = 0;
+ linear.p2.x = 0;
+
+ if (direction < 0)
+ {
+ linear.p