summaryrefslogtreecommitdiffstats
path: root/kwin/tools
diff options
context:
space:
mode:
Diffstat (limited to 'kwin/tools')
-rw-r--r--kwin/tools/Makefile.am11
-rw-r--r--kwin/tools/decobenchmark/Makefile.am9
-rw-r--r--kwin/tools/decobenchmark/main.cpp138
-rw-r--r--kwin/tools/decobenchmark/main.h51
-rw-r--r--kwin/tools/decobenchmark/preview.cpp412
-rw-r--r--kwin/tools/decobenchmark/preview.h137
-rw-r--r--kwin/tools/test_gravity.cpp99
-rw-r--r--kwin/tools/xreply/Makefile2
-rw-r--r--kwin/tools/xreply/xreply.c197
9 files changed, 1056 insertions, 0 deletions
diff --git a/kwin/tools/Makefile.am b/kwin/tools/Makefile.am
new file mode 100644
index 000000000..da92d969d
--- /dev/null
+++ b/kwin/tools/Makefile.am
@@ -0,0 +1,11 @@
+noinst_PROGRAMS = test_gravity
+
+SUBDIRS = decobenchmark
+
+INCLUDES = $(all_includes)
+
+test_gravity_SOURCES = test_gravity.cpp
+test_gravity_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+test_gravity_LDADD = $(LIB_X11)
+
+METASOURCES = AUTO
diff --git a/kwin/tools/decobenchmark/Makefile.am b/kwin/tools/decobenchmark/Makefile.am
new file mode 100644
index 000000000..306c89971
--- /dev/null
+++ b/kwin/tools/decobenchmark/Makefile.am
@@ -0,0 +1,9 @@
+noinst_PROGRAMS = decobenchmark
+
+INCLUDES = $(all_includes)
+
+decobenchmark_SOURCES = main.cpp preview.cpp
+decobenchmark_LDFLAGS = $(all_libraries)
+decobenchmark_LDADD = ../../lib/libkdecorations.la
+
+METASOURCES = AUTO
diff --git a/kwin/tools/decobenchmark/main.cpp b/kwin/tools/decobenchmark/main.cpp
new file mode 100644
index 000000000..847fef69c
--- /dev/null
+++ b/kwin/tools/decobenchmark/main.cpp
@@ -0,0 +1,138 @@
+/*
+ *
+ * Copyright (c) 2005 Sandro Giessl <[email protected]>
+ * Copyright (c) 2005 Luciano Montanaro <[email protected]>
+ *
+ * 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 <qtimer.h>
+
+#include <kdebug.h>
+#include <kconfig.h>
+#include <kdecoration_plugins_p.h>
+#include <kdecorationfactory.h>
+
+#include <time.h>
+#include <sys/timeb.h>
+#include <iostream>
+
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+
+#include "preview.h"
+#include "main.h"
+
+static KCmdLineOptions options[] =
+{
+ { "+decoration", "Decoration library to use, such as kwin3_plastik.", 0 },
+ { "+tests", "Which test should be executed ('all', 'repaint', 'caption', 'resize', 'recreation')", 0 },
+ { "+repetitions", "Number of test repetitions.", 0 },
+ { 0, 0, 0 }
+};
+
+DecoBenchApplication::DecoBenchApplication(const QString &library, Tests tests, int count) :
+ m_tests(tests),
+ m_count(count)
+{
+ KConfig kwinConfig("kwinrc");
+ kwinConfig.setGroup("Style");
+
+ plugins = new KDecorationPreviewPlugins( &kwinConfig );
+ preview = new KDecorationPreview( plugins, 0 );
+
+ if (plugins->loadPlugin(library) )
+ kdDebug() << "Decoration library " << library << " loaded..." << endl;
+ else
+ kdError() << "Error loading decoration library " << library << "!" << endl;
+
+ if (preview->recreateDecoration() )
+ kdDebug() << "Decoration created..." << endl;
+ else
+ kdError() << "Error creating decoration!" << endl;
+
+ preview->show();
+}
+
+DecoBenchApplication::~DecoBenchApplication()
+{
+ delete preview;
+ delete plugins;
+}
+
+void DecoBenchApplication::executeTest()
+{
+ clock_t stime = clock();
+ timeb astart, aend;
+ ftime(&astart);
+
+ if (m_tests == AllTests || m_tests == RepaintTest)
+ preview->performRepaintTest(m_count);
+ if (m_tests == AllTests || m_tests == CaptionTest)
+ preview->performCaptionTest(m_count);
+ if (m_tests == AllTests || m_tests == ResizeTest)
+ preview->performResizeTest(m_count);
+ if (m_tests == AllTests || m_tests == RecreationTest)
+ preview->performRecreationTest(m_count);
+
+ clock_t etime = clock();
+ ftime(&aend);
+
+ long long time_diff = (aend.time - astart.time)*1000+aend.millitm - astart.millitm;
+ kdDebug() << "Total:" << (float(time_diff)/1000) << endl;
+ quit();
+}
+
+int main(int argc, char** argv)
+{
+ QString style = "keramik";
+ // KApplication app(argc, argv);
+ KAboutData about("decobenchmark", "DecoBenchmark", "0.1", "kwin decoration performance tester...", KAboutData::License_LGPL, "(C) 2005 Sandro Giessl");
+ KCmdLineArgs::init(argc, argv, &about);
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ if (args->count() != 3)
+ KCmdLineArgs::usage("Wrong number of arguments!");
+
+ QString library = QString(args->arg(0) );
+ QString t = QString(args->arg(1) );
+ int count = QString(args->arg(2) ).toInt();
+
+ Tests test;
+ if (t == "all")
+ test = AllTests;
+ else if (t == "repaint")
+ test = RepaintTest;
+ else if (t == "caption")
+ test = CaptionTest;
+ else if (t == "resize")
+ test = ResizeTest;
+ else if (t == "recreation")
+ test = RecreationTest;
+ else
+ KCmdLineArgs::usage("Specify a valid test!");
+
+ DecoBenchApplication app(library, test, count);
+
+ QTimer::singleShot(0, &app, SLOT(executeTest()));
+ app.exec();
+}
+#include "main.moc"
+
+// kate: space-indent off; tab-width 4;
diff --git a/kwin/tools/decobenchmark/main.h b/kwin/tools/decobenchmark/main.h
new file mode 100644
index 000000000..4073238a1
--- /dev/null
+++ b/kwin/tools/decobenchmark/main.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright (c) 2005 Sandro Giessl <[email protected]>
+ * Copyright (c) 2005 Luciano Montanaro <[email protected]>
+ *
+ * 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 BENCH_MAIN_H
+#define BENCH_MAIN_H
+
+enum Tests {
+ AllTests,
+ RepaintTest,
+ CaptionTest,
+ ResizeTest,
+ RecreationTest
+};
+
+class DecoBenchApplication : public KApplication
+{
+ Q_OBJECT
+public:
+ DecoBenchApplication(const QString &library, Tests tests, int count);
+ ~DecoBenchApplication();
+
+public slots:
+ void executeTest();
+
+private:
+ KDecorationPreview *preview;
+ KDecorationPlugins *plugins;
+ Tests m_tests;
+ int m_count;
+};
+
+#endif // BENCH_MAIN_H
+
+// kate: space-indent off; tab-width 4;
diff --git a/kwin/tools/decobenchmark/preview.cpp b/kwin/tools/decobenchmark/preview.cpp
new file mode 100644
index 000000000..35301c513
--- /dev/null
+++ b/kwin/tools/decobenchmark/preview.cpp
@@ -0,0 +1,412 @@
+/*
+ *
+ * Copyright (c) 2003 Lubos Lunak <[email protected]>
+ *
+ * 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 "preview.h"
+
+#include <kdebug.h>
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kglobal.h>
+#include <qlabel.h>
+#include <qstyle.h>
+#include <kiconloader.h>
+
+#include <X11/Xlib.h>
+#include <X11/extensions/shape.h>
+
+#include <kdecorationfactory.h>
+#include <kdecoration_plugins_p.h>
+
+// FRAME the preview doesn't update to reflect the changes done in the kcm
+
+KDecorationPreview::KDecorationPreview( KDecorationPlugins* plugin, QWidget* parent, const char* name )
+ : QWidget( parent, name ),
+ m_plugin(plugin)
+{
+ options = new KDecorationPreviewOptions;
+
+ bridge = new KDecorationPreviewBridge( this, true, "Deco Benchmark" );
+
+ deco = 0;
+
+ setFixedSize( 600, 500 );
+
+ positionPreviews();
+}
+
+KDecorationPreview::~KDecorationPreview()
+{
+ delete deco;
+ delete bridge;
+ delete options;
+}
+
+void KDecorationPreview::performRepaintTest(int n)
+{
+ kdDebug() << "start " << n << " repaints..." << endl;
+ bridge->setCaption("Deco Benchmark");
+ deco->captionChange();
+ positionPreviews(0);
+ for (int i = 0; i < n; ++i) {
+ deco->widget()->repaint();
+ kapp->processEvents();
+ }
+}
+
+void KDecorationPreview::performCaptionTest(int n)
+{
+ kdDebug() << "start " << n << " caption changes..." << endl;
+ QString caption = "Deco Benchmark %1";
+ positionPreviews(0);
+ for (int i = 0; i < n; ++i) {
+ bridge->setCaption(caption.arg(i) );
+ deco->captionChange();
+ deco->widget()->repaint();
+ kapp->processEvents();
+ }
+}
+
+void KDecorationPreview::performResizeTest(int n)
+{
+ kdDebug() << "start " << n << " resizes..." << endl;
+ bridge->setCaption("Deco Benchmark");
+ deco->captionChange();
+ for (int i = 0; i < n; ++i) {
+ positionPreviews(i % 200);
+ kapp->processEvents();
+ }
+}
+
+void KDecorationPreview::performRecreationTest(int n)
+{
+ kdDebug() << "start " << n << " resizes..." << endl;
+ bridge->setCaption("Deco Benchmark");
+ deco->captionChange();
+ positionPreviews(0);
+ for (int i = 0; i < n; ++i) {
+ recreateDecoration();
+ kapp->processEvents();
+ }
+}
+
+bool KDecorationPreview::recreateDecoration()
+{
+ delete deco;
+ deco = m_plugin->createDecoration(bridge);
+ deco->init();
+
+ if (!deco)
+ return false;
+
+ positionPreviews();
+ deco->widget()->show();
+
+ return true;
+}
+
+void KDecorationPreview::positionPreviews(int shrink)
+{
+ if ( !deco )
+ return;
+
+ QSize size = QSize(width()-2*10-shrink, height()-2*10-shrink)/*.expandedTo(deco->minimumSize()*/;
+
+ QRect geometry(QPoint(10, 10), size);
+ deco->widget()->setGeometry(geometry);
+}
+
+void KDecorationPreview::setPreviewMask( const QRegion& reg, int mode )
+{
+ QWidget *widget = deco->widget();
+
+ // FRAME duped from client.cpp
+ if( mode == Unsorted )
+ {
+ XShapeCombineRegion( qt_xdisplay(), widget->winId(), ShapeBounding, 0, 0,
+ reg.handle(), ShapeSet );
+ }
+ else
+ {
+ QMemArray< QRect > rects = reg.rects();
+ XRectangle* xrects = new XRectangle[ rects.count() ];
+ for( unsigned int i = 0;
+ i < rects.count();
+ ++i )
+ {
+ xrects[ i ].x = rects[ i ].x();
+ xrects[ i ].y = rects[ i ].y();
+ xrects[ i ].width = rects[ i ].width();
+ xrects[ i ].height = rects[ i ].height();
+ }
+ XShapeCombineRectangles( qt_xdisplay(), widget->winId(), ShapeBounding, 0, 0,
+ xrects, rects.count(), ShapeSet, mode );
+ delete[] xrects;
+ }
+}
+
+QRect KDecorationPreview::windowGeometry( bool active ) const
+{
+ QWidget *widget = deco->widget();
+ return widget->geometry();
+}
+
+QRegion KDecorationPreview::unobscuredRegion( bool active, const QRegion& r ) const
+{
+ return r;
+}
+
+KDecorationPreviewBridge::KDecorationPreviewBridge( KDecorationPreview* p, bool a, const QString &c )
+ : preview( p ), active( a ), m_caption( c )
+{
+}
+
+void KDecorationPreviewBridge::setCaption(const QString &c)
+{
+ m_caption = c;
+}
+
+QWidget* KDecorationPreviewBridge::initialParentWidget() const
+ {
+ return preview;
+ }
+
+Qt::WFlags KDecorationPreviewBridge::initialWFlags() const
+ {
+ return 0;
+ }
+
+bool KDecorationPreviewBridge::isActive() const
+ {
+ return active;
+ }
+
+bool KDecorationPreviewBridge::isCloseable() const
+ {
+ return true;
+ }
+
+bool KDecorationPreviewBridge::isMaximizable() const
+ {
+ return true;
+ }
+
+KDecoration::MaximizeMode KDecorationPreviewBridge::maximizeMode() const
+ {
+ return KDecoration::MaximizeRestore;
+ }
+
+bool KDecorationPreviewBridge::isMinimizable() const
+ {
+ return true;
+ }
+
+bool KDecorationPreviewBridge::providesContextHelp() const
+ {
+ return true;
+ }
+
+int KDecorationPreviewBridge::desktop() const
+ {
+ return 1;
+ }
+
+bool KDecorationPreviewBridge::isModal() const
+ {
+ return false;
+ }
+
+bool KDecorationPreviewBridge::isShadeable() const
+ {
+ return true;
+ }
+
+bool KDecorationPreviewBridge::isShade() const
+ {
+ return false;
+ }
+
+bool KDecorationPreviewBridge::isSetShade() const
+ {
+ return false;
+ }
+
+bool KDecorationPreviewBridge::keepAbove() const
+ {
+ return false;
+ }
+
+bool KDecorationPreviewBridge::keepBelow() const
+ {
+ return false;
+ }
+
+bool KDecorationPreviewBridge::isMovable() const
+ {
+ return true;
+ }
+
+bool KDecorationPreviewBridge::isResizable() const
+ {
+ return true;
+ }
+
+NET::WindowType KDecorationPreviewBridge::windowType( unsigned long ) const
+ {
+ return NET::Normal;
+ }
+
+QIconSet KDecorationPreviewBridge::icon() const
+ {
+ return SmallIconSet( "xapp" );
+ }
+
+QString KDecorationPreviewBridge::caption() const
+{
+ return m_caption;
+}
+
+void KDecorationPreviewBridge::processMousePressEvent( QMouseEvent* )
+ {
+ }
+
+void KDecorationPreviewBridge::showWindowMenu( const QRect &)
+ {
+ }
+
+void KDecorationPreviewBridge::showWindowMenu( QPoint )
+ {
+ }
+
+void KDecorationPreviewBridge::performWindowOperation( WindowOperation )
+ {
+ }
+
+void KDecorationPreviewBridge::setMask( const QRegion& reg, int mode )
+ {
+ preview->setPreviewMask( reg, mode );
+ }
+
+bool KDecorationPreviewBridge::isPreview() const
+ {
+ return false;
+ }
+
+QRect KDecorationPreviewBridge::geometry() const
+ {
+ return preview->windowGeometry( active );
+ }
+
+QRect KDecorationPreviewBridge::iconGeometry() const
+ {
+ return QRect();
+ }
+
+QRegion KDecorationPreviewBridge::unobscuredRegion( const QRegion& r ) const
+ {
+ return preview->unobscuredRegion( active, r );
+ }
+
+QWidget* KDecorationPreviewBridge::workspaceWidget() const
+ {
+ return preview;
+ }
+
+WId KDecorationPreviewBridge::windowId() const
+ {
+ return 0; // no decorated window
+ }
+
+void KDecorationPreviewBridge::closeWindow()
+ {
+ }
+
+void KDecorationPreviewBridge::maximize( MaximizeMode )
+ {
+ }
+
+void KDecorationPreviewBridge::minimize()
+ {
+ }
+
+void KDecorationPreviewBridge::showContextHelp()
+ {
+ }
+
+void KDecorationPreviewBridge::setDesktop( int )
+ {
+ }
+
+void KDecorationPreviewBridge::titlebarDblClickOperation()
+ {
+ }
+
+void KDecorationPreviewBridge::setShade( bool )
+ {
+ }
+
+void KDecorationPreviewBridge::setKeepAbove( bool )
+ {
+ }
+
+void KDecorationPreviewBridge::setKeepBelow( bool )
+ {
+ }
+
+int KDecorationPreviewBridge::currentDesktop() const
+ {
+ return 1;
+ }
+
+void KDecorationPreviewBridge::helperShowHide( bool )
+ {
+ }
+
+void KDecorationPreviewBridge::grabXServer( bool )
+ {
+ }
+
+KDecorationPreviewOptions::KDecorationPreviewOptions()
+ {
+ d = new KDecorationOptionsPrivate;
+ d->defaultKWinSettings();
+ updateSettings();
+ }
+
+KDecorationPreviewOptions::~KDecorationPreviewOptions()
+ {
+ delete d;
+ }
+
+unsigned long KDecorationPreviewOptions::updateSettings()
+{
+ KConfig cfg( "kwinrc", true );
+ unsigned long changed = 0;
+ changed |= d->updateKWinSettings( &cfg );
+
+ return changed;
+}
+
+bool KDecorationPreviewPlugins::provides( Requirement )
+ {
+ return false;
+ }
+
+// #include "preview.moc"
diff --git a/kwin/tools/decobenchmark/preview.h b/kwin/tools/decobenchmark/preview.h
new file mode 100644
index 000000000..4c82ac0a1
--- /dev/null
+++ b/kwin/tools/decobenchmark/preview.h
@@ -0,0 +1,137 @@
+/*
+ *
+ * Copyright (c) 2003 Lubos Lunak <[email protected]>
+ *
+ * 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 KWINDECORATION_PREVIEW_H
+#define KWINDECORATION_PREVIEW_H
+
+#include <qwidget.h>
+#include <kdecoration_p.h>
+#include <kdecoration_plugins_p.h>
+
+class QLabel;
+
+class KDecorationPreviewBridge;
+class KDecorationPreviewOptions;
+
+class KDecorationPreview
+ : public QWidget
+ {
+ public:
+ KDecorationPreview( KDecorationPlugins* plugin, QWidget* parent = NULL, const char* name = NULL );
+ virtual ~KDecorationPreview();
+
+ void performRepaintTest(int n);
+ void performCaptionTest(int n);
+ void performResizeTest(int n);
+ void performRecreationTest(int n);
+
+ bool recreateDecoration();
+ void setPreviewMask( const QRegion&, int );
+ QRegion unobscuredRegion( bool, const QRegion& ) const;
+ QRect windowGeometry( bool ) const;
+ private:
+ void positionPreviews(int shrink = 0);
+ KDecorationPreviewOptions* options;
+ KDecorationPreviewBridge* bridge;
+ KDecoration* deco;
+ KDecorationPlugins* m_plugin;
+ };
+
+class KDecorationPreviewBridge
+ : public KDecorationBridge
+ {
+ public:
+ KDecorationPreviewBridge( KDecorationPreview* preview, bool active, const QString &caption );
+
+ void setCaption(const QString &caption);
+
+ 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 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 show );
+ virtual void grabXServer( bool grab );
+ private:
+ KDecorationPreview* preview;
+ bool active;
+ QString m_caption;
+ };
+
+class KDecorationPreviewOptions
+ : public KDecorationOptions
+ {
+ public:
+ KDecorationPreviewOptions();
+ virtual ~KDecorationPreviewOptions();
+ virtual unsigned long updateSettings();
+
+ private:
+ };
+
+class KDecorationPreviewPlugins
+ : public KDecorationPlugins
+ {
+ public:
+ KDecorationPreviewPlugins( KConfig* cfg );
+ virtual bool provides( Requirement );
+ };
+
+inline KDecorationPreviewPlugins::KDecorationPreviewPlugins( KConfig* cfg )
+ : KDecorationPlugins( cfg )
+ {
+ }
+
+#endif
diff --git a/kwin/tools/test_gravity.cpp b/kwin/tools/test_gravity.cpp
new file mode 100644
index 000000000..618023b5f
--- /dev/null
+++ b/kwin/tools/test_gravity.cpp
@@ -0,0 +1,99 @@
+// tests for window gravity
+
+#include <iostream>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+using namespace std;
+
+const int gravities[ 10 ] =
+ {
+ NorthWestGravity,
+ NorthGravity,
+ NorthEastGravity,
+ WestGravity,
+ CenterGravity,
+ EastGravity,
+ SouthWestGravity,
+ SouthGravity,
+ SouthEastGravity,
+ StaticGravity
+ };
+
+const char* const gravity_names[ 10 ] =
+ {
+ "NW", "N", "NE", "W", "C", "E", "SW", "S", "SE", "ST"
+ };
+
+Display* dpy = NULL;
+
+int get_gravity( const char* name )
+ {
+ for( int i = 0;
+ i < 10;
+ ++i )
+ if( strcmp( name, gravity_names[ i ] ) == 0 )
+ return gravities[ i ];
+ cerr << "Wrong gravity name" << endl;
+ exit( 1 );
+ }
+
+void test( const char* gravity )
+ {
+ XSetWindowAttributes attrs;
+ XSizeHints hints;
+ hints.flags = USPosition | PWinGravity;
+ hints.win_gravity = get_gravity( gravity );
+ Window w = XCreateWindow( dpy, DefaultRootWindow( dpy ), 100, 100, 200, 100, 0, CopyFromParent, CopyFromParent,
+ CopyFromParent, 0, &attrs );
+ XSetWMNormalHints( dpy, w, &hints );
+ XSelectInput( dpy, w, StructureNotifyMask | ButtonPressMask );
+ XMapWindow( dpy, w );
+ for(;;)
+ {
+ XEvent ev;
+ XNextEvent( dpy, &ev );
+ if( ev.type == ConfigureNotify )
+ {
+ cout << "CONFIGURENOTIFY:" << ev.xany.send_event << ":" << ev.xconfigure.x << ":" << ev.xconfigure.y
+ << ":" << ev.xconfigure.width << ":" << ev.xconfigure.height << endl;
+ Window root, child;
+ int x, x_local, y, y_local;
+ unsigned int width, height, border, depth;
+ XGetGeometry( dpy, w, &root, &x_local, &y_local, &width, &height, &border, &depth );
+ XTranslateCoordinates( dpy, w, root, 0, 0, &x, &y, &child );
+ cout << "GEOMETRY:" << x << ":" << y << ":" << width << ":" << height << ":(" << x_local << ":" << y_local << ")" << endl;
+ }
+ else if( ev.type == ButtonPress )
+ {
+ if( ev.xbutton.button == Button1 ) // move
+ {
+ cout << "MOVE" << endl;
+ XMoveWindow( dpy, w, 100, 100 );
+ }
+ else if( ev.xbutton.button == Button2 ) // resize
+ {
+ cout << "RESIZE" << endl;
+ XResizeWindow( dpy, w, 200, 100 );
+ }
+ else if( ev.xbutton.button == Button3 ) // move and resize
+ {
+ cout << "MOVERESIZE" << endl;
+ XMoveResizeWindow( dpy, w, 100, 100, 200, 100 );
+ }
+ }
+ }
+ }
+
+int main( int argc, char* argv[] )
+ {
+ dpy = XOpenDisplay( NULL );
+ if( argc != 2 )
+ {
+ cerr << "specify gravity" << endl;
+ exit( 1 );
+ }
+ test( argv[ 1 ] );
+ XCloseDisplay( dpy );
+ }
diff --git a/kwin/tools/xreply/Makefile b/kwin/tools/xreply/Makefile
new file mode 100644
index 000000000..af06929d5
--- /dev/null
+++ b/kwin/tools/xreply/Makefile
@@ -0,0 +1,2 @@
+all:
+ gcc -O2 -Wall -shared -fPIC -o libxreply.so xreply.c
diff --git a/kwin/tools/xreply/xreply.c b/kwin/tools/xreply/xreply.c
new file mode 100644
index 000000000..ecdf6ebc3
--- /dev/null
+++ b/kwin/tools/xreply/xreply.c
@@ -0,0 +1,197 @@
+/*
+
+ LD_PRELOAD library that gives statistic on number of roundtrips in an application.
+
+ $XREPLY_BACKTRACE defines whether and how backtraces will be printed for every
+ roundtrip. If not set, only total number of roundtrips is printed after the process
+ exits. If set to a number, backtrace for every roundtrip will be printed, and the
+ backtraces will be as deep as the given number. If set to C<number> (e.g. C10),
+ the backtraces will be "compressed" - every backtrace will be printed only once
+ after the process exits, together with number of times it occured.
+
+*/
+
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <execinfo.h>
+#include <assert.h>
+#include <X11/Xlibint.h>
+
+/* Since these symbols are weak, the apps can provide their own, and therefore
+ e.g. temporarily suspend counting of roundtrips. At least theoretically,
+ I haven't really tried it.
+*/
+__attribute((weak)) long ___xreply_reply_count = 0;
+__attribute((weak)) int ___xreply_reply_enabled = 1;
+
+#define MAX_BACKTRACES 1024
+
+extern long ___xreply_reply_count;
+extern int ___xreply_reply_enabled;
+
+typedef Status (*xreply_ptr_t)(Display*,xReply*,int,Bool);
+
+static xreply_ptr_t xreply_ptr = NULL;
+static int xreply_backtrace_set = 0;
+static int xreply_backtrace_type = 0;
+
+struct xreply_struct
+ {
+ char* key;
+ char* text;
+ int count;
+ };
+static struct xreply_struct backtraces[ MAX_BACKTRACES ];
+static int backtraces_size = 0;
+
+static int xreply_compare( const void* left, const void* right )
+ {
+ int left_count = ((struct xreply_struct*)left)->count;
+ int right_count = ((struct xreply_struct*)right)->count;
+ return right_count - left_count;
+ }
+
+static void xreply_print(void)
+ {
+ char tmp[ 1024 ];
+ int fd;
+ fd = open( "/proc/self/cmdline", O_RDONLY );
+ if( fd >= 0 )
+ {
+ read( fd, tmp, 1024 );
+ tmp[ 1023 ] = '\0';
+ close( fd );
+ }
+ fprintf( stderr, "XREPLY (%d : %s): %ld\n", getpid(), tmp, ___xreply_reply_count );
+ if( xreply_backtrace_type < 0 )
+ {
+ int i;
+ qsort( backtraces, backtraces_size, sizeof( struct xreply_struct ), xreply_compare );
+ for( i = 0;
+ i < backtraces_size;
+ ++i )
+ fprintf( stderr, "%d:%s\n\n", backtraces[ i ].count, backtraces[ i ].text );
+ }
+ }
+
+static void xreply_backtrace()
+ {
+ void* trace[256];
+ int n = backtrace(trace, 256);
+ char** strings = backtrace_symbols (trace, n);
+
+ if( xreply_backtrace_type > 0 )
+ {
+ fprintf( stderr, "%ld [\n", ___xreply_reply_count );
+ if( n > xreply_backtrace_type )
+ n = xreply_backtrace_type;
+ int i;
+ for( i = 0;
+ i < n;
+ ++i )
+ fprintf( stderr, "%d: %s\n", i, strings[ i ] );
+ fprintf( stderr, "]\n" );
+ }
+ else
+ {
+ char stack[ 256 * 20 ];
+ int pos = 0;
+ int i;
+ stack[ 0 ] = '\0';
+ if( n > -xreply_backtrace_type )
+ n = -xreply_backtrace_type;
+ for( i = 0;
+ i < n;
+ ++i )
+ {
+ const char* start = strrchr( strings[ i ], '[' );
+ if( start == NULL )
+ assert( !"No [ in address." );
+ long addr;
+ if( sscanf( start + 1, "0x%lx", &addr ) != 1 )
+ assert( !"Failed to parse address." );
+ if( sizeof( void* ) == 4 )
+ {
+ sprintf( stack + pos, "0x%8lx", addr );
+ pos += 10;
+ }
+ else if( sizeof( void* ) == 8 )
+ {
+ sprintf( stack + pos, "0x%16lx", addr );
+ pos += 18;
+ }
+ else
+ assert( !"Unknown sizeof( void* )." );
+ }
+ for( i = 0;
+ i < backtraces_size;
+ ++i )
+ if( strcmp( backtraces[ i ].key, stack ) == 0 )
+ {
+ ++backtraces[ i ].count;
+ break;
+ }
+ if( i == backtraces_size )
+ {
+ int stack_text_size = 10;
+ char* stack_text;
+ char* stack_text_pos;
+ for( i = 0;
+ i < n;
+ ++i )
+ stack_text_size += strlen( strings[ i ] ) + 5;
+ stack_text = stack_text_pos = malloc( stack_text_size );
+ for( i = 0;
+ i < n;
+ ++i )
+ {
+ stack_text_pos = stpcpy( stack_text_pos, "\n" );
+ stack_text_pos = stpcpy( stack_text_pos, strings[ i ] );
+ }
+ backtraces[ backtraces_size ].key = strdup( stack );
+ backtraces[ backtraces_size ].text = stack_text;
+ backtraces[ backtraces_size ].count = 1;
+ ++backtraces_size;
+ if( backtraces_size >= MAX_BACKTRACES )
+ assert( !"MAX_BACKTRACES reached." );
+ }
+ }
+ free (strings);
+ }
+
+Status
+_XReply (dpy, rep, extra, discard)
+ register Display *dpy;
+ register xReply *rep;
+ int extra; /* number of 32-bit words expected after the reply */
+ Bool discard; /* should I discard data following "extra" words? */
+ {
+ if( ___xreply_reply_enabled )
+ ++___xreply_reply_count;
+ if( xreply_backtrace_set == 0 )
+ {
+ if( getenv( "XREPLY_BACKTRACE" ) != NULL )
+ { // C<number> - compress backtraces, saved as negative value in xreply_backtrace_type
+ if( getenv( "XREPLY_BACKTRACE" )[ 0 ] == 'C' )
+ xreply_backtrace_type = -atoi( getenv( "XREPLY_BACKTRACE" ) + 1 );
+ else // <number> - print the backtrace every time
+ xreply_backtrace_type = atoi( getenv( "XREPLY_BACKTRACE" ));
+ }
+ else
+ xreply_backtrace_type = 0;
+ }
+ if( xreply_backtrace_type != 0 )
+ xreply_backtrace();
+ if( xreply_ptr == NULL )
+ {
+ xreply_ptr = (xreply_ptr_t)dlsym( RTLD_NEXT, "_XReply" );
+ if( xreply_ptr == NULL )
+ assert( !"dlsym() failed." );
+ atexit( xreply_print );
+ }
+ return xreply_ptr( dpy, rep, extra, discard );
+ }