src/gui/kernel/qapplication_x11.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui/kernel/qapplication_x11.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,6103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// ### 4.0: examine Q_EXPORT's below. The respective symbols had all
+// been in use (e.g. in the KDE wm) before the introduction of a version
+// map. One might want to turn some of them into proper public API and
+// provide a proper alternative for others. See also the exports in
+// qapplication_win.cpp, which suggest a unification.
+
+#include "qplatformdefs.h"
+
+#include "qcolormap.h"
+#include "qdesktopwidget.h"
+#include "qapplication.h"
+#include "qapplication_p.h"
+#include "qcursor.h"
+#include "qwidget.h"
+#include "qbitarray.h"
+#include "qpainter.h"
+#include "qfile.h"
+#include "qpixmapcache.h"
+#include "qdatetime.h"
+#include "qtextcodec.h"
+#include "qdatastream.h"
+#include "qbuffer.h"
+#include "qsocketnotifier.h"
+#include "qsessionmanager.h"
+#include "qclipboard.h"
+#include "qwhatsthis.h"
+#include "qsettings.h"
+#include "qstylefactory.h"
+#include "qfileinfo.h"
+#include "qdir.h"
+#include "qhash.h"
+#include "qevent.h"
+#include "qevent_p.h"
+#include "qvarlengtharray.h"
+#include "qdebug.h"
+#include <private/qunicodetables_p.h>
+#include <private/qcrashhandler_p.h>
+#include <private/qcolor_p.h>
+#include <private/qcursor_p.h>
+#include <private/qiconloader_p.h>
+#include <private/gtksymbols_p.h>
+#include "qstyle.h"
+#include "qmetaobject.h"
+#include "qtimer.h"
+#include "qlibrary.h"
+#include <private/qgraphicssystemfactory_p.h>
+#include "qguiplatformplugin_p.h"
+#include "qkde_p.h"
+
+#if !defined (QT_NO_TABLET)
+extern "C" {
+#   define class c_class  //XIproto.h has a name member named 'class' which the c++ compiler doesn't like
+#   include <wacomcfg.h>
+#   undef class
+}
+#endif
+
+//#define ALIEN_DEBUG
+
+#if !defined(QT_NO_GLIB)
+#  include "qguieventdispatcher_glib_p.h"
+#endif
+#include "qeventdispatcher_x11_p.h"
+#include <private/qpaintengine_x11_p.h>
+
+#include <private/qkeymapper_p.h>
+
+// Input method stuff
+#ifndef QT_NO_IM
+#include "qinputcontext.h"
+#include "qinputcontextfactory.h"
+#endif // QT_NO_IM
+
+#ifndef QT_NO_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif // QT_NO_XFIXES
+
+#include "qt_x11_p.h"
+#include "qx11info_x11.h"
+
+#define XK_MISCELLANY
+#include <X11/keysymdef.h>
+#if !defined(QT_NO_XINPUT)
+#include <X11/extensions/XI.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <locale.h>
+
+#include "qwidget_p.h"
+
+#include <private/qbackingstore_p.h>
+
+#ifdef QT_RX71_MULTITOUCH
+#  include <qsocketnotifier.h>
+#  include <linux/input.h>
+#  include <errno.h>
+#endif
+
+#if _POSIX_VERSION+0 < 200112L && !defined(Q_OS_BSD4)
+# define QT_NO_UNSETENV
+#endif
+
+QT_BEGIN_NAMESPACE
+
+//#define X_NOT_BROKEN
+#ifdef X_NOT_BROKEN
+// Some X libraries are built with setlocale #defined to _Xsetlocale,
+// even though library users are then built WITHOUT such a definition.
+// This creates a problem - Qt might setlocale() one value, but then
+// X looks and doesn't see the value Qt set. The solution here is to
+// implement _Xsetlocale just in case X calls it - redirecting it to
+// the real libC version.
+//
+# ifndef setlocale
+extern "C" char *_Xsetlocale(int category, const char *locale);
+char *_Xsetlocale(int category, const char *locale)
+{
+    //qDebug("_Xsetlocale(%d,%s),category,locale");
+    return setlocale(category,locale);
+}
+# endif // setlocale
+#endif // X_NOT_BROKEN
+
+/* Warning: if you modify this string, modify the list of atoms in qt_x11_p.h as well! */
+static const char * x11_atomnames = {
+    // window-manager <-> client protocols
+    "WM_PROTOCOLS\0"
+    "WM_DELETE_WINDOW\0"
+    "WM_TAKE_FOCUS\0"
+    "_NET_WM_PING\0"
+    "_NET_WM_CONTEXT_HELP\0"
+    "_NET_WM_SYNC_REQUEST\0"
+    "_NET_WM_SYNC_REQUEST_COUNTER\0"
+
+    // ICCCM window state
+    "WM_STATE\0"
+    "WM_CHANGE_STATE\0"
+
+    // Session management
+    "WM_CLIENT_LEADER\0"
+    "WM_WINDOW_ROLE\0"
+    "SM_CLIENT_ID\0"
+
+    // Clipboard
+    "CLIPBOARD\0"
+    "INCR\0"
+    "TARGETS\0"
+    "MULTIPLE\0"
+    "TIMESTAMP\0"
+    "SAVE_TARGETS\0"
+    "CLIP_TEMPORARY\0"
+    "_QT_SELECTION\0"
+    "_QT_CLIPBOARD_SENTINEL\0"
+    "_QT_SELECTION_SENTINEL\0"
+    "CLIPBOARD_MANAGER\0"
+
+    "RESOURCE_MANAGER\0"
+
+    "_XSETROOT_ID\0"
+
+    "_QT_SCROLL_DONE\0"
+    "_QT_INPUT_ENCODING\0"
+
+    "_MOTIF_WM_HINTS\0"
+
+    "DTWM_IS_RUNNING\0"
+    "KDE_FULL_SESSION\0"
+    "KWIN_RUNNING\0"
+    "KWM_RUNNING\0"
+    "GNOME_BACKGROUND_PROPERTIES\0"
+    "ENLIGHTENMENT_DESKTOP\0"
+    "_SGI_DESKS_MANAGER\0"
+
+    // EWMH (aka NETWM)
+    "_NET_SUPPORTED\0"
+    "_NET_VIRTUAL_ROOTS\0"
+    "_NET_WORKAREA\0"
+
+    "_NET_MOVERESIZE_WINDOW\0"
+    "_NET_WM_MOVERESIZE\0"
+
+    "_NET_WM_NAME\0"
+    "_NET_WM_ICON_NAME\0"
+    "_NET_WM_ICON\0"
+
+    "_NET_WM_PID\0"
+
+    "_NET_WM_WINDOW_OPACITY\0"
+
+    "_NET_WM_STATE\0"
+    "_NET_WM_STATE_ABOVE\0"
+    "_NET_WM_STATE_BELOW\0"
+    "_NET_WM_STATE_FULLSCREEN\0"
+    "_NET_WM_STATE_MAXIMIZED_HORZ\0"
+    "_NET_WM_STATE_MAXIMIZED_VERT\0"
+    "_NET_WM_STATE_MODAL\0"
+    "_NET_WM_STATE_STAYS_ON_TOP\0"
+    "_NET_WM_STATE_DEMANDS_ATTENTION\0"
+
+    "_NET_WM_USER_TIME\0"
+    "_NET_WM_USER_TIME_WINDOW\0"
+    "_NET_WM_FULL_PLACEMENT\0"
+
+    "_NET_WM_WINDOW_TYPE\0"
+    "_NET_WM_WINDOW_TYPE_DESKTOP\0"
+    "_NET_WM_WINDOW_TYPE_DOCK\0"
+    "_NET_WM_WINDOW_TYPE_TOOLBAR\0"
+    "_NET_WM_WINDOW_TYPE_MENU\0"
+    "_NET_WM_WINDOW_TYPE_UTILITY\0"
+    "_NET_WM_WINDOW_TYPE_SPLASH\0"
+    "_NET_WM_WINDOW_TYPE_DIALOG\0"
+    "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU\0"
+    "_NET_WM_WINDOW_TYPE_POPUP_MENU\0"
+    "_NET_WM_WINDOW_TYPE_TOOLTIP\0"
+    "_NET_WM_WINDOW_TYPE_NOTIFICATION\0"
+    "_NET_WM_WINDOW_TYPE_COMBO\0"
+    "_NET_WM_WINDOW_TYPE_DND\0"
+    "_NET_WM_WINDOW_TYPE_NORMAL\0"
+    "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE\0"
+
+    "_KDE_NET_WM_FRAME_STRUT\0"
+
+    "_NET_STARTUP_INFO\0"
+    "_NET_STARTUP_INFO_BEGIN\0"
+
+    "_NET_SUPPORTING_WM_CHECK\0"
+
+    "_NET_WM_CM_S0\0"
+
+    "_NET_SYSTEM_TRAY_VISUAL\0"
+
+    // Property formats
+    "COMPOUND_TEXT\0"
+    "TEXT\0"
+    "UTF8_STRING\0"
+
+    // xdnd
+    "XdndEnter\0"
+    "XdndPosition\0"
+    "XdndStatus\0"
+    "XdndLeave\0"
+    "XdndDrop\0"
+    "XdndFinished\0"
+    "XdndTypeList\0"
+    "XdndActionList\0"
+
+    "XdndSelection\0"
+
+    "XdndAware\0"
+    "XdndProxy\0"
+
+    "XdndActionCopy\0"
+    "XdndActionLink\0"
+    "XdndActionMove\0"
+    "XdndActionPrivate\0"
+
+    // Motif DND
+    "_MOTIF_DRAG_AND_DROP_MESSAGE\0"
+    "_MOTIF_DRAG_INITIATOR_INFO\0"
+    "_MOTIF_DRAG_RECEIVER_INFO\0"
+    "_MOTIF_DRAG_WINDOW\0"
+    "_MOTIF_DRAG_TARGETS\0"
+
+    "XmTRANSFER_SUCCESS\0"
+    "XmTRANSFER_FAILURE\0"
+
+    // Xkb
+    "_XKB_RULES_NAMES\0"
+
+    // XEMBED
+    "_XEMBED\0"
+    "_XEMBED_INFO\0"
+
+    "Wacom Stylus\0"
+    "Wacom Cursor\0"
+    "Wacom Eraser\0"
+};
+
+Q_GUI_EXPORT QX11Data *qt_x11Data = 0;
+
+/*****************************************************************************
+  Internal variables and functions
+ *****************************************************************************/
+static const char *appName = 0;                        // application name
+static const char *appClass = 0;                        // application class
+static const char *appFont        = 0;                // application font
+static const char *appBGCol        = 0;                // application bg color
+static const char *appFGCol        = 0;                // application fg color
+static const char *appBTNCol        = 0;                // application btn color
+static const char *mwGeometry        = 0;                // main widget geometry
+static const char *mwTitle        = 0;                // main widget title
+char    *qt_ximServer        = 0;                // XIM Server will connect to
+static bool        appSync                = false;        // X11 synchronization
+#if defined(QT_DEBUG)
+static bool        appNoGrab        = false;        // X11 grabbing enabled
+static bool        appDoGrab        = false;        // X11 grabbing override (gdb)
+#endif
+static bool        app_save_rootinfo = false;        // save root info
+static bool        app_do_modal        = false;        // modal mode
+static Window        curWin = 0;                        // current window
+
+
+// function to update the workarea of the screen - in qdesktopwidget_x11.cpp
+extern void qt_desktopwidget_update_workarea();
+
+// Function to change the window manager state (from qwidget_x11.cpp)
+extern void qt_change_net_wm_state(const QWidget *w, bool set, Atom one, Atom two = 0);
+
+// modifier masks for alt, meta, super, hyper, and mode_switch - detected when the application starts
+// and/or keyboard layout changes
+uchar qt_alt_mask = 0;
+uchar qt_meta_mask = 0;
+uchar qt_super_mask = 0;
+uchar qt_hyper_mask = 0;
+uchar qt_mode_switch_mask = 0;
+
+// flags for extensions for special Languages, currently only for RTL languages
+bool         qt_use_rtl_extensions = false;
+
+static Window        mouseActWindow             = 0;        // window where mouse is
+static Qt::MouseButton  mouseButtonPressed   = Qt::NoButton; // last mouse button pressed
+static Qt::MouseButtons mouseButtonState     = Qt::NoButton; // mouse button state
+static Time        mouseButtonPressTime = 0;        // when was a button pressed
+static short        mouseXPos, mouseYPos;                // mouse pres position in act window
+static short        mouseGlobalXPos, mouseGlobalYPos; // global mouse press position
+
+extern QWidgetList *qt_modal_stack;                // stack of modal widgets
+
+// window where mouse buttons have been pressed
+static Window pressed_window = XNone;
+
+// popup control
+static bool replayPopupMouseEvent = false;
+static bool popupGrabOk;
+
+bool qt_sm_blockUserInput = false;                // session management
+
+Q_GUI_EXPORT int qt_xfocusout_grab_counter = 0;
+
+#if !defined (QT_NO_TABLET)
+Q_GLOBAL_STATIC(QTabletDeviceDataList, tablet_devices)
+QTabletDeviceDataList *qt_tablet_devices()
+{
+    return tablet_devices();
+}
+
+extern bool qt_tabletChokeMouse;
+#endif
+
+static bool qt_x11EventFilter(XEvent* ev)
+{
+    long unused;
+    if (qApp->filterEvent(ev, &unused))
+        return true;
+    return qApp->x11EventFilter(ev);
+}
+
+#if !defined(QT_NO_XIM)
+XIMStyle        qt_xim_preferred_style = 0;
+#endif
+int qt_ximComposingKeycode=0;
+QTextCodec * qt_input_mapper = 0;
+
+extern bool qt_check_clipboard_sentinel(); //def in qclipboard_x11.cpp
+extern bool qt_check_selection_sentinel(); //def in qclipboard_x11.cpp
+extern bool qt_xfixes_clipboard_changed(Window clipboardOwner, Time timestamp); //def in qclipboard_x11.cpp
+extern bool qt_xfixes_selection_changed(Window selectionOwner, Time timestamp); //def in qclipboard_x11.cpp
+
+static void        qt_save_rootinfo();
+Q_GUI_EXPORT bool qt_try_modal(QWidget *, XEvent *);
+
+QWidget *qt_button_down = 0; // last widget to be pressed with the mouse
+QPointer<QWidget> qt_last_mouse_receiver = 0;
+static QWidget *qt_popup_down = 0;  // popup that contains the pressed widget
+
+extern bool qt_xdnd_dragging;
+
+// gui or non-gui from qapplication.cpp
+extern bool qt_is_gui_used;
+
+/*!
+    \internal
+    Try to resolve a \a symbol from \a library with the version specified
+    by \a vernum.
+
+    Note that, in the case of the Xfixes library, \a vernum is not the same as
+    \c XFIXES_MAJOR - it is a part of soname and may differ from the Xfixes
+    version.
+*/
+static void* qt_load_library_runtime(const char *library, int vernum,
+                                     int highestVernum, const char *symbol)
+{
+    QList<int> versions;
+    // we try to load in the following order:
+    // explicit version -> the default one -> (from the highest (highestVernum) to the lowest (vernum) )
+    if (vernum != -1)
+        versions << vernum;
+    versions << -1;
+    if (vernum != -1) {
+        for(int i = highestVernum; i > vernum; --i)
+            versions << i;
+    }
+    Q_FOREACH(int version, versions) {
+        QLatin1String libName(library);
+        QLibrary xfixesLib(libName, version);
+        if (xfixesLib.load()) {
+            void *ptr = xfixesLib.resolve(symbol);
+            if (ptr)
+                return ptr;
+        }
+    }
+    return 0;
+}
+
+#ifndef QT_NO_XINPUT
+# ifdef QT_RUNTIME_XINPUT
+#  define XINPUT_LOAD_RUNTIME(vernum, symbol, symbol_type) \
+    (symbol_type)qt_load_library_runtime("libXi", vernum, 6, #symbol);
+#  define XINPUT_LOAD(symbol) \
+    XINPUT_LOAD_RUNTIME(1, symbol, Ptr##symbol)
+# else // not runtime XInput
+#  define XINPUT_LOAD(symbol) symbol
+# endif // QT_RUNTIME_XINPUT
+#else // not using Xinput at all
+# define XINPUT_LOAD(symbol) 0
+#endif // QT_NO_XINPUT
+
+#ifndef QT_NO_XFIXES
+# ifdef QT_RUNTIME_XFIXES
+#  define XFIXES_LOAD_RUNTIME(vernum, symbol, symbol_type) \
+    (symbol_type)qt_load_library_runtime("libXfixes", vernum, 4, #symbol);
+#  define XFIXES_LOAD_V1(symbol) \
+    XFIXES_LOAD_RUNTIME(1, symbol, Ptr##symbol)
+#  define XFIXES_LOAD_V2(symbol) \
+    XFIXES_LOAD_RUNTIME(2, symbol, Ptr##symbol)
+
+# else // not runtime Xfixes
+
+#  if XFIXES_MAJOR >= 2
+#   define XFIXES_LOAD_V1(symbol) symbol
+#   define XFIXES_LOAD_V2(symbol) symbol
+#  elif XFIXES_MAJOR >= 1
+#   define XFIXES_LOAD_V1(symbol) symbol
+#   define XFIXES_LOAD_V2(symbol) 0
+#  else
+#   error Unsupported version of Xfixes
+#  endif
+# endif // QT_RUNTIME_XFIXES
+#else // not using Xfixes at all
+# define XFIXES_LOAD_V1(symbol) 0
+# define XFIXES_LOAD_V2(symbol) 0
+#endif // QT_NO_XFIXES
+
+#ifndef QT_NO_XFIXES
+
+struct qt_xfixes_selection_event_data
+{
+    // which selection to filter out.
+    Atom selection;
+};
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static Bool qt_xfixes_scanner(Display*, XEvent *event, XPointer arg)
+{
+    qt_xfixes_selection_event_data *data =
+        reinterpret_cast<qt_xfixes_selection_event_data*>(arg);
+    if (event->type == X11->xfixes_eventbase + XFixesSelectionNotify) {
+        XFixesSelectionNotifyEvent *xfixes_event = reinterpret_cast<XFixesSelectionNotifyEvent*>(event);
+        if (xfixes_event->selection == data->selection)
+            return true;
+    }
+    return false;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+#endif // QT_NO_XFIXES
+
+class QETWidget : public QWidget                // event translator widget
+{
+public:
+    QWidgetPrivate* d_func() { return QWidget::d_func(); }
+    bool translateMouseEvent(const XEvent *);
+    void translatePaintEvent(const XEvent *);
+    bool translateConfigEvent(const XEvent *);
+    bool translateCloseEvent(const XEvent *);
+    bool translateScrollDoneEvent(const XEvent *);
+    bool translateWheelEvent(int global_x, int global_y, int delta, Qt::MouseButtons buttons,
+                             Qt::KeyboardModifiers modifiers, Qt::Orientation orient);
+#if !defined (QT_NO_TABLET)
+    bool translateXinputEvent(const XEvent*, QTabletDeviceData *tablet);
+#endif
+    bool translatePropertyEvent(const XEvent *);
+
+    void doDeferredMap()
+    {
+        Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+        if (!testAttribute(Qt::WA_Resized)) {
+            adjustSize();
+            setAttribute(Qt::WA_Resized, false);
+        }
+
+        /*
+          workaround for WM's that throw away ConfigureRequests from the following:
+
+          window->hide();
+          window->move(x, y); // could also be resize(), move()+resize(), or setGeometry()
+          window->show();
+        */
+        QRect r = geometry();
+
+        XMoveResizeWindow(X11->display,
+                          internalWinId(),
+                          r.x(),
+                          r.y(),
+                          r.width(),
+                          r.height());
+
+        // static gravity!
+        XSizeHints sh;
+        long unused;
+        XGetWMNormalHints(X11->display, internalWinId(), &sh, &unused);
+        sh.flags |= USPosition | PPosition | USSize | PSize | PWinGravity;
+        sh.x = r.x();
+        sh.y = r.y();
+        sh.width = r.width();
+        sh.height = r.height();
+        sh.win_gravity = StaticGravity;
+        XSetWMNormalHints(X11->display, internalWinId(), &sh);
+
+        setAttribute(Qt::WA_Mapped);
+        if (testAttribute(Qt::WA_DontShowOnScreen))
+            return;
+        d_func()->topData()->waitingForMapNotify = 1;
+        XMapWindow(X11->display, internalWinId());
+    }
+};
+
+
+void QApplicationPrivate::createEventDispatcher()
+{
+    Q_Q(QApplication);
+#if !defined(QT_NO_GLIB)
+    if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
+        eventDispatcher = (q->type() != QApplication::Tty
+                           ? new QGuiEventDispatcherGlib(q)
+                           : new QEventDispatcherGlib(q));
+    else
+#endif
+        eventDispatcher = (q->type() != QApplication::Tty
+                           ? new QEventDispatcherX11(q)
+                           : new QEventDispatcherUNIX(q));
+}
+
+/*****************************************************************************
+  Default X error handlers
+ *****************************************************************************/
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static int (*original_x_errhandler)(Display *dpy, XErrorEvent *);
+static int (*original_xio_errhandler)(Display *dpy);
+
+static int qt_x_errhandler(Display *dpy, XErrorEvent *err)
+{
+    switch (err->error_code) {
+    case BadAtom:
+        if (err->request_code == 20 /* X_GetProperty */
+            && (err->resourceid == XA_RESOURCE_MANAGER
+                || err->resourceid == XA_RGB_DEFAULT_MAP
+                || err->resourceid == ATOM(_NET_SUPPORTED)
+                || err->resourceid == ATOM(_NET_SUPPORTING_WM_CHECK)
+                || err->resourceid == ATOM(KDE_FULL_SESSION)
+                || err->resourceid == ATOM(KWIN_RUNNING)
+                || err->resourceid == ATOM(XdndProxy)
+                || err->resourceid == ATOM(XdndAware))) {
+            // Perhaps we're running under SECURITY reduction? :/
+            return 0;
+        }
+        break;
+
+    case BadWindow:
+        if (err->request_code == 2 /* X_ChangeWindowAttributes */
+            || err->request_code == 38 /* X_QueryPointer */) {
+            for (int i = 0; i < ScreenCount(dpy); ++i) {
+                if (err->resourceid == RootWindow(dpy, i)) {
+                    // Perhaps we're running under SECURITY reduction? :/
+                    return 0;
+                }
+            }
+        }
+        X11->seen_badwindow = true;
+        if (err->request_code == 25 /* X_SendEvent */) {
+            for (int i = 0; i < ScreenCount(dpy); ++i) {
+                if (err->resourceid == RootWindow(dpy, i)) {
+                    // Perhaps we're running under SECURITY reduction? :/
+                    return 0;
+                }
+            }
+            if (X11->xdndHandleBadwindow()) {
+                qDebug("xdndHandleBadwindow returned true");
+                return 0;
+            }
+        }
+        if (X11->ignore_badwindow)
+            return 0;
+        break;
+
+    case BadMatch:
+        if (err->request_code == 42 /* X_SetInputFocus */)
+            return 0;
+        break;
+
+    default:
+#if !defined(QT_NO_XINPUT)
+        if (err->request_code == X11->xinput_major
+            && err->error_code == (X11->xinput_errorbase + XI_BadDevice)
+            && err->minor_code == 3 /* X_OpenDevice */) {
+            return 0;
+        }
+#endif
+        break;
+    }
+
+    char errstr[256];
+    XGetErrorText( dpy, err->error_code, errstr, 256 );
+    char buffer[256];
+    char request_str[256];
+    qsnprintf(buffer, 256, "%d", err->request_code);
+    XGetErrorDatabaseText(dpy, "XRequest", buffer, "", request_str, 256);
+    if (err->request_code < 128) {
+        // X error for a normal protocol request
+        qWarning( "X Error: %s %d\n"
+                  "  Major opcode: %d (%s)\n"
+                  "  Resource id:  0x%lx",
+                  errstr, err->error_code,
+                  err->request_code,
+                  request_str,
+                  err->resourceid );
+    } else {
+        // X error for an extension request
+        const char *extensionName = 0;
+        if (err->request_code == X11->xrender_major)
+            extensionName = "RENDER";
+        else if (err->request_code == X11->xrandr_major)
+            extensionName = "RANDR";
+        else if (err->request_code == X11->xinput_major)
+            extensionName = "XInputExtension";
+        else if (err->request_code == X11->mitshm_major)
+            extensionName = "MIT-SHM";
+
+        char minor_str[256];
+        if (extensionName) {
+            qsnprintf(buffer, 256, "%s.%d", extensionName, err->minor_code);
+            XGetErrorDatabaseText(dpy, "XRequest", buffer, "", minor_str, 256);
+        } else {
+            extensionName = "Uknown extension";
+            qsnprintf(minor_str, 256, "Unknown request");
+        }
+        qWarning( "X Error: %s %d\n"
+                  "  Extension:    %d (%s)\n"
+                  "  Minor opcode: %d (%s)\n"
+                  "  Resource id:  0x%lx",
+                  errstr, err->error_code,
+                  err->request_code,
+                  extensionName,
+                  err->minor_code,
+                  minor_str,
+                  err->resourceid );
+    }
+
+    // ### we really should distinguish between severe, non-severe and
+    // ### application specific errors
+
+    return 0;
+}
+
+
+static int qt_xio_errhandler(Display *)
+{
+    qWarning("%s: Fatal IO error: client killed", appName);
+    QApplicationPrivate::reset_instance_pointer();
+    exit(1);
+    //### give the application a chance for a proper shutdown instead,
+    //### exit(1) doesn't help.
+    return 0;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+#ifndef QT_NO_XSYNC
+struct qt_sync_request_event_data
+{
+    WId window;
+};
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static Bool qt_sync_request_scanner(Display*, XEvent *event, XPointer arg)
+{
+    qt_sync_request_event_data *data =
+        reinterpret_cast<qt_sync_request_event_data*>(arg);
+    if (event->type == ClientMessage &&
+        event->xany.window == data->window &&
+        event->xclient.message_type == ATOM(WM_PROTOCOLS) &&
+        (Atom)event->xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST)) {
+        QWidget *w = QWidget::find(event->xany.window);
+        if (QTLWExtra *tlw = ((QETWidget*)w)->d_func()->maybeTopData()) {
+            const ulong timestamp = (const ulong) event->xclient.data.l[1];
+            if (timestamp > X11->time)
+                X11->time = timestamp;
+            if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
+                tlw->syncRequestTimestamp = timestamp;
+                tlw->newCounterValueLo = event->xclient.data.l[2];
+                tlw->newCounterValueHi = event->xclient.data.l[3];
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+#endif // QT_NO_XSYNC
+
+static void qt_x11_create_intern_atoms()
+{
+    const char *names[QX11Data::NAtoms];
+    const char *ptr = x11_atomnames;
+
+    int i = 0;
+    while (*ptr) {
+        names[i++] = ptr;
+        while (*ptr)
+            ++ptr;
+        ++ptr;
+    }
+
+    Q_ASSERT(i == QX11Data::NPredefinedAtoms);
+
+    QByteArray settings_atom_name("_QT_SETTINGS_TIMESTAMP_");
+    settings_atom_name += XDisplayName(X11->displayName);
+    names[i++] = settings_atom_name;
+
+    Q_ASSERT(i == QX11Data::NAtoms);
+#if defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 6)
+    XInternAtoms(X11->display, (char **)names, i, False, X11->atoms);
+#else
+    for (i = 0; i < QX11Data::NAtoms; ++i)
+        X11->atoms[i] = XInternAtom(X11->display, (char *)names[i], False);
+#endif
+}
+
+Q_GUI_EXPORT void qt_x11_apply_settings_in_all_apps()
+{
+    QByteArray stamp;
+    QDataStream s(&stamp, QIODevice::WriteOnly);
+    s << QDateTime::currentDateTime();
+
+    XChangeProperty(QX11Info::display(), QX11Info::appRootWindow(0),
+                    ATOM(_QT_SETTINGS_TIMESTAMP), ATOM(_QT_SETTINGS_TIMESTAMP), 8,
+                    PropModeReplace, (unsigned char *)stamp.data(), stamp.size());
+}
+
+/*! \internal
+    apply the settings to the application
+*/
+bool QApplicationPrivate::x11_apply_settings()
+{
+    QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+
+    settings.beginGroup(QLatin1String("Qt"));
+
+    /*
+      Qt settings. This is now they are written into the datastream.
+
+      Palette / *                - QPalette
+      font                       - QFont
+      libraryPath                - QStringList
+      style                      - QString
+      doubleClickInterval        - int
+      keyboardInputInterval  - int
+      cursorFlashTime            - int
+      wheelScrollLines           - int
+      colorSpec                  - QString
+      defaultCodec               - QString
+      globalStrut/width          - int
+      globalStrut/height         - int
+      GUIEffects                 - QStringList
+      Font Substitutions/ *      - QStringList
+      Font Substitutions/...     - QStringList
+    */
+
+    QStringList strlist;
+    int i;
+    QPalette pal(Qt::black);
+    int groupCount = 0;
+    strlist = settings.value(QLatin1String("Palette/active")).toStringList();
+    if (!strlist.isEmpty()) {
+        ++groupCount;
+        for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
+            pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
+                         QColor(strlist[i]));
+    }
+    strlist = settings.value(QLatin1String("Palette/inactive")).toStringList();
+    if (!strlist.isEmpty()) {
+        ++groupCount;
+        for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
+            pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
+                         QColor(strlist[i]));
+    }
+    strlist = settings.value(QLatin1String("Palette/disabled")).toStringList();
+    if (!strlist.isEmpty()) {
+        ++groupCount;
+        for (i = 0; i < qMin(strlist.count(), int(QPalette::NColorRoles)); i++)
+            pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
+                         QColor(strlist[i]));
+    }
+
+    // ### Fix properly for 4.6
+    bool usingGtkSettings = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle");
+    if (!usingGtkSettings) {
+        if (groupCount == QPalette::NColorGroups)
+            QApplicationPrivate::setSystemPalette(pal);
+    }
+
+    if (!appFont) {
+        // ### Fix properly for 4.6
+        if (!usingGtkSettings) {
+            QFont font(QApplication::font());
+            QString fontDescription;
+            // Override Qt font if KDE4 settings can be used
+            if (X11->desktopVersion == 4) {
+                QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
+                fontDescription = kdeSettings.value(QLatin1String("font")).toString();
+                if (fontDescription.isEmpty()) {
+                    // KDE stores fonts without quotes
+                    fontDescription = kdeSettings.value(QLatin1String("font")).toStringList().join(QLatin1String(","));
+                }
+            }
+            if (fontDescription.isEmpty())
+                fontDescription = settings.value(QLatin1String("font")).toString();
+            if (!fontDescription .isEmpty()) {
+                font.fromString(fontDescription );
+                QApplicationPrivate::setSystemFont(font);
+            }
+        }
+    }
+
+    // read library (ie. plugin) path list
+    QString libpathkey =
+        QString::fromLatin1("%1.%2/libraryPath")
+        .arg(QT_VERSION >> 16)
+        .arg((QT_VERSION & 0xff00) >> 8);
+    QStringList pathlist = settings.value(libpathkey).toString().split(QLatin1Char(':'));
+    if (! pathlist.isEmpty()) {
+        QStringList::ConstIterator it = pathlist.constBegin();
+        while (it != pathlist.constEnd())
+            QApplication::addLibraryPath(*it++);
+    }
+
+    // read new QStyle
+    QString stylename = settings.value(QLatin1String("style")).toString();
+
+    if (stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull() && X11->use_xrender) {
+        stylename = qt_guiPlatformPlugin()->styleName();
+    }
+
+    static QString currentStyleName = stylename;
+    if (QCoreApplication::startingUp()) {
+        if (!stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull())
+            QApplicationPrivate::styleOverride = stylename;
+    } else {
+        if (currentStyleName != stylename) {
+            currentStyleName = stylename;
+            QApplication::setStyle(stylename);
+        }
+    }
+
+    int num =
+        settings.value(QLatin1String("doubleClickInterval"),
+                       QApplication::doubleClickInterval()).toInt();
+    QApplication::setDoubleClickInterval(num);
+
+    num =
+        settings.value(QLatin1String("cursorFlashTime"),
+                       QApplication::cursorFlashTime()).toInt();
+    QApplication::setCursorFlashTime(num);
+
+    num =
+        settings.value(QLatin1String("wheelScrollLines"),
+                       QApplication::wheelScrollLines()).toInt();
+    QApplication::setWheelScrollLines(num);
+
+    QString colorspec = settings.value(QLatin1String("colorSpec"),
+                                       QVariant(QLatin1String("default"))).toString();
+    if (colorspec == QLatin1String("normal"))
+        QApplication::setColorSpec(QApplication::NormalColor);
+    else if (colorspec == QLatin1String("custom"))
+        QApplication::setColorSpec(QApplication::CustomColor);
+    else if (colorspec == QLatin1String("many"))
+        QApplication::setColorSpec(QApplication::ManyColor);
+    else if (colorspec != QLatin1String("default"))
+        colorspec = QLatin1String("default");
+
+    QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
+                                          QVariant(QLatin1String("none"))).toString();
+    if (defaultcodec != QLatin1String("none")) {
+        QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
+        if (codec)
+            QTextCodec::setCodecForTr(codec);
+    }
+
+    int w = settings.value(QLatin1String("globalStrut/width")).toInt();
+    int h = settings.value(QLatin1String("globalStrut/height")).toInt();
+    QSize strut(w, h);
+    if (strut.isValid())
+        QApplication::setGlobalStrut(strut);
+
+    QStringList effects = settings.value(QLatin1String("GUIEffects")).toStringList();
+    QApplication::setEffectEnabled(Qt::UI_General,
+                                   effects.contains(QLatin1String("general")));
+    QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
+                                   effects.contains(QLatin1String("animatemenu")));
+    QApplication::setEffectEnabled(Qt::UI_FadeMenu,
+                                   effects.contains(QLatin1String("fademenu")));
+    QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
+                                   effects.contains(QLatin1String("animatecombo")));
+    QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
+                                   effects.contains(QLatin1String("animatetooltip")));
+    QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
+                                   effects.contains(QLatin1String("fadetooltip")));
+    QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
+                                   effects.contains(QLatin1String("animatetoolbox")));
+
+    if (!X11->has_fontconfig) {
+        settings.beginGroup(QLatin1String("Font Substitutions"));
+        QStringList fontsubs = settings.childKeys();
+        if (!fontsubs.isEmpty()) {
+            QStringList::Iterator it = fontsubs.begin();
+            for (; it != fontsubs.end(); ++it) {
+                QString fam = *it;
+                QStringList subs = settings.value(fam).toStringList();
+                QFont::insertSubstitutions(fam, subs);
+            }
+        }
+        settings.endGroup();
+    }
+
+    qt_use_rtl_extensions =
+        settings.value(QLatin1String("useRtlExtensions"), false).toBool();
+
+#ifndef QT_NO_XIM
+    if (qt_xim_preferred_style == 0) {
+        QString ximInputStyle = settings.value(QLatin1String("XIMInputStyle"),
+                                               QVariant(QLatin1String("on the spot"))).toString().toLower();
+        if (ximInputStyle == QLatin1String("on the spot"))
+            qt_xim_preferred_style = XIMPreeditCallbacks | XIMStatusNothing;
+        else if (ximInputStyle == QLatin1String("over the spot"))
+            qt_xim_preferred_style = XIMPreeditPosition | XIMStatusNothing;
+        else if (ximInputStyle == QLatin1String("off the spot"))
+            qt_xim_preferred_style = XIMPreeditArea | XIMStatusArea;
+        else if (ximInputStyle == QLatin1String("root"))
+            qt_xim_preferred_style = XIMPreeditNothing | XIMStatusNothing;
+    }
+#endif
+    QStringList inputMethods = QInputContextFactory::keys();
+    if (inputMethods.size() > 2 && inputMethods.contains(QLatin1String("imsw-multi"))) {
+        X11->default_im = QLatin1String("imsw-multi");
+    } else {
+        X11->default_im = settings.value(QLatin1String("DefaultInputMethod"),
+                                         QLatin1String("xim")).toString();
+    }
+
+    settings.endGroup(); // Qt
+
+    return true;
+}
+
+
+/*! \internal
+    Resets the QApplication::instance() pointer to zero
+*/
+void QApplicationPrivate::reset_instance_pointer()
+{ QApplication::self = 0; }
+
+
+// read the _QT_INPUT_ENCODING property and apply the settings to
+// the application
+static void qt_set_input_encoding()
+{
+    Atom type;
+    int format;
+    ulong  nitems, after = 1;
+    unsigned char *data = 0;
+
+    int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+                                ATOM(_QT_INPUT_ENCODING), 0, 1024,
+                                False, XA_STRING, &type, &format, &nitems,
+                                &after, &data);
+    if (e != Success || !nitems || type == XNone) {
+        // Always use the locale codec, since we have no examples of non-local
+        // XIMs, and since we cannot get a sensible answer about the encoding
+        // from the XIM.
+        qt_input_mapper = QTextCodec::codecForLocale();
+
+    } else {
+        if (!qstricmp((char *)data, "locale"))
+            qt_input_mapper = QTextCodec::codecForLocale();
+        else
+            qt_input_mapper = QTextCodec::codecForName((char *)data);
+        // make sure we have an input codec
+        if(!qt_input_mapper)
+            qt_input_mapper = QTextCodec::codecForName("ISO 8859-1");
+    }
+    if (qt_input_mapper && qt_input_mapper->mibEnum() == 11) // 8859-8
+        qt_input_mapper = QTextCodec::codecForName("ISO 8859-8-I");
+    if(data)
+        XFree((char *)data);
+}
+
+// set font, foreground and background from x11 resources. The
+// arguments may override the resource settings.
+static void qt_set_x11_resources(const char* font = 0, const char* fg = 0,
+                                 const char* bg = 0, const char* button = 0)
+{
+
+    QString resFont, resFG, resBG, resButton, resEF, sysFont, selectBackground, selectForeground;
+
+    QApplication::setEffectEnabled(Qt::UI_General, false);
+    QApplication::setEffectEnabled(Qt::UI_AnimateMenu, false);
+    QApplication::setEffectEnabled(Qt::UI_FadeMenu, false);
+    QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false);
+    QApplication::setEffectEnabled(Qt::UI_AnimateTooltip, false);
+    QApplication::setEffectEnabled(Qt::UI_FadeTooltip, false);
+    QApplication::setEffectEnabled(Qt::UI_AnimateToolBox, false);
+
+    bool paletteAlreadySet = false;
+    if (QApplication::desktopSettingsAware()) {
+        // first, read from settings
+        QApplicationPrivate::x11_apply_settings();
+        // the call to QApplication::style() below creates the system
+        // palette, which breaks the logic after the RESOURCE_MANAGER
+        // loop... so I have to save this value to be able to use it later
+        paletteAlreadySet = (QApplicationPrivate::sys_pal != 0);
+
+        // second, parse the RESOURCE_MANAGER property
+        int format;
+        ulong  nitems, after = 1;
+        QString res;
+        long offset = 0;
+        Atom type = XNone;
+
+        while (after > 0) {
+            uchar *data = 0;
+            if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(0),
+                                   ATOM(RESOURCE_MANAGER),
+                                   offset, 8192, False, AnyPropertyType,
+                                   &type, &format, &nitems, &after,
+                                   &data) != Success) {
+                res = QString();
+                break;
+            }
+            if (type == XA_STRING)
+                res += QString::fromLatin1((char*)data);
+            else
+                res += QString::fromLocal8Bit((char*)data);
+            offset += 2048; // offset is in 32bit quantities... 8192/4 == 2048
+            if (data)
+                XFree((char *)data);
+        }
+
+        QString key, value;
+        int l = 0, r;
+        QString apn = QString::fromLocal8Bit(appName);
+        QString apc = QString::fromLocal8Bit(appClass);
+        int apnl = apn.length();
+        int apcl = apc.length();
+        int resl = res.length();
+
+        while (l < resl) {
+            r = res.indexOf(QLatin1Char('\n'), l);
+            if (r < 0)
+                r = resl;
+            while (res.at(l).isSpace())
+                l++;
+            bool mine = false;
+            QChar sc = res.at(l + 1);
+            if (res.at(l) == QLatin1Char('*') &&
+                (sc == QLatin1Char('f') || sc == QLatin1Char('b') || sc == QLatin1Char('g') ||
+                 sc == QLatin1Char('F') || sc == QLatin1Char('B') || sc == QLatin1Char('G') ||
+                 sc == QLatin1Char('s') || sc == QLatin1Char('S')
+                 // capital T only, since we're looking for "Text.selectSomething"
+                 || sc == QLatin1Char('T'))) {
+                // OPTIMIZED, since we only want "*[fbgsT].."
+                QString item = res.mid(l, r - l).simplified();
+                int i = item.indexOf(QLatin1Char(':'));
+                key = item.left(i).trimmed().mid(1).toLower();
+                value = item.right(item.length() - i - 1).trimmed();
+                mine = true;
+            } else if ((apnl && res.at(l) == apn.at(0)) || (appClass && apcl && res.at(l) == apc.at(0))) {
+                if (res.mid(l,apnl) == apn && (res.at(l+apnl) == QLatin1Char('.')
+                                               || res.at(l+apnl) == QLatin1Char('*'))) {
+                    QString item = res.mid(l, r - l).simplified();
+                    int i = item.indexOf(QLatin1Char(':'));
+                    key = item.left(i).trimmed().mid(apnl+1).toLower();
+                    value = item.right(item.length() - i - 1).trimmed();
+                    mine = true;
+                } else if (res.mid(l,apcl) == apc && (res.at(l+apcl) == QLatin1Char('.')
+                                                      || res.at(l+apcl) == QLatin1Char('*'))) {
+                    QString item = res.mid(l, r - l).simplified();
+                    int i = item.indexOf(QLatin1Char(':'));
+                    key = item.left(i).trimmed().mid(apcl+1).toLower();
+                    value = item.right(item.length() - i - 1).trimmed();
+                    mine = true;
+                }
+            }
+
+            if (mine) {
+                if (!font && key == QLatin1String("systemfont"))
+                    sysFont = value.left(value.lastIndexOf(QLatin1Char(':')));
+                if (!font && key == QLatin1String("font"))
+                    resFont = value;
+                else if (!fg && !paletteAlreadySet) {
+                    if (key == QLatin1String("foreground"))
+                        resFG = value;
+                    else if (!bg && key == QLatin1String("background"))
+                        resBG = value;
+                    else if (!bg && !button && key == QLatin1String("button.background"))
+                        resButton = value;
+                    else if (key == QLatin1String("text.selectbackground")) {
+                        selectBackground = value;
+                    } else if (key == QLatin1String("text.selectforeground")) {
+                        selectForeground = value;
+                    }
+                } else if (key == QLatin1String("guieffects"))
+                    resEF = value;
+                // NOTE: if you add more, change the [fbg] stuff above
+            }
+
+            l = r + 1;
+        }
+    }
+    if (!sysFont.isEmpty())
+        resFont = sysFont;
+    if (resFont.isEmpty())
+        resFont = QString::fromLocal8Bit(font);
+    if (resFG.isEmpty())
+        resFG = QString::fromLocal8Bit(fg);
+    if (resBG.isEmpty())
+        resBG = QString::fromLocal8Bit(bg);
+    if (resButton.isEmpty())
+        resButton = QString::fromLocal8Bit(button);
+    if (!resFont.isEmpty()
+        && !X11->has_fontconfig
+        && !QApplicationPrivate::sys_font) {
+        // set application font
+        QFont fnt;
+        fnt.setRawName(resFont);
+
+        // the font we get may actually be an alias for another font,
+        // so we reset the application font to the real font info.
+        if (! fnt.exactMatch()) {
+            QFontInfo fontinfo(fnt);
+            fnt.setFamily(fontinfo.family());
+            fnt.setRawMode(fontinfo.rawMode());
+
+            if (! fnt.rawMode()) {
+                fnt.setItalic(fontinfo.italic());
+                fnt.setWeight(fontinfo.weight());
+                fnt.setUnderline(fontinfo.underline());
+                fnt.setStrikeOut(fontinfo.strikeOut());
+                fnt.setStyleHint(fontinfo.styleHint());
+
+                if (fnt.pointSize() <= 0 && fnt.pixelSize() <= 0) {
+                    // size is all wrong... fix it
+                    qreal pointSize = fontinfo.pixelSize() * 72. / (float) QX11Info::appDpiY();
+                    if (pointSize <= 0)
+                        pointSize = 12;
+                    fnt.setPointSize(qRound(pointSize));
+                }
+            }
+        }
+
+        QApplicationPrivate::setSystemFont(fnt);
+    }
+    // QGtkStyle sets it's own system palette
+    bool gtkStyle = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle");
+    bool kdeColors = (QApplication::desktopSettingsAware() && X11->desktopEnvironment == DE_KDE);
+    if (!gtkStyle && (kdeColors || (button || !resBG.isEmpty() || !resFG.isEmpty()))) {// set app colors
+        bool allowX11ColorNames = QColor::allowX11ColorNames();
+        QColor::setAllowX11ColorNames(true);
+
+        (void) QApplication::style();  // trigger creation of application style and system palettes
+        QColor btn;
+        QColor bg;
+        QColor fg;
+        QColor bfg;
+        QColor wfg;
+        if (!resBG.isEmpty())
+            bg = QColor(resBG);
+        if (!bg.isValid())
+            bg = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::Window);
+
+        if (!resFG.isEmpty())
+            fg = QColor(resFG);
+        if (!fg.isValid())
+            fg = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::WindowText);
+
+        if (!resButton.isEmpty())
+            btn = QColor(resButton);
+        else if (!resBG.isEmpty())
+            btn = bg;
+        if (!btn.isValid())
+            btn = QApplicationPrivate::sys_pal->color(QPalette::Active, QPalette::Button);
+
+        int h,s,v;
+        fg.getHsv(&h,&s,&v);
+        QColor base = Qt::white;
+        bool bright_mode = false;
+        if (v >= 255 - 50) {
+            base = btn.darker(150);
+            bright_mode = true;
+        }
+
+        QPalette pal(fg, btn, btn.lighter(125), btn.darker(130), btn.darker(120), wfg.isValid() ? wfg : fg, Qt::white, base, bg);
+        QColor disabled((fg.red()   + btn.red())  / 2,
+                        (fg.green() + btn.green())/ 2,
+                        (fg.blue()  + btn.blue()) / 2);
+        pal.setColorGroup(QPalette::Disabled, disabled, btn, btn.lighter(125),
+                          btn.darker(130), btn.darker(150), disabled, Qt::white, Qt::white, bg);
+
+        QColor highlight, highlightText;
+        if (!selectBackground.isEmpty() && !selectForeground.isEmpty()) {
+            highlight = QColor(selectBackground);
+            highlightText = QColor(selectForeground);
+        }
+
+        if (highlight.isValid() && highlightText.isValid()) {
+            pal.setColor(QPalette::Highlight, highlight);
+            pal.setColor(QPalette::HighlightedText, highlightText);
+
+            // calculate disabled colors by removing saturation
+            highlight.setHsv(highlight.hue(), 0, highlight.value(), highlight.alpha());
+            highlightText.setHsv(highlightText.hue(), 0, highlightText.value(), highlightText.alpha());
+            pal.setColor(QPalette::Disabled, QPalette::Highlight, highlight);
+            pal.setColor(QPalette::Disabled, QPalette::HighlightedText, highlightText);
+        } else if (bright_mode) {
+            pal.setColor(QPalette::HighlightedText, base);
+            pal.setColor(QPalette::Highlight, Qt::white);
+            pal.setColor(QPalette::Disabled, QPalette::HighlightedText, base);
+            pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::white);
+        } else {
+            pal.setColor(QPalette::HighlightedText, Qt::white);
+            pal.setColor(QPalette::Highlight, Qt::darkBlue);
+            pal.setColor(QPalette::Disabled, QPalette::HighlightedText, Qt::white);
+            pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue);
+        }
+
+        pal = qt_guiPlatformPlugin()->palette().resolve(pal);
+        QApplicationPrivate::setSystemPalette(pal);
+        QColor::setAllowX11ColorNames(allowX11ColorNames);
+    }
+
+    if (!resEF.isEmpty()) {
+        QStringList effects = resEF.split(QLatin1Char(' '));
+        QApplication::setEffectEnabled(Qt::UI_General, effects.contains(QLatin1String("general")));
+        QApplication::setEffectEnabled(Qt::UI_AnimateMenu,
+                                       effects.contains(QLatin1String("animatemenu")));
+        QApplication::setEffectEnabled(Qt::UI_FadeMenu,
+                                       effects.contains(QLatin1String("fademenu")));
+        QApplication::setEffectEnabled(Qt::UI_AnimateCombo,
+                                       effects.contains(QLatin1String("animatecombo")));
+        QApplication::setEffectEnabled(Qt::UI_AnimateTooltip,
+                                       effects.contains(QLatin1String("animatetooltip")));
+        QApplication::setEffectEnabled(Qt::UI_FadeTooltip,
+                                       effects.contains(QLatin1String("fadetooltip")));
+        QApplication::setEffectEnabled(Qt::UI_AnimateToolBox,
+                                       effects.contains(QLatin1String("animatetoolbox")));
+    }
+
+    QIconLoader::instance()->updateSystemTheme();
+}
+
+
+// update the supported array
+static void qt_get_net_supported()
+{
+    Atom type;
+    int format;
+    long offset = 0;
+    unsigned long nitems, after;
+    unsigned char *data = 0;
+
+    int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+                               ATOM(_NET_SUPPORTED), 0, 0,
+                               False, XA_ATOM, &type, &format, &nitems, &after, &data);
+    if (data)
+        XFree(data);
+
+    if (X11->net_supported_list)
+        delete [] X11->net_supported_list;
+    X11->net_supported_list = 0;
+
+    if (e == Success && type == XA_ATOM && format == 32) {
+        QBuffer ts;
+        ts.open(QIODevice::WriteOnly);
+
+        while (after > 0) {
+            XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+                               ATOM(_NET_SUPPORTED), offset, 1024,
+                               False, XA_ATOM, &type, &format, &nitems, &after, &data);
+
+            if (type == XA_ATOM && format == 32) {
+                ts.write(reinterpret_cast<char *>(data), nitems * sizeof(long));
+                offset += nitems;
+            } else
+                after = 0;
+            if (data)
+                XFree(data);
+        }
+
+        // compute nitems
+        QByteArray buffer(ts.buffer());
+        nitems = buffer.size() / sizeof(Atom);
+        X11->net_supported_list = new Atom[nitems + 1];
+        Atom *a = (Atom *) buffer.data();
+        uint i;
+        for (i = 0; i < nitems; i++)
+            X11->net_supported_list[i] = a[i];
+        X11->net_supported_list[nitems] = 0;
+    }
+}
+
+
+bool QX11Data::isSupportedByWM(Atom atom)
+{
+    if (!X11->net_supported_list)
+        return false;
+
+    bool supported = false;
+    int i = 0;
+    while (X11->net_supported_list[i] != 0) {
+        if (X11->net_supported_list[i++] == atom) {
+            supported = true;
+            break;
+        }
+    }
+
+    return supported;
+}
+
+
+// update the virtual roots array
+static void qt_get_net_virtual_roots()
+{
+    if (X11->net_virtual_root_list)
+        delete [] X11->net_virtual_root_list;
+    X11->net_virtual_root_list = 0;
+
+    if (!X11->isSupportedByWM(ATOM(_NET_VIRTUAL_ROOTS)))
+        return;
+
+    Atom type;
+    int format;
+    long offset = 0;
+    unsigned long nitems, after;
+    unsigned char *data;
+
+    int e = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+                               ATOM(_NET_VIRTUAL_ROOTS), 0, 0,
+                               False, XA_ATOM, &type, &format, &nitems, &after, &data);
+    if (data)
+        XFree(data);
+
+    if (e == Success && type == XA_ATOM && format == 32) {
+        QBuffer ts;
+        ts.open(QIODevice::WriteOnly);
+
+        while (after > 0) {
+            XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+                               ATOM(_NET_VIRTUAL_ROOTS), offset, 1024,
+                               False, XA_ATOM, &type, &format, &nitems, &after, &data);
+
+            if (type == XA_ATOM && format == 32) {
+                ts.write(reinterpret_cast<char *>(data), nitems * 4);
+                offset += nitems;
+            } else
+                after = 0;
+            if (data)
+                XFree(data);
+        }
+
+        // compute nitems
+        QByteArray buffer(ts.buffer());
+        nitems = buffer.size() / sizeof(Window);
+        X11->net_virtual_root_list = new Window[nitems + 1];
+        Window *a = (Window *) buffer.data();
+        uint i;
+        for (i = 0; i < nitems; i++)
+            X11->net_virtual_root_list[i] = a[i];
+        X11->net_virtual_root_list[nitems] = 0;
+    }
+}
+
+void qt_net_remove_user_time(QWidget *tlw)
+{
+    Q_ASSERT(tlw);
+    QTLWExtra *extra = tlw->d_func()->maybeTopData();
+    if (extra && extra->userTimeWindow) {
+        Q_ASSERT(tlw->internalWinId());
+        XDeleteProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME_WINDOW));
+        XDestroyWindow(X11->display, extra->userTimeWindow);
+        extra->userTimeWindow = 0;
+    }
+}
+
+void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp)
+{
+    Q_ASSERT(tlw);
+    Q_ASSERT(tlw->isWindow());
+    Q_ASSERT(tlw->testAttribute(Qt::WA_WState_Created));
+    QTLWExtra *extra = tlw->d_func()->topData();
+    WId wid = tlw->internalWinId();
+    const bool isSupportedByWM = X11->isSupportedByWM(ATOM(_NET_WM_USER_TIME_WINDOW));
+    if (extra->userTimeWindow || isSupportedByWM) {
+        if (!extra->userTimeWindow) {
+            extra->userTimeWindow = XCreateSimpleWindow(X11->display,
+                                                        tlw->internalWinId(),
+                                                        -1, -1, 1, 1, 0, 0, 0);
+            wid = extra->userTimeWindow;
+            XChangeProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME_WINDOW),
+                            XA_WINDOW, 32, PropModeReplace,
+                            (unsigned char *)&wid, 1);
+            XDeleteProperty(X11->display, tlw->internalWinId(), ATOM(_NET_WM_USER_TIME));
+        } else if (!isSupportedByWM) {
+            // WM no longer supports it, then we should remove the
+            // _NET_WM_USER_TIME_WINDOW atom.
+            qt_net_remove_user_time(tlw);
+        } else {
+            wid = extra->userTimeWindow;
+        }
+    }
+    XChangeProperty(X11->display, wid, ATOM(_NET_WM_USER_TIME),
+                    XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &timestamp, 1);
+}
+
+static void qt_check_focus_model()
+{
+    Window fw = XNone;
+    int unused;
+    XGetInputFocus(X11->display, &fw, &unused);
+    if (fw == PointerRoot)
+        X11->focus_model = QX11Data::FM_PointerRoot;
+    else
+        X11->focus_model = QX11Data::FM_Other;
+}
+
+#ifndef QT_NO_TABLET
+
+#if !defined (Q_OS_IRIX)
+// from include/Xwacom.h
+#  define XWACOM_PARAM_TOOLID 322
+#  define XWACOM_PARAM_TOOLSERIAL 323
+
+typedef WACOMCONFIG * (*PtrWacomConfigInit) (Display*, WACOMERRORFUNC);
+typedef WACOMDEVICE * (*PtrWacomConfigOpenDevice) (WACOMCONFIG*, const char*);
+typedef int *(*PtrWacomConfigGetRawParam) (WACOMDEVICE*, int, int*, int, unsigned*);
+typedef int (*PtrWacomConfigCloseDevice) (WACOMDEVICE *);
+typedef void (*PtrWacomConfigTerm) (WACOMCONFIG *);
+
+static PtrWacomConfigInit ptrWacomConfigInit = 0;
+static PtrWacomConfigOpenDevice ptrWacomConfigOpenDevice = 0;
+static PtrWacomConfigGetRawParam ptrWacomConfigGetRawParam = 0;
+static PtrWacomConfigCloseDevice ptrWacomConfigCloseDevice = 0;
+static PtrWacomConfigTerm ptrWacomConfigTerm = 0;
+Q_GLOBAL_STATIC(QByteArray, wacomDeviceName)
+#endif
+
+#endif
+
+/*****************************************************************************
+  qt_init() - initializes Qt for X11
+ *****************************************************************************/
+
+#if !defined(QT_NO_FONTCONFIG)
+static void getXDefault(const char *group, const char *key, int *val)
+{
+    char *str = XGetDefault(X11->display, group, key);
+    if (str) {
+        char *end = 0;
+        int v = strtol(str, &end, 0);
+        if (str != end)
+            *val = v;
+    }
+}
+
+static void getXDefault(const char *group, const char *key, double *val)
+{
+    char *str = XGetDefault(X11->display, group, key);
+    if (str) {
+        bool ok;
+        double v = QByteArray(str).toDouble(&ok);
+        if (ok)
+            *val = v;
+    }
+}
+
+static void getXDefault(const char *group, const char *key, bool *val)
+{
+    char *str = XGetDefault(X11->display, group, key);
+    if (str) {
+        char c = str[0];
+        if (isupper((int)c))
+            c = tolower(c);
+        if (c == 't' || c == 'y' || c == '1')
+            *val = true;
+        else if (c == 'f' || c == 'n' || c == '0')
+            *val = false;
+        if (c == 'o') {
+            c = str[1];
+            if (isupper((int)c))
+                c = tolower(c);
+            if (c == 'n')
+                *val = true;
+            if (c == 'f')
+                *val = false;
+        }
+    }
+}
+#endif
+
+// ### This should be static but it isn't because of the friend declaration
+// ### in qpaintdevice.h which then should have a static too but can't have
+// ### it because "storage class specifiers invalid in friend function
+// ### declarations" :-) Ideas anyone?
+void qt_init(QApplicationPrivate *priv, int,
+	     Display *display, Qt::HANDLE visual, Qt::HANDLE colormap)
+{
+    X11 = new QX11Data;
+    X11->display = display;
+    X11->displayName = 0;
+    X11->foreignDisplay = (display != 0);
+    X11->focus_model = -1;
+
+    // RANDR
+    X11->use_xrandr = false;
+    X11->xrandr_major = 0;
+    X11->xrandr_eventbase = 0;
+    X11->xrandr_errorbase = 0;
+
+    // RENDER
+    X11->use_xrender = false;
+    X11->xrender_major = 0;
+    X11->xrender_version = 0;
+
+    // XFIXES
+    X11->use_xfixes = false;
+    X11->xfixes_major = 0;
+    X11->xfixes_eventbase = 0;
+    X11->xfixes_errorbase = 0;
+
+    // XInputExtension
+    X11->use_xinput = false;
+    X11->xinput_major = 0;
+    X11->xinput_eventbase = 0;
+    X11->xinput_errorbase = 0;
+
+    // MIT-SHM
+    X11->use_mitshm = false;
+    X11->mitshm_major = 0;
+
+    X11->sip_serial = 0;
+    X11->net_supported_list = 0;
+    X11->net_virtual_root_list = 0;
+    X11->wm_client_leader = 0;
+    X11->screens = 0;
+    X11->argbVisuals = 0;
+    X11->argbColormaps = 0;
+    X11->screenCount = 0;
+    X11->time = CurrentTime;
+    X11->userTime = CurrentTime;
+    X11->ignore_badwindow = false;
+    X11->seen_badwindow = false;
+
+    X11->motifdnd_active = false;
+
+    X11->default_im = QLatin1String("imsw-multi");
+    priv->inputContext = 0;
+
+    // colormap control
+    X11->visual_class = -1;
+    X11->visual_id = -1;
+    X11->color_count = 0;
+    X11->custom_cmap = false;
+
+    // outside visual/colormap
+    X11->visual = reinterpret_cast<Visual *>(visual);
+    X11->colormap = colormap;
+
+    // Fontconfig
+    X11->has_fontconfig = false;
+#if !defined(QT_NO_FONTCONFIG)
+    if (qgetenv("QT_X11_NO_FONTCONFIG").isNull())
+        X11->has_fontconfig = FcInit();
+    X11->fc_antialias = true;
+#endif
+
+#ifndef QT_NO_XRENDER
+    memset(X11->solid_fills, 0, sizeof(X11->solid_fills));
+    for (int i = 0; i < X11->solid_fill_count; ++i)
+        X11->solid_fills[i].screen = -1;
+    memset(X11->pattern_fills, 0, sizeof(X11->pattern_fills));
+    for (int i = 0; i < X11->pattern_fill_count; ++i)
+        X11->pattern_fills[i].screen = -1;
+#endif
+
+    X11->startupId = 0;
+
+    int argc = priv->argc;
+    char **argv = priv->argv;
+
+    if (X11->display) {
+        // Qt part of other application
+
+        // Set application name and class
+        appName = qstrdup("Qt-subapplication");
+        char *app_class = 0;
+        if (argv) {
+            const char* p = strrchr(argv[0], '/');
+            app_class = qstrdup(p ? p + 1 : argv[0]);
+            if (app_class[0])
+                app_class[0] = toupper(app_class[0]);
+        }
+        appClass = app_class;
+    } else {
+        // Qt controls everything (default)
+
+        // Set application name and class
+        char *app_class = 0;
+        if (argv && argv[0]) {
+            const char *p = strrchr(argv[0], '/');
+            appName = p ? p + 1 : argv[0];
+            app_class = qstrdup(appName);
+            if (app_class[0])
+                app_class[0] = toupper(app_class[0]);
+        }
+        appClass = app_class;
+    }
+
+    // Install default error handlers
+    original_x_errhandler = XSetErrorHandler(qt_x_errhandler);
+    original_xio_errhandler = XSetIOErrorHandler(qt_xio_errhandler);
+
+    // Get command line params
+    int j = argc ? 1 : 0;
+    for (int i=1; i<argc; i++) {
+        if (argv[i] && *argv[i] != '-') {
+            argv[j++] = argv[i];
+            continue;
+        }
+        QByteArray arg(argv[i]);
+        if (arg == "-display") {
+            if (++i < argc && !X11->display)
+                X11->displayName = argv[i];
+        } else if (arg == "-fn" || arg == "-font") {
+            if (++i < argc)
+                appFont = argv[i];
+        } else if (arg == "-bg" || arg == "-background") {
+            if (++i < argc)
+                appBGCol = argv[i];
+        } else if (arg == "-btn" || arg == "-button") {
+            if (++i < argc)
+                appBTNCol = argv[i];
+        } else if (arg == "-fg" || arg == "-foreground") {
+            if (++i < argc)
+                appFGCol = argv[i];
+        } else if (arg == "-name") {
+            if (++i < argc)
+                appName = argv[i];
+        } else if (arg == "-title") {
+            if (++i < argc)
+                mwTitle = argv[i];
+        } else if (arg == "-geometry") {
+            if (++i < argc)
+                mwGeometry = argv[i];
+        } else if (arg == "-im") {
+            if (++i < argc)
+                qt_ximServer = argv[i];
+        } else if (arg == "-ncols") {   // xv and netscape use this name
+            if (++i < argc)
+                X11->color_count = qMax(0,atoi(argv[i]));
+        } else if (arg == "-visual") {  // xv and netscape use this name
+            if (++i < argc && !X11->visual) {
+                QString s = QString::fromLocal8Bit(argv[i]).toLower();
+                if (s == QLatin1String("staticgray"))
+                    X11->visual_class = StaticGray;
+                else if (s == QLatin1String("grayscale"))
+                    X11->visual_class = XGrayScale;
+                else if (s == QLatin1String("staticcolor"))
+                    X11->visual_class = StaticColor;
+                else if (s == QLatin1String("pseudocolor"))
+                    X11->visual_class = PseudoColor;
+                else if (s == QLatin1String("truecolor"))
+                    X11->visual_class = TrueColor;
+                else if (s == QLatin1String("directcolor"))
+                    X11->visual_class = DirectColor;
+                else
+                    X11->visual_id = static_cast<int>(strtol(argv[i], 0, 0));
+            }
+#ifndef QT_NO_XIM
+        } else if (arg == "-inputstyle") {
+            if (++i < argc) {
+                QString s = QString::fromLocal8Bit(argv[i]).toLower();
+                if (s == QLatin1String("onthespot"))
+                    qt_xim_preferred_style = XIMPreeditCallbacks |
+                                             XIMStatusNothing;
+                else if (s == QLatin1String("overthespot"))
+                    qt_xim_preferred_style = XIMPreeditPosition |
+                                             XIMStatusNothing;
+                else if (s == QLatin1String("offthespot"))
+                    qt_xim_preferred_style = XIMPreeditArea |
+                                             XIMStatusArea;
+                else if (s == QLatin1String("root"))
+                    qt_xim_preferred_style = XIMPreeditNothing |
+                                             XIMStatusNothing;
+            }
+#endif
+        } else if (arg == "-cmap") {    // xv uses this name
+            if (!X11->colormap)
+                X11->custom_cmap = true;
+        }
+        else if (arg == "-sync")
+            appSync = !appSync;
+#if defined(QT_DEBUG)
+        else if (arg == "-nograb")
+            appNoGrab = !appNoGrab;
+        else if (arg == "-dograb")
+            appDoGrab = !appDoGrab;
+#endif
+        else
+            argv[j++] = argv[i];
+    }
+
+    priv->argc = j;
+
+#if defined(QT_DEBUG) && defined(Q_OS_LINUX)
+    if (!appNoGrab && !appDoGrab) {
+        QString s;
+        s.sprintf("/proc/%d/cmdline", getppid());
+        QFile f(s);
+        if (f.open(QIODevice::ReadOnly)) {
+            s.clear();
+            char c;
+            while (f.getChar(&c) && c) {
+                if (c == '/')
+                    s.clear();
+                else
+                    s += QLatin1Char(c);
+            }
+            if (s == QLatin1String("gdb")) {
+                appNoGrab = true;
+                qDebug("Qt: gdb: -nograb added to command-line options.\n"
+                       "\t Use the -dograb option to enforce grabbing.");
+            }
+            f.close();
+        }
+    }
+#endif
+
+    // Connect to X server
+    if (qt_is_gui_used && !X11->display) {
+        if ((X11->display = XOpenDisplay(X11->displayName)) == 0) {
+            qWarning("%s: cannot connect to X server %s", appName,
+                     XDisplayName(X11->displayName));
+            QApplicationPrivate::reset_instance_pointer();
+            exit(1);
+        }
+
+        if (appSync)                                // if "-sync" argument
+            XSynchronize(X11->display, true);
+    }
+
+    // Common code, regardless of whether display is foreign.
+
+    // Get X parameters
+
+    if (qt_is_gui_used) {
+        X11->defaultScreen = DefaultScreen(X11->display);
+        X11->screenCount = ScreenCount(X11->display);
+
+        X11->screens = new QX11InfoData[X11->screenCount];
+        X11->argbVisuals = new Visual *[X11->screenCount];
+        X11->argbColormaps = new Colormap[X11->screenCount];
+
+        for (int s = 0; s < X11->screenCount; s++) {
+            QX11InfoData *screen = X11->screens + s;
+            screen->ref = 1; // ensures it doesn't get deleted
+            screen->screen = s;
+
+            int widthMM = DisplayWidthMM(X11->display, s);
+            if (widthMM != 0) {
+                screen->dpiX = (DisplayWidth(X11->display, s) * 254 + widthMM * 5) / (widthMM * 10);
+            } else {
+                screen->dpiX = 72;
+            }
+
+            int heightMM = DisplayHeightMM(X11->display, s);
+            if (heightMM != 0) {
+                screen->dpiY = (DisplayHeight(X11->display, s) * 254 + heightMM * 5) / (heightMM * 10);
+            } else {
+                screen->dpiY = 72;
+            }
+
+            X11->argbVisuals[s] = 0;
+            X11->argbColormaps[s] = 0;
+        }
+
+
+#ifndef QT_NO_XRENDER
+        int xrender_eventbase,  xrender_errorbase;
+        // See if XRender is supported on the connected display
+        if (XQueryExtension(X11->display, "RENDER", &X11->xrender_major,
+                            &xrender_eventbase, &xrender_errorbase)
+            && XRenderQueryExtension(X11->display, &xrender_eventbase,
+                                     &xrender_errorbase)) {
+            // Check the version as well - we need v0.4 or higher
+            int major = 0;
+            int minor = 0;
+            XRenderQueryVersion(X11->display, &major, &minor);
+            if (qgetenv("QT_X11_NO_XRENDER").isNull()) {
+                X11->use_xrender = (major >= 0 && minor >= 5);
+                X11->xrender_version = major*100+minor;
+                // workaround for broken XServer on Ubuntu Breezy (6.8 compiled with 7.0
+                // protocol headers)
+                if (X11->xrender_version == 10
+                    && VendorRelease(X11->display) < 60900000
+                    && QByteArray(ServerVendor(X11->display)).contains("X.Org"))
+                    X11->xrender_version = 9;
+            }
+        }
+#endif // QT_NO_XRENDER
+
+#ifndef QT_NO_MITSHM
+        int mitshm_minor;
+        int mitshm_major;
+        int mitshm_eventbase;
+        int mitshm_errorbase;
+        int mitshm_pixmaps;
+        if (XQueryExtension(X11->display, "MIT-SHM", &X11->mitshm_major,
+                            &mitshm_eventbase, &mitshm_errorbase)
+            && XShmQueryVersion(X11->display, &mitshm_major, &mitshm_minor,
+                                &mitshm_pixmaps))
+        {
+            QString displayName = QLatin1String(XDisplayName(NULL));
+
+            // MITSHM only works for local displays, so do a quick check here
+            // to determine whether the display is local or not (not 100 % accurate).
+            // BGR server layouts are not supported either, since it requires the raster
+            // engine to work on a QImage with BGR layout.
+            bool local = displayName.isEmpty() || displayName.lastIndexOf(QLatin1Char(':')) == 0;
+            if (local && (qgetenv("QT_X11_NO_MITSHM").toInt() == 0)) {
+                Visual *defaultVisual = DefaultVisual(X11->display, DefaultScreen(X11->display));
+                X11->use_mitshm = mitshm_pixmaps && ((defaultVisual->red_mask == 0xff0000
+                                                      || defaultVisual->red_mask == 0xf800)
+                                                     && (defaultVisual->green_mask == 0xff00
+                                                         || defaultVisual->green_mask == 0x7e0)
+                                                     && (defaultVisual->blue_mask == 0xff
+                                                         || defaultVisual->blue_mask == 0x1f));
+            }
+        }
+#endif // QT_NO_MITSHM
+
+        // initialize the graphics system - order is imporant here - it must be done before
+        // the QColormap::initialize() call
+        QApplicationPrivate::graphics_system = QGraphicsSystemFactory::create(QApplicationPrivate::graphics_system_name);
+        QColormap::initialize();
+
+        // Support protocols
+        X11->xdndSetup();
+
+        // Finally create all atoms
+        qt_x11_create_intern_atoms();
+
+        // initialize NET lists
+        qt_get_net_supported();
+        qt_get_net_virtual_roots();
+
+#ifndef QT_NO_XRANDR
+        // See if XRandR is supported on the connected display
+        if (XQueryExtension(X11->display, "RANDR", &X11->xrandr_major,
+                            &X11->xrandr_eventbase, &X11->xrandr_errorbase)) {
+
+#  ifdef QT_RUNTIME_XRANDR
+            X11->ptrXRRSelectInput = 0;
+            X11->ptrXRRUpdateConfiguration = 0;
+            X11->ptrXRRRootToScreen = 0;
+            X11->ptrXRRQueryExtension = 0;
+            QLibrary xrandrLib(QLatin1String("Xrandr"), 2);
+            if (!xrandrLib.load()) { // try without the version number
+                xrandrLib.setFileName(QLatin1String("Xrandr"));
+                xrandrLib.load();
+            }
+            if (xrandrLib.isLoaded()) {
+                X11->ptrXRRSelectInput =
+                    (PtrXRRSelectInput) xrandrLib.resolve("XRRSelectInput");
+                X11->ptrXRRUpdateConfiguration =
+                    (PtrXRRUpdateConfiguration) xrandrLib.resolve("XRRUpdateConfiguration");
+                X11->ptrXRRRootToScreen =
+                    (PtrXRRRootToScreen) xrandrLib.resolve("XRRRootToScreen");
+                X11->ptrXRRQueryExtension =
+                    (PtrXRRQueryExtension) xrandrLib.resolve("XRRQueryExtension");
+            }
+#  else
+            X11->ptrXRRSelectInput = XRRSelectInput;
+            X11->ptrXRRUpdateConfiguration = XRRUpdateConfiguration;
+            X11->ptrXRRRootToScreen = XRRRootToScreen;
+            X11->ptrXRRQueryExtension = XRRQueryExtension;
+#  endif
+
+            if (X11->ptrXRRQueryExtension
+                && X11->ptrXRRQueryExtension(X11->display, &X11->xrandr_eventbase, &X11->xrandr_errorbase)) {
+                // XRandR is supported
+                X11->use_xrandr = true;
+            }
+        }
+#endif // QT_NO_XRANDR
+
+#ifndef QT_NO_XRENDER
+        if (X11->use_xrender) {
+            // XRender is supported, let's see if we have a PictFormat for the
+            // default visual
+            XRenderPictFormat *format =
+                XRenderFindVisualFormat(X11->display,
+                                        (Visual *) QX11Info::appVisual(X11->defaultScreen));
+
+            if (!format) {
+                X11->use_xrender = false;
+            }
+        }
+#endif // QT_NO_XRENDER
+
+#ifndef QT_NO_XFIXES
+        // See if Xfixes is supported on the connected display
+        if (XQueryExtension(X11->display, "XFIXES", &X11->xfixes_major,
+                            &X11->xfixes_eventbase, &X11->xfixes_errorbase)) {
+            X11->ptrXFixesQueryExtension  = XFIXES_LOAD_V1(XFixesQueryExtension);
+            X11->ptrXFixesQueryVersion    = XFIXES_LOAD_V1(XFixesQueryVersion);
+            X11->ptrXFixesSetCursorName   = XFIXES_LOAD_V2(XFixesSetCursorName);
+            X11->ptrXFixesSelectSelectionInput = XFIXES_LOAD_V2(XFixesSelectSelectionInput);
+
+            if(X11->ptrXFixesQueryExtension && X11->ptrXFixesQueryVersion
+               && X11->ptrXFixesQueryExtension(X11->display, &X11->xfixes_eventbase,
+                                               &X11->xfixes_errorbase)) {
+                // Xfixes is supported.
+                // Note: the XFixes protocol version is negotiated using QueryVersion.
+                // We supply the highest version we support, the X server replies with
+                // the highest version it supports, but no higher than the version we
+                // asked for. The version sent back is the protocol version the X server
+                // will use to talk us. If this call is removed, the behavior of the
+                // X server when it receives an XFixes request is undefined.
+                int major = 3;
+                int minor = 0;
+                X11->ptrXFixesQueryVersion(X11->display, &major, &minor);
+                X11->use_xfixes = (major >= 1);
+                X11->xfixes_major = major;
+            }
+        }
+#endif // QT_NO_XFIXES
+
+#ifndef QT_NO_XCURSOR
+#ifdef QT_RUNTIME_XCURSOR
+        X11->ptrXcursorLibraryLoadCursor = 0;
+        QLibrary xcursorLib(QLatin1String("Xcursor"), 1);
+        bool xcursorFound = xcursorLib.load();
+        if (!xcursorFound) { //try without the version number
+            xcursorLib.setFileName(QLatin1String("Xcursor"));
+            xcursorFound = xcursorLib.load();
+        }
+        if (xcursorFound) {
+            X11->ptrXcursorLibraryLoadCursor =
+                (PtrXcursorLibraryLoadCursor) xcursorLib.resolve("XcursorLibraryLoadCursor");
+        }
+#else
+        X11->ptrXcursorLibraryLoadCursor = XcursorLibraryLoadCursor;
+#endif // QT_RUNTIME_XCURSOR
+#endif // QT_NO_XCURSOR
+
+#ifndef QT_NO_XSYNC
+        int xsync_evbase, xsync_errbase;
+        int major, minor;
+        if (XSyncQueryExtension(X11->display, &xsync_evbase, &xsync_errbase))
+            XSyncInitialize(X11->display, &major, &minor);
+#endif // QT_NO_XSYNC
+
+#ifndef QT_NO_XINERAMA
+#ifdef QT_RUNTIME_XINERAMA
+        X11->ptrXineramaQueryExtension = 0;
+        X11->ptrXineramaIsActive = 0;
+        X11->ptrXineramaQueryScreens = 0;
+        QLibrary xineramaLib(QLatin1String("Xinerama"), 1);
+        bool xineramaFound = xineramaLib.load();
+        if (!xineramaFound) { //try without the version number
+            xineramaLib.setFileName(QLatin1String("Xinerama"));
+            xineramaFound = xineramaLib.load();
+        }
+        if (xineramaFound) {
+            X11->ptrXineramaQueryExtension =
+                (PtrXineramaQueryExtension) xineramaLib.resolve("XineramaQueryExtension");
+            X11->ptrXineramaIsActive =
+                (PtrXineramaIsActive) xineramaLib.resolve("XineramaIsActive");
+            X11->ptrXineramaQueryScreens =
+                (PtrXineramaQueryScreens) xineramaLib.resolve("XineramaQueryScreens");
+        }
+#else
+        X11->ptrXineramaQueryScreens = XineramaQueryScreens;
+        X11->ptrXineramaIsActive = XineramaIsActive;
+        X11->ptrXineramaQueryExtension = XineramaQueryExtension;
+#endif // QT_RUNTIME_XINERAMA
+#endif // QT_NO_XINERAMA
+
+#ifndef QT_NO_XINPUT
+        // See if Xinput is supported on the connected display
+        X11->ptrXCloseDevice = 0;
+        X11->ptrXListInputDevices = 0;
+        X11->ptrXOpenDevice = 0;
+        X11->ptrXFreeDeviceList = 0;
+        X11->ptrXSelectExtensionEvent = 0;
+        X11->use_xinput = XQueryExtension(X11->display, "XInputExtension", &X11->xinput_major,
+                                          &X11->xinput_eventbase, &X11->xinput_errorbase);
+        if (X11->use_xinput) {
+            X11->ptrXCloseDevice = XINPUT_LOAD(XCloseDevice);
+            X11->ptrXListInputDevices = XINPUT_LOAD(XListInputDevices);
+            X11->ptrXOpenDevice = XINPUT_LOAD(XOpenDevice);
+            X11->ptrXFreeDeviceList = XINPUT_LOAD(XFreeDeviceList);
+            X11->ptrXSelectExtensionEvent = XINPUT_LOAD(XSelectExtensionEvent);
+        }
+#endif // QT_NO_XINPUT
+
+#if !defined(QT_NO_FONTCONFIG)
+        int dpi = 0;
+        getXDefault("Xft", FC_DPI, &dpi);
+        if (dpi) {
+            for (int s = 0; s < ScreenCount(X11->display); ++s) {
+                QX11Info::setAppDpiX(s, dpi);
+                QX11Info::setAppDpiY(s, dpi);
+            }
+        }
+        double fc_scale = 1.;
+        getXDefault("Xft", FC_SCALE, &fc_scale);
+        X11->fc_scale = fc_scale;
+        for (int s = 0; s < ScreenCount(X11->display); ++s) {
+            int subpixel = FC_RGBA_UNKNOWN;
+#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
+            if (X11->use_xrender) {
+                int rsp = XRenderQuerySubpixelOrder(X11->display, s);
+                switch (rsp) {
+                default:
+                case SubPixelUnknown:
+                    subpixel = FC_RGBA_UNKNOWN;
+                    break;
+                case SubPixelHorizontalRGB:
+                    subpixel = FC_RGBA_RGB;
+                    break;
+                case SubPixelHorizontalBGR:
+                    subpixel = FC_RGBA_BGR;
+                    break;
+                case SubPixelVerticalRGB:
+                    subpixel = FC_RGBA_VRGB;
+                    break;
+                case SubPixelVerticalBGR:
+                    subpixel = FC_RGBA_VBGR;
+                    break;
+                case SubPixelNone:
+                    subpixel = FC_RGBA_NONE;
+                    break;
+                }
+            }
+#endif
+
+            char *rgba = XGetDefault(X11->display, "Xft", FC_RGBA);
+            if (rgba) {
+                char *end = 0;
+                int v = strtol(rgba, &end, 0);
+                if (rgba != end) {
+                    subpixel = v;
+                } else if (qstrncmp(rgba, "unknown", 7) == 0) {
+                    subpixel = FC_RGBA_UNKNOWN;
+                } else if (qstrncmp(rgba, "rgb", 3) == 0) {
+                    subpixel = FC_RGBA_RGB;
+                } else if (qstrncmp(rgba, "bgr", 3) == 0) {
+                    subpixel = FC_RGBA_BGR;
+                } else if (qstrncmp(rgba, "vrgb", 4) == 0) {
+                    subpixel = FC_RGBA_VRGB;
+                } else if (qstrncmp(rgba, "vbgr", 4) == 0) {
+                    subpixel = FC_RGBA_VBGR;
+                } else if (qstrncmp(rgba, "none", 4) == 0) {
+                    subpixel = FC_RGBA_NONE;
+                }
+            }
+            X11->screens[s].subpixel = subpixel;
+        }
+        getXDefault("Xft", FC_ANTIALIAS, &X11->fc_antialias);
+#ifdef FC_HINT_STYLE
+        getXDefault("Xft", FC_HINT_STYLE, &X11->fc_hint_style);
+#endif
+#if 0
+        // ###### these are implemented by Xft, not sure we need them
+        getXDefault("Xft", FC_AUTOHINT, &X11->fc_autohint);
+        getXDefault("Xft", FC_HINTING, &X11->fc_autohint);
+        getXDefault("Xft", FC_MINSPACE, &X11->fc_autohint);
+#endif
+#endif // QT_NO_XRENDER
+
+        // initialize key mapper
+        QKeyMapper::changeKeyboard();
+
+#ifndef QT_NO_XKB
+        if (qt_keymapper_private()->useXKB) {
+            // If XKB is detected, set the GrabsUseXKBState option so input method
+            // compositions continue to work (ie. deadkeys)
+            unsigned int state = XkbPCF_GrabsUseXKBStateMask;
+            (void) XkbSetPerClientControls(X11->display, state, &state);
+        }
+#endif // QT_NO_XKB
+
+        // Misc. initialization
+#if 0 //disabled for now..
+        QSegfaultHandler::initialize(priv->argv, priv->argc);
+#endif
+        QCursorData::initialize();
+    }
+    QFont::initialize();
+
+    if(qt_is_gui_used) {
+        qApp->setObjectName(QString::fromLocal8Bit(appName));
+
+        int screen;
+        for (screen = 0; screen < X11->screenCount; ++screen) {
+            XSelectInput(X11->display, QX11Info::appRootWindow(screen),
+                         KeymapStateMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask);
+
+#ifndef QT_NO_XRANDR
+            if (X11->use_xrandr)
+                X11->ptrXRRSelectInput(X11->display, QX11Info::appRootWindow(screen), True);
+#endif // QT_NO_XRANDR
+        }
+    }
+
+    if (qt_is_gui_used) {
+        // Attempt to determine the current running X11 Desktop Enviornment
+        // Use dbus if/when we can, but fall back to using windowManagerName() for now
+
+        X11->compositingManagerRunning = XGetSelectionOwner(X11->display,
+                                                            ATOM(_NET_WM_CM_S0));
+        X11->desktopEnvironment = DE_UNKNOWN;
+        X11->desktopVersion = 0;
+
+        // See if the current window manager is using the freedesktop.org spec to give its name
+        Window windowManagerWindow = XNone;
+        Atom typeReturned;
+        int formatReturned;
+        unsigned long nitemsReturned;
+        unsigned long unused;
+        unsigned char *data = 0;
+        if (XGetWindowProperty(QX11Info::display(), QX11Info::appRootWindow(),
+                           ATOM(_NET_SUPPORTING_WM_CHECK),
+                           0, 1024, False, XA_WINDOW, &typeReturned,
+                           &formatReturned, &nitemsReturned, &unused, &data)
+              == Success) {
+            if (typeReturned == XA_WINDOW && formatReturned == 32)
+                windowManagerWindow = *((Window*) data);
+            if (data)
+                XFree(data);
+
+            if (windowManagerWindow != XNone) {
+                QString wmName;
+                Atom utf8atom = ATOM(UTF8_STRING);
+                if (XGetWindowProperty(QX11Info::display(), windowManagerWindow, ATOM(_NET_WM_NAME),
+                                       0, 1024, False, utf8atom, &typeReturned,
+                                       &formatReturned, &nitemsReturned, &unused, &data)
+                    == Success) {
+                    if (typeReturned == utf8atom && formatReturned == 8)
+                        wmName = QString::fromUtf8((const char*)data);
+                    if (data)
+                        XFree(data);
+                    if (wmName == QLatin1String("KWin"))
+                        X11->desktopEnvironment = DE_KDE;
+                    if (wmName == QLatin1String("Metacity"))
+                        X11->desktopEnvironment = DE_GNOME;
+                }
+            }
+        }
+
+        // Running a different/newer/older window manager?  Try some other things
+        if (X11->desktopEnvironment == DE_UNKNOWN){
+            Atom type;
+            int format;
+            unsigned long length, after;
+            uchar *data = 0;
+
+            QString session = QString::fromLocal8Bit(qgetenv("DESKTOP_SESSION"));
+            if (session == QLatin1String("kde")) {
+                X11->desktopEnvironment = DE_KDE;
+            } else if (session == QLatin1String("gnome") || session == QLatin1String("xfce")) {
+                X11->desktopEnvironment = DE_GNOME;
+            } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
+                                          0, 1, False, AnyPropertyType, &type, &format, &length,
+                                   &after, &data) == Success && length) {
+                // DTWM is running, meaning most likely CDE is running...
+                X11->desktopEnvironment = DE_CDE;
+            } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+                                          ATOM(GNOME_BACKGROUND_PROPERTIES), 0, 1, False, AnyPropertyType,
+                                          &type, &format, &length, &after, &data) == Success && length) {
+                X11->desktopEnvironment = DE_GNOME;
+            } else if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) {
+                X11->desktopEnvironment = DE_GNOME;
+            } else if ((XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KDE_FULL_SESSION),
+                                           0, 1, False, AnyPropertyType, &type, &format, &length, &after, &data) == Success
+                        && length)
+                       || (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KWIN_RUNNING),
+                                              0, 1, False, AnyPropertyType, &type, &format, &length,
+                                              &after, &data) == Success
+                           && length)
+                       || (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KWM_RUNNING),
+                                              0, 1, False, AnyPropertyType, &type, &format, &length,
+                                              &after, &data) == Success && length)) {
+                X11->desktopEnvironment = DE_KDE;
+            } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_SGI_DESKS_MANAGER),
+                                          0, 1, False, XA_WINDOW, &type, &format, &length, &after, &data) == Success
+                       && length) {
+                X11->desktopEnvironment = DE_4DWM;
+            }
+            if (data)
+                XFree((char *)data);
+        }
+
+        if (X11->desktopEnvironment == DE_KDE)
+            X11->desktopVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt();
+
+#if !defined(QT_NO_STYLE_GTK)
+        if (X11->desktopEnvironment == DE_GNOME) {
+            static bool menusHaveIcons = QGtk::getGConfBool(QLatin1String("/desktop/gnome/interface/menus_have_icons"), true);
+            QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !menusHaveIcons);
+        }
+#endif
+        qt_set_input_encoding();
+
+        qt_set_x11_resources(appFont, appFGCol, appBGCol, appBTNCol);
+
+        // be smart about the size of the default font. most X servers have helvetica
+        // 12 point available at 2 resolutions:
+        //     75dpi (12 pixels) and 100dpi (17 pixels).
+        // At 95 DPI, a 12 point font should be 16 pixels tall - in which case a 17
+        // pixel font is a closer match than a 12 pixel font
+        int ptsz = (X11->use_xrender
+                    ? 9
+                    : (int) (((QX11Info::appDpiY() >= 95 ? 17. : 12.) *
+                              72. / (float) QX11Info::appDpiY()) + 0.5));
+
+        if (!QApplicationPrivate::sys_font) {
+            // no font from settings or RESOURCE_MANAGER, provide a fallback
+            QFont f(X11->has_fontconfig ? QLatin1String("Sans Serif") : QLatin1String("Helvetica"),
+                    ptsz);
+            QApplicationPrivate::setSystemFont(f);
+        }
+
+#if !defined (QT_NO_TABLET)
+        if (X11->use_xinput) {
+            int ndev,
+                i,
+                j;
+            bool gotStylus,
+                gotEraser;
+            XDeviceInfo *devices = 0, *devs;
+            XInputClassInfo *ip;
+            XAnyClassPtr any;
+            XValuatorInfoPtr v;
+            XAxisInfoPtr a;
+            XDevice *dev = 0;
+
+            if (X11->ptrXListInputDevices) {
+                devices = X11->ptrXListInputDevices(X11->display, &ndev);
+                if (!devices)
+                    qWarning("QApplication: Failed to get list of tablet devices");
+            }
+            if (!devices)
+                ndev = -1;
+            QTabletEvent::TabletDevice deviceType;
+            for (devs = devices, i = 0; i < ndev && devs; i++, devs++) {
+                dev = 0;
+                deviceType = QTabletEvent::NoDevice;
+                gotStylus = false;
+                gotEraser = false;
+
+#if defined(Q_OS_IRIX)
+                QString devName = QString::fromLocal8Bit(devs->name).toLower();
+                if (devName == QLatin1String(WACOM_NAME)) {
+                    deviceType = QTabletEvent::Stylus;
+                    gotStylus = true;
+                }
+#else
+                if (devs->type == ATOM(XWacomStylus)) {
+                    deviceType = QTabletEvent::Stylus;
+                    if (wacomDeviceName()->isEmpty())
+                        wacomDeviceName()->append(devs->name);
+                    gotStylus = true;
+                } else if (devs->type == ATOM(XWacomEraser)) {
+                    deviceType = QTabletEvent::XFreeEraser;
+                    gotEraser = true;
+                }
+#endif
+                if (deviceType == QTabletEvent::NoDevice)
+                    continue;
+
+                if (gotStylus || gotEraser) {
+                    if (X11->ptrXOpenDevice)
+                        dev = X11->ptrXOpenDevice(X11->display, devs->id);
+
+                    if (!dev)
+                        continue;
+
+                    QTabletDeviceData device_data;
+                    device_data.deviceType = deviceType;
+                    device_data.eventCount = 0;
+                    device_data.device = dev;
+                    device_data.xinput_motion = -1;
+                    device_data.xinput_key_press = -1;
+                    device_data.xinput_key_release = -1;
+                    device_data.xinput_button_press = -1;
+                    device_data.xinput_button_release = -1;
+                    device_data.xinput_proximity_in = -1;
+                    device_data.xinput_proximity_out = -1;
+                    device_data.widgetToGetPress = 0;
+
+                    if (dev->num_classes > 0) {
+                        for (ip = dev->classes, j = 0; j < dev->num_classes;
+                             ip++, j++) {
+                            switch (ip->input_class) {
+                            case KeyClass:
+                                DeviceKeyPress(dev, device_data.xinput_key_press,
+                                               device_data.eventList[device_data.eventCount]);
+                                if (device_data.eventList[device_data.eventCount])
+                                    ++device_data.eventCount;
+                                DeviceKeyRelease(dev, device_data.xinput_key_release,
+                                                 device_data.eventList[device_data.eventCount]);
+                                if (device_data.eventList[device_data.eventCount])
+                                    ++device_data.eventCount;
+                                break;
+                            case ButtonClass:
+                                DeviceButtonPress(dev, device_data.xinput_button_press,
+                                                  device_data.eventList[device_data.eventCount]);
+                                if (device_data.eventList[device_data.eventCount])
+                                    ++device_data.eventCount;
+                                DeviceButtonRelease(dev, device_data.xinput_button_release,
+                                                    device_data.eventList[device_data.eventCount]);
+                                if (device_data.eventList[device_data.eventCount])
+                                    ++device_data.eventCount;
+                                break;
+                            case ValuatorClass:
+                                // I'm only going to be interested in motion when the
+                                // stylus is already down anyway!
+                                DeviceMotionNotify(dev, device_data.xinput_motion,
+                                                   device_data.eventList[device_data.eventCount]);
+                                if (device_data.eventList[device_data.eventCount])
+                                    ++device_data.eventCount;
+                                ProximityIn(dev, device_data.xinput_proximity_in, device_data.eventList[device_data.eventCount]);
+                                if (device_data.eventList[device_data.eventCount])
+                                    ++device_data.eventCount;
+                                ProximityOut(dev, device_data.xinput_proximity_out, device_data.eventList[device_data.eventCount]);
+                                if (device_data.eventList[device_data.eventCount])
+                                    ++device_data.eventCount;
+                            default:
+                                break;
+                            }
+                        }
+                    }
+
+                    // get the min/max value for pressure!
+                    any = (XAnyClassPtr) (devs->inputclassinfo);
+                    for (j = 0; j < devs->num_classes; j++) {
+                        if (any->c_class == ValuatorClass) {
+                            v = (XValuatorInfoPtr) any;
+                            a = (XAxisInfoPtr) ((char *) v +
+                                                sizeof (XValuatorInfo));
+#if defined (Q_OS_IRIX)
+                            // I'm not exaclty wild about this, but the
+                            // dimensions of the tablet are more relevant here
+                            // than the min and max values from the axis
+                            // (actually it seems to be 2/3 or what is in the
+                            // axis.  So we'll try to parse it from this
+                            // string. --tws
+                            char returnString[SGIDeviceRtrnLen];
+                            int tmp;
+                            if (XSGIMiscQueryExtension(X11->display, &tmp, &tmp)
+                                && XSGIDeviceQuery(X11->display, devs->id,
+                                                   "dimensions", returnString)) {
+                                QString str = QLatin1String(returnString);
+                                int comma = str.indexOf(',');
+                                device_data.minX = 0;
+                                device_data.minY = 0;
+                                device_data.maxX = str.left(comma).toInt();
+                                device_data.maxY = str.mid(comma + 1).toInt();
+                            } else {
+                                device_data.minX = a[WAC_XCOORD_I].min_value;
+                                device_data.maxX = a[WAC_XCOORD_I].max_value;
+                                device_data.minY = a[WAC_YCOORD_I].min_value;
+                                device_data.maxY = a[WAC_YCOORD_I].max_value;
+                            }
+                            device_data.minPressure = a[WAC_PRESSURE_I].min_value;
+                            device_data.maxPressure = a[WAC_PRESSURE_I].max_value;
+                            device_data.minTanPressure = a[WAC_TAN_PRESSURE_I].min_value;
+                            device_data.maxTanPressure = a[WAC_TAN_PRESSURE_I].max_value;
+                            device_data.minZ = a[WAC_ZCOORD_I].min_value;
+                            device_data.maxZ = a[WAC_ZCOORD_I].max_value;
+#else
+                            device_data.minX = a[0].min_value;
+                            device_data.maxX = a[0].max_value;
+                            device_data.minY = a[1].min_value;
+                            device_data.maxY = a[1].max_value;
+                            device_data.minPressure = a[2].min_value;
+                            device_data.maxPressure = a[2].max_value;
+                            device_data.minTanPressure = 0;
+                            device_data.maxTanPressure = 0;
+                            device_data.minZ = 0;
+                            device_data.maxZ = 0;
+#endif
+
+                            // got the max pressure no need to go further...
+                            break;
+                        }
+                        any = (XAnyClassPtr) ((char *) any + any->length);
+                    } // end of for loop
+
+                    tablet_devices()->append(device_data);
+                } // if (gotStylus || gotEraser)
+            }
+            if (X11->ptrXFreeDeviceList)
+                X11->ptrXFreeDeviceList(devices);
+        }
+#endif // QT_NO_TABLET
+
+        X11->startupId = getenv("DESKTOP_STARTUP_ID");
+        if (X11->startupId) {
+#ifndef QT_NO_UNSETENV
+            unsetenv("DESKTOP_STARTUP_ID");
+#else
+            // it's a small memory leak, however we won't crash if Qt is
+            // unloaded and someones tries to use the envoriment.
+            putenv(strdup("DESKTOP_STARTUP_ID="));
+#endif
+        }
+   } else {
+        // read some non-GUI settings when not using the X server...
+
+        if (QApplication::desktopSettingsAware()) {
+            QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+            settings.beginGroup(QLatin1String("Qt"));
+
+            // read library (ie. plugin) path list
+            QString libpathkey = QString::fromLatin1("%1.%2/libraryPath")
+                                 .arg(QT_VERSION >> 16)
+                                 .arg((QT_VERSION & 0xff00) >> 8);
+            QStringList pathlist =
+                settings.value(libpathkey).toString().split(QLatin1Char(':'));
+            if (! pathlist.isEmpty()) {
+                QStringList::ConstIterator it = pathlist.constBegin();
+                while (it != pathlist.constEnd())
+                    QApplication::addLibraryPath(*it++);
+            }
+
+            QString defaultcodec = settings.value(QLatin1String("defaultCodec"),
+                                                  QVariant(QLatin1String("none"))).toString();
+            if (defaultcodec != QLatin1String("none")) {
+                QTextCodec *codec = QTextCodec::codecForName(defaultcodec.toLatin1());
+                if (codec)
+                    QTextCodec::setCodecForTr(codec);
+            }
+
+            settings.endGroup(); // Qt
+        }
+    }
+
+#if !defined (Q_OS_IRIX) && !defined (QT_NO_TABLET)
+    QLibrary wacom(QString::fromLatin1("wacomcfg"), 0); // version 0 is the latest release at time of writing this.
+    if (wacom.load()) {
+        // NOTE: C casts instead of reinterpret_cast for GCC 3.3.x
+        ptrWacomConfigInit = (PtrWacomConfigInit)wacom.resolve("WacomConfigInit");
+        ptrWacomConfigOpenDevice = (PtrWacomConfigOpenDevice)wacom.resolve("WacomConfigOpenDevice");
+        ptrWacomConfigGetRawParam  = (PtrWacomConfigGetRawParam)wacom.resolve("WacomConfigGetRawParam");
+        ptrWacomConfigCloseDevice = (PtrWacomConfigCloseDevice)wacom.resolve("WacomConfigCloseDevice");
+        ptrWacomConfigTerm = (PtrWacomConfigTerm)wacom.resolve("WacomConfigTerm");
+
+        if (ptrWacomConfigInit == 0 || ptrWacomConfigOpenDevice == 0 || ptrWacomConfigGetRawParam == 0
+                || ptrWacomConfigCloseDevice == 0 || ptrWacomConfigTerm == 0) { // either we have all, or we have none.
+            ptrWacomConfigInit = 0;
+            ptrWacomConfigOpenDevice = 0;
+            ptrWacomConfigGetRawParam  = 0;
+            ptrWacomConfigCloseDevice = 0;
+            ptrWacomConfigTerm = 0;
+        }
+    }
+#endif
+}
+
+void QApplicationPrivate::initializeWidgetPaletteHash()
+{
+}
+
+/*****************************************************************************
+  qt_cleanup() - cleans up when the application is finished
+ *****************************************************************************/
+
+void qt_cleanup()
+{
+    if (app_save_rootinfo)                        // root window must keep state
+        qt_save_rootinfo();
+
+    if (qt_is_gui_used) {
+        QPixmapCache::clear();
+        QCursorData::cleanup();
+        QFont::cleanup();
+        QColormap::cleanup();
+
+#if !defined (QT_NO_TABLET)
+        QTabletDeviceDataList *devices = qt_tablet_devices();
+        if (X11->ptrXCloseDevice)
+            for (int i = 0; i < devices->size(); ++i)
+                X11->ptrXCloseDevice(X11->display, (XDevice*)devices->at(i).device);
+        devices->clear();
+#endif
+    }
+
+#ifndef QT_NO_XRENDER
+    for (int i = 0; i < X11->solid_fill_count; ++i) {
+        if (X11->solid_fills[i].picture)
+            XRenderFreePicture(X11->display, X11->solid_fills[i].picture);
+    }
+    for (int i = 0; i < X11->pattern_fill_count; ++i) {
+        if (X11->pattern_fills[i].picture)
+            XRenderFreePicture(X11->display, X11->pattern_fills[i].picture);
+    }
+#endif
+
+#if !defined(QT_NO_IM)
+    delete QApplicationPrivate::inputContext;
+    QApplicationPrivate::inputContext = 0;
+#endif
+
+    // Reset the error handlers
+    if (qt_is_gui_used)
+        XSync(X11->display, False); // sync first to process all possible errors
+    XSetErrorHandler(original_x_errhandler);
+    XSetIOErrorHandler(original_xio_errhandler);
+
+    if (X11->argbColormaps) {
+        for (int s = 0; s < X11->screenCount; s++) {
+            if (X11->argbColormaps[s])
+                XFreeColormap(X11->display, X11->argbColormaps[s]);
+        }
+    }
+
+    if (qt_is_gui_used && !X11->foreignDisplay)
+        XCloseDisplay(X11->display);                // close X display
+    X11->display = 0;
+
+    delete [] X11->screens;
+    delete [] X11->argbVisuals;
+    delete [] X11->argbColormaps;
+
+    if (X11->foreignDisplay) {
+        delete [] (char *)appName;
+        appName = 0;
+    }
+
+    delete [] (char *)appClass;
+    appClass = 0;
+
+    if (X11->net_supported_list)
+        delete [] X11->net_supported_list;
+    X11->net_supported_list = 0;
+
+    if (X11->net_virtual_root_list)
+        delete [] X11->net_virtual_root_list;
+    X11->net_virtual_root_list = 0;
+
+    delete X11;
+    X11 = 0;
+}
+
+
+/*****************************************************************************
+  Platform specific global and internal functions
+ *****************************************************************************/
+
+void qt_save_rootinfo()                                // save new root info
+{
+    Atom type;
+    int format;
+    unsigned long length, after;
+    uchar *data = 0;
+
+    if (ATOM(_XSETROOT_ID)) {                        // kill old pixmap
+        if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
+                                 ATOM(_XSETROOT_ID), 0, 1,
+                                 True, AnyPropertyType, &type, &format,
+                                 &length, &after, &data) == Success) {
+            if (type == XA_PIXMAP && format == 32 && length == 1 &&
+                 after == 0 && data) {
+                XKillClient(X11->display, *((Pixmap*)data));
+            }
+            Pixmap dummy = XCreatePixmap(X11->display, QX11Info::appRootWindow(),
+                                          1, 1, 1);
+            XChangeProperty(X11->display, QX11Info::appRootWindow(),
+                             ATOM(_XSETROOT_ID), XA_PIXMAP, 32,
+                             PropModeReplace, (uchar *)&dummy, 1);
+            XSetCloseDownMode(X11->display, RetainPermanent);
+        }
+    }
+    if (data)
+        XFree((char *)data);
+}
+
+void qt_updated_rootinfo()
+{
+    app_save_rootinfo = true;
+}
+
+// ### Cleanup, this function is not in use!
+bool qt_wstate_iconified(WId winid)
+{
+    Atom type;
+    int format;
+    unsigned long length, after;
+    uchar *data = 0;
+    int r = XGetWindowProperty(X11->display, winid, ATOM(WM_STATE), 0, 2,
+                                 False, AnyPropertyType, &type, &format,
+                                 &length, &after, &data);
+    bool iconic = false;
+    if (r == Success && data && format == 32) {
+        // quint32 *wstate = (quint32*)data;
+        unsigned long *wstate = (unsigned long *) data;
+        iconic = (*wstate == IconicState);
+        XFree((char *)data);
+    }
+    return iconic;
+}
+
+QString QApplicationPrivate::appName() const
+{
+    return QString::fromLocal8Bit(QT_PREPEND_NAMESPACE(appName));
+}
+
+const char *QX11Info::appClass()                                // get application class
+{
+    return QT_PREPEND_NAMESPACE(appClass);
+}
+
+bool qt_nograb()                                // application no-grab option
+{
+#if defined(QT_DEBUG)
+    return appNoGrab;
+#else
+    return false;
+#endif
+}
+
+
+/*****************************************************************************
+  Platform specific QApplication members
+ *****************************************************************************/
+
+#ifdef QT3_SUPPORT
+void QApplication::setMainWidget(QWidget *mainWidget)
+{
+#ifndef QT_NO_DEBUG
+    if (mainWidget && mainWidget->parentWidget() && mainWidget->isWindow())
+        qWarning("QApplication::setMainWidget: New main widget (%s/%s) "
+                  "has a parent",
+                  mainWidget->metaObject()->className(), mainWidget->objectName().toLocal8Bit().constData());
+#endif
+    if (mainWidget)
+        mainWidget->d_func()->createWinId();
+    QApplicationPrivate::main_widget = mainWidget;
+    if (QApplicationPrivate::main_widget) // give WM command line
+        QApplicationPrivate::applyX11SpecificCommandLineArguments(QApplicationPrivate::main_widget);
+}
+#endif
+
+void QApplicationPrivate::applyX11SpecificCommandLineArguments(QWidget *main_widget)
+{
+    static bool beenHereDoneThat = false;
+    if (beenHereDoneThat)
+        return;
+    beenHereDoneThat = true;
+    Q_ASSERT(main_widget->testAttribute(Qt::WA_WState_Created));
+    if (mwTitle) {
+        XStoreName(X11->display, main_widget->effectiveWinId(), (char*)mwTitle);
+        QByteArray net_wm_name = QString::fromLocal8Bit(mwTitle).toUtf8();
+        XChangeProperty(X11->display, main_widget->effectiveWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
+                        PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
+    }
+    if (mwGeometry) { // parse geometry
+        int x, y;
+        int w, h;
+        int m = XParseGeometry((char*)mwGeometry, &x, &y, (uint*)&w, (uint*)&h);
+        QSize minSize = main_widget->minimumSize();
+        QSize maxSize = main_widget->maximumSize();
+        if ((m & XValue) == 0)
+            x = main_widget->geometry().x();
+        if ((m & YValue) == 0)
+            y = main_widget->geometry().y();
+        if ((m & WidthValue) == 0)
+            w = main_widget->width();
+        if ((m & HeightValue) == 0)
+            h = main_widget->height();
+        w = qMin(w,maxSize.width());
+        h = qMin(h,maxSize.height());
+        w = qMax(w,minSize.width());
+        h = qMax(h,minSize.height());
+        if ((m & XNegative)) {
+            x = QApplication::desktop()->width()  + x - w;
+        }
+        if ((m & YNegative)) {
+            y = QApplication::desktop()->height() + y - h;
+        }
+        main_widget->setGeometry(x, y, w, h);
+    }
+}
+
+#ifndef QT_NO_CURSOR
+
+/*****************************************************************************
+  QApplication cursor stack
+ *****************************************************************************/
+
+void QApplication::setOverrideCursor(const QCursor &cursor)
+{
+    qApp->d_func()->cursor_list.prepend(cursor);
+
+    QWidgetList all = allWidgets();
+    for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
+        register QWidget *w = *it;
+        if ((w->testAttribute(Qt::WA_SetCursor) || w->isWindow()) && (w->windowType() != Qt::Desktop))
+            qt_x11_enforce_cursor(w);
+    }
+    XFlush(X11->display);                                // make X execute it NOW
+}
+
+void QApplication::restoreOverrideCursor()
+{
+    if (qApp->d_func()->cursor_list.isEmpty())
+        return;
+    qApp->d_func()->cursor_list.removeFirst();
+
+    if (QWidgetPrivate::mapper != 0 && !closingDown()) {
+        QWidgetList all = allWidgets();
+        for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
+            register QWidget *w = *it;
+            if ((w->testAttribute(Qt::WA_SetCursor) || w->isWindow()) && (w->windowType() != Qt::Desktop))
+                qt_x11_enforce_cursor(w);
+        }
+        XFlush(X11->display);
+    }
+}
+
+#endif
+
+
+/*****************************************************************************
+  Routines to find a Qt widget from a screen position
+ *****************************************************************************/
+
+Window QX11Data::findClientWindow(Window win, Atom property, bool leaf)
+{
+    Atom   type = XNone;
+    int           format, i;
+    ulong  nitems, after;
+    uchar *data = 0;
+    Window root, parent, target=0, *children=0;
+    uint   nchildren;
+    if (XGetWindowProperty(X11->display, win, property, 0, 0, false, AnyPropertyType,
+                             &type, &format, &nitems, &after, &data) == Success) {
+        if (data)
+            XFree((char *)data);
+        if (type)
+            return win;
+    }
+    if (!XQueryTree(X11->display,win,&root,&parent,&children,&nchildren)) {
+        if (children)
+            XFree((char *)children);
+        return 0;
+    }
+    for (i=nchildren-1; !target && i >= 0; i--)
+        target = X11->findClientWindow(children[i], property, leaf);
+    if (children)
+        XFree((char *)children);
+    return target;
+}
+
+QWidget *QApplication::topLevelAt(const QPoint &p)
+{
+#ifdef QT_NO_CURSOR
+    Q_UNUSED(p);
+    return 0;
+#else
+    int screen = QCursor::x11Screen();
+    int unused;
+
+    int x = p.x();
+    int y = p.y();
+    Window target;
+    if (!XTranslateCoordinates(X11->display,
+                               QX11Info::appRootWindow(screen),
+                               QX11Info::appRootWindow(screen),
+                               x, y, &unused, &unused, &target)) {
+        return 0;
+    }
+    if (!target || target == QX11Info::appRootWindow(screen))
+        return 0;
+    QWidget *w;
+    w = QWidget::find((WId)target);
+
+    if (!w) {
+        X11->ignoreBadwindow();
+        target = X11->findClientWindow(target, ATOM(WM_STATE), true);
+        if (X11->badwindow())
+            return 0;
+        w = QWidget::find((WId)target);
+        if (!w) {
+            // Perhaps the widget at (x,y) is inside a foreign application?
+            // Search all toplevel widgets to see if one is within target
+            QWidgetList list = QApplication::topLevelWidgets();
+            for (int i = 0; i < list.count(); ++i) {
+                QWidget *widget = list.at(i);
+                Window ctarget = target;
+                if (widget->isVisible() && !(widget->windowType() == Qt::Desktop)) {
+                    Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
+                    Window wid = widget->internalWinId();
+                    while (ctarget && !w) {
+                        X11->ignoreBadwindow();
+                        if (!XTranslateCoordinates(X11->display,
+                                                   QX11Info::appRootWindow(screen),
+                                                   ctarget, x, y, &unused, &unused, &ctarget)
+                                || X11->badwindow())
+                            break;
+                        if (ctarget == wid) {
+                            // Found!
+                            w = widget;
+                            break;
+                        }
+                    }
+                }
+                if (w)
+                    break;
+            }
+        }
+    }
+    return w ? w->window() : 0;
+#endif
+}
+
+void QApplication::syncX()
+{
+    if (X11->display)
+        XSync(X11->display, False);  // don't discard events
+}
+
+
+void QApplication::beep()
+{
+    if (X11->display)
+        XBell(X11->display, 0);
+    else
+        printf("\7");
+}
+
+void QApplication::alert(QWidget *widget, int msec)
+{
+    if (!QApplicationPrivate::checkInstance("alert"))
+        return;
+
+    QWidgetList windowsToMark;
+    if (!widget) {
+        windowsToMark += topLevelWidgets();
+    } else {
+        windowsToMark.append(widget->window());
+    }
+
+    for (int i = 0; i < windowsToMark.size(); ++i) {
+        QWidget *window = windowsToMark.at(i);
+        if (!window->isActiveWindow()) {
+            qt_change_net_wm_state(window, true, ATOM(_NET_WM_STATE_DEMANDS_ATTENTION));
+            if (msec != 0) {
+                QTimer *timer = new QTimer(qApp);
+                timer->setSingleShot(true);
+                connect(timer, SIGNAL(timeout()), qApp, SLOT(_q_alertTimeOut()));
+                if (QTimer *oldTimer = qApp->d_func()->alertTimerHash.value(window)) {
+                    qApp->d_func()->alertTimerHash.remove(window);
+                    delete oldTimer;
+                }
+                qApp->d_func()->alertTimerHash.insert(window, timer);
+                timer->start(msec);
+            }
+        }
+    }
+}
+
+void QApplicationPrivate::_q_alertTimeOut()
+{
+    if (QTimer *timer = qobject_cast<QTimer *>(q_func()->sender())) {
+        QHash<QWidget *, QTimer *>::iterator it = alertTimerHash.begin();
+        while (it != alertTimerHash.end()) {
+            if (it.value() == timer) {
+                QWidget *window = it.key();
+                qt_change_net_wm_state(window, false, ATOM(_NET_WM_STATE_DEMANDS_ATTENTION));
+                alertTimerHash.erase(it);
+                timer->deleteLater();
+                break;
+            }
+            ++it;
+        }
+    }
+}
+
+/*****************************************************************************
+  Special lookup functions for windows that have been reparented recently
+ *****************************************************************************/
+
+static QWidgetMapper *wPRmapper = 0;                // alternative widget mapper
+
+void qPRCreate(const QWidget *widget, Window oldwin)
+{                                                // QWidget::reparent mechanism
+    if (!wPRmapper)
+        wPRmapper = new QWidgetMapper;
+
+    QETWidget *w = static_cast<QETWidget *>(const_cast<QWidget *>(widget));
+    wPRmapper->insert((int)oldwin, w);        // add old window to mapper
+    w->setAttribute(Qt::WA_WState_Reparented);        // set reparented flag
+}
+
+void qPRCleanup(QWidget *widget)
+{
+    QETWidget *etw = static_cast<QETWidget *>(const_cast<QWidget *>(widget));
+    if (!(wPRmapper && widget->testAttribute(Qt::WA_WState_Reparented)))
+        return;                                        // not a reparented widget
+    QWidgetMapper::Iterator it = wPRmapper->begin();
+    while (it != wPRmapper->constEnd()) {
+        QWidget *w = *it;
+        if (w == etw) {                       // found widget
+            etw->setAttribute(Qt::WA_WState_Reparented, false); // clear flag
+            it = wPRmapper->erase(it);// old window no longer needed
+        } else {
+            ++it;
+        }
+    }
+    if (wPRmapper->size() == 0) {        // became empty
+        delete wPRmapper;                // then reset alt mapper
+        wPRmapper = 0;
+    }
+}
+
+static QETWidget *qPRFindWidget(Window oldwin)
+{
+    return wPRmapper ? (QETWidget*)wPRmapper->value((int)oldwin, 0) : 0;
+}
+
+int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
+{
+    if (w && !w->internalWinId())
+        return 0;
+    QETWidget *widget = (QETWidget*)w;
+    if (event->xclient.format == 32 && event->xclient.message_type) {
+        if (event->xclient.message_type == ATOM(WM_PROTOCOLS)) {
+            Atom a = event->xclient.data.l[0];
+            if (a == ATOM(WM_DELETE_WINDOW)) {
+                if (passive_only) return 0;
+                widget->translateCloseEvent(event);
+            }
+            else if (a == ATOM(WM_TAKE_FOCUS)) {
+                if ((ulong) event->xclient.data.l[1] > X11->time)
+                    X11->time = event->xclient.data.l[1];
+                QWidget *amw = activeModalWidget();
+                if (amw && !QApplicationPrivate::tryModalHelper(widget, 0)) {
+                    QWidget *p = amw->parentWidget();
+                    while (p && p != widget)
+                        p = p->parentWidget();
+                    if (!p || !X11->net_supported_list)
+                        amw->raise(); // help broken window managers
+                    amw->activateWindow();
+                }
+#ifndef QT_NO_WHATSTHIS
+            } else if (a == ATOM(_NET_WM_CONTEXT_HELP)) {
+                QWhatsThis::enterWhatsThisMode();
+#endif // QT_NO_WHATSTHIS
+            } else if (a == ATOM(_NET_WM_PING)) {
+                // avoid send/reply loops
+                Window root = RootWindow(X11->display, w->x11Info().screen());
+                if (event->xclient.window != root) {
+                    event->xclient.window = root;
+                    XSendEvent(event->xclient.display, event->xclient.window,
+                                False, SubstructureNotifyMask|SubstructureRedirectMask, event);
+                }
+#ifndef QT_NO_XSYNC
+            } else if (a == ATOM(_NET_WM_SYNC_REQUEST)) {
+                const ulong timestamp = (const ulong) event->xclient.data.l[1];
+                if (timestamp > X11->time)
+                    X11->time = timestamp;
+                if (QTLWExtra *tlw = w->d_func()->maybeTopData()) {
+                    if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
+                        tlw->syncRequestTimestamp = timestamp;
+                        tlw->newCounterValueLo = event->xclient.data.l[2];
+                        tlw->newCounterValueHi = event->xclient.data.l[3];
+                    }
+                }
+#endif
+            }
+        } else if (event->xclient.message_type == ATOM(_QT_SCROLL_DONE)) {
+            widget->translateScrollDoneEvent(event);
+        } else if (event->xclient.message_type == ATOM(XdndPosition)) {
+            X11->xdndHandlePosition(widget, event, passive_only);
+        } else if (event->xclient.message_type == ATOM(XdndEnter)) {
+            X11->xdndHandleEnter(widget, event, passive_only);
+        } else if (event->xclient.message_type == ATOM(XdndStatus)) {
+            X11->xdndHandleStatus(widget, event, passive_only);
+        } else if (event->xclient.message_type == ATOM(XdndLeave)) {
+            X11->xdndHandleLeave(widget, event, passive_only);
+        } else if (event->xclient.message_type == ATOM(XdndDrop)) {
+            X11->xdndHandleDrop(widget, event, passive_only);
+        } else if (event->xclient.message_type == ATOM(XdndFinished)) {
+            X11->xdndHandleFinished(widget, event, passive_only);
+        } else {
+            if (passive_only) return 0;
+            // All other are interactions
+        }
+    } else {
+        X11->motifdndHandle(widget, event, passive_only);
+    }
+
+    return 0;
+}
+
+int QApplication::x11ProcessEvent(XEvent* event)
+{
+    Q_D(QApplication);
+    QScopedLoopLevelCounter loopLevelCounter(d->threadData);
+
+#ifdef ALIEN_DEBUG
+    //qDebug() << "QApplication::x11ProcessEvent:" << event->type;
+#endif
+    switch (event->type) {
+    case ButtonPress:
+        pressed_window = event->xbutton.window;
+        X11->userTime = event->xbutton.time;
+        // fallthrough intended
+    case ButtonRelease:
+        X11->time = event->xbutton.time;
+        break;
+    case MotionNotify:
+        X11->time = event->xmotion.time;
+        break;
+    case XKeyPress:
+        X11->userTime = event->xkey.time;
+        // fallthrough intended
+    case XKeyRelease:
+        X11->time = event->xkey.time;
+        break;
+    case PropertyNotify:
+        X11->time = event->xproperty.time;
+        break;
+    case EnterNotify:
+    case LeaveNotify:
+        X11->time = event->xcrossing.time;
+        break;
+    case SelectionClear:
+        X11->time = event->xselectionclear.time;
+        break;
+    default:
+        break;
+    }
+#ifndef QT_NO_XFIXES
+    if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) {
+        XFixesSelectionNotifyEvent *req =
+            reinterpret_cast<XFixesSelectionNotifyEvent *>(event);
+        X11->time = req->selection_timestamp;
+    }
+#endif
+
+    QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window);
+
+    if (wPRmapper) {                                // just did a widget reparent?
+        if (widget == 0) {                        // not in std widget mapper
+            switch (event->type) {                // only for mouse/key events
+            case ButtonPress:
+            case ButtonRelease:
+            case MotionNotify:
+            case XKeyPress:
+            case XKeyRelease:
+                widget = qPRFindWidget(event->xany.window);
+                break;
+            }
+        }
+        else if (widget->testAttribute(Qt::WA_WState_Reparented))
+            qPRCleanup(widget);                // remove from alt mapper
+    }
+
+    QETWidget *keywidget=0;
+    bool grabbed=false;
+    if (event->type==XKeyPress || event->type==XKeyRelease) {
+        keywidget = (QETWidget*)QWidget::keyboardGrabber();
+        if (keywidget) {
+            grabbed = true;
+        } else if (!keywidget) {
+            if (d->inPopupMode()) // no focus widget, see if we have a popup
+                keywidget = (QETWidget*) (activePopupWidget()->focusWidget() ? activePopupWidget()->focusWidget() : activePopupWidget());
+            else if (QApplicationPrivate::focus_widget)
+                keywidget = (QETWidget*)QApplicationPrivate::focus_widget;
+            else if (widget)
+                keywidget = (QETWidget*)widget->window();
+        }
+    }
+
+#ifndef QT_NO_IM
+    // Filtering input events by the input context. It has to be taken
+    // place before any other key event consumers such as eventfilters
+    // and accelerators because some input methods require quite
+    // various key combination and sequences. It often conflicts with
+    // accelerators and so on, so we must give the input context the
+    // filtering opportunity first to ensure all input methods work
+    // properly regardless of application design.
+
+    if(keywidget && keywidget->isEnabled() && keywidget->testAttribute(Qt::WA_InputMethodEnabled)) {
+        // block user interaction during session management
+	if((event->type==XKeyPress || event->type==XKeyRelease) && qt_sm_blockUserInput)
+	    return true;
+
+        // for XIM handling
+	QInputContext *qic = keywidget->inputContext();
+	if(qic && qic->x11FilterEvent(keywidget, event))
+	    return true;
+
+	// filterEvent() accepts QEvent *event rather than preexpanded
+	// key event attribute values. This is intended to pass other
+	// QInputEvent in future. Other non IM-related events should
+	// not be forwarded to input contexts to prevent weird event
+	// handling.
+	if ((event->type == XKeyPress || event->type == XKeyRelease)) {
+	    int code = -1;
+	    int count = 0;
+	    Qt::KeyboardModifiers modifiers;
+	    QEvent::Type type;
+	    QString text;
+            KeySym keySym;
+
+            qt_keymapper_private()->translateKeyEventInternal(keywidget, event, keySym, count,
+                                                              text, modifiers, code, type, false);
+
+	    // both key press/release is required for some complex
+	    // input methods. don't eliminate anything.
+	    QKeyEventEx keyevent(type, code, modifiers, text, false, qMax(qMax(count, 1), text.length()),
+                                 event->xkey.keycode, keySym, event->xkey.state);
+	    if(qic && qic->filterEvent(&keyevent))
+		return true;
+	}
+    } else
+#endif // QT_NO_IM
+        {
+            if (XFilterEvent(event, XNone))
+                return true;
+        }
+
+    if (qt_x11EventFilter(event))                // send through app filter
+        return 1;
+
+    if (event->type == MappingNotify) {
+        // keyboard mapping changed
+        XRefreshKeyboardMapping(&event->xmapping);
+
+        QKeyMapper::changeKeyboard();
+        return 0;
+    }
+
+    if (!widget) {                                // don't know this windows
+        QWidget* popup = QApplication::activePopupWidget();
+        if (popup) {
+
+            /*
+              That is more than suboptimal. The real solution should
+              do some keyevent and buttonevent translation, so that
+              the popup still continues to work as the user expects.
+              Unfortunately this translation is currently only
+              possible with a known widget. I'll change that soon
+              (Matthias).
+            */
+
+            // Danger - make sure we don't lock the server
+            switch (event->type) {
+            case ButtonPress:
+            case ButtonRelease:
+            case XKeyPress:
+            case XKeyRelease:
+                do {
+                    popup->close();
+                } while ((popup = qApp->activePopupWidget()));
+                return 1;
+            }
+        }
+        return -1;
+    }
+
+    if (event->type == XKeyPress || event->type == XKeyRelease)
+        widget = keywidget; // send XKeyEvents through keywidget->x11Event()
+
+    if (app_do_modal)                                // modal event handling
+        if (!qt_try_modal(widget, event)) {
+            if (event->type == ClientMessage && !widget->x11Event(event))
+                x11ClientMessage(widget, event, true);
+            return 1;
+        }
+
+
+    if (widget->x11Event(event))                // send through widget filter
+        return 1;
+#if !defined (QT_NO_TABLET)
+    if (!qt_xdnd_dragging) {
+        QTabletDeviceDataList *tablets = qt_tablet_devices();
+        for (int i = 0; i < tablets->size(); ++i) {
+            QTabletDeviceData &tab = tablets->operator [](i);
+            if (event->type == tab.xinput_motion
+            || event->type == tab.xinput_button_release
+            || event->type == tab.xinput_button_press
+            || event->type == tab.xinput_proximity_in
+            || event->type == tab.xinput_proximity_out) {
+                widget->translateXinputEvent(event, &tab);
+                return 0;
+            }
+        }
+    }
+#endif
+
+#ifndef QT_NO_XRANDR
+    if (X11->use_xrandr && event->type == (X11->xrandr_eventbase + RRScreenChangeNotify)) {
+        // update Xlib internals with the latest screen configuration
+        X11->ptrXRRUpdateConfiguration(event);
+
+        // update the size for desktop widget
+        int scr = X11->ptrXRRRootToScreen(X11->display, event->xany.window);
+        QDesktopWidget *desktop = QApplication::desktop();
+        QWidget *w = desktop->screen(scr);
+        QSize oldSize(w->size());
+        w->data->crect.setWidth(DisplayWidth(X11->display, scr));
+        w->data->crect.setHeight(DisplayHeight(X11->display, scr));
+        QResizeEvent e(w->size(), oldSize);
+        QApplication::sendEvent(w, &e);
+        if (w != desktop)
+            QApplication::sendEvent(desktop, &e);
+    }
+#endif // QT_NO_XRANDR
+
+#ifndef QT_NO_XFIXES
+    if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) {
+        XFixesSelectionNotifyEvent *req = reinterpret_cast<XFixesSelectionNotifyEvent *>(event);
+
+        // compress all XFixes events related to this selection
+        // we don't want to handle old SelectionNotify events.
+        qt_xfixes_selection_event_data xfixes_event;
+        xfixes_event.selection = req->selection;
+        for (XEvent ev;;) {
+            if (!XCheckIfEvent(X11->display, &ev, &qt_xfixes_scanner, (XPointer)&xfixes_event))
+                break;
+        }
+
+        if (req->selection == ATOM(CLIPBOARD)) {
+            if (qt_xfixes_clipboard_changed(req->owner, req->selection_timestamp)) {
+                emit clipboard()->changed(QClipboard::Clipboard);
+                emit clipboard()->dataChanged();
+            }
+        } else if (req->selection == XA_PRIMARY) {
+            if (qt_xfixes_selection_changed(req->owner, req->selection_timestamp)) {
+                emit clipboard()->changed(QClipboard::Selection);
+                emit clipboard()->selectionChanged();
+            }
+        }
+    }
+#endif // QT_NO_XFIXES
+
+    switch (event->type) {
+
+    case ButtonRelease:                        // mouse event
+        if (!d->inPopupMode() && !QWidget::mouseGrabber() && pressed_window != widget->internalWinId()
+            && (widget = (QETWidget*) QWidget::find((WId)pressed_window)) == 0)
+            break;
+        // fall through intended
+    case ButtonPress:
+        if (event->xbutton.root != RootWindow(X11->display, widget->x11Info().screen())
+            && ! qt_xdnd_dragging) {
+            while (activePopupWidget())
+                activePopupWidget()->close();
+            return 1;
+        }
+        if (event->type == ButtonPress)
+            qt_net_update_user_time(widget->window(), X11->userTime);
+        // fall through intended
+    case MotionNotify:
+#if !defined(QT_NO_TABLET)
+        if (!qt_tabletChokeMouse) {
+#endif
+            if (widget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
+                QPoint pos(event->xbutton.x, event->xbutton.y);
+                pos = widget->d_func()->mapFromWS(pos);
+                QWidget *window = widget->window();
+                pos = widget->mapTo(window, pos);
+                if (QWidget *child = window->childAt(pos)) {
+                    widget = static_cast<QETWidget *>(child);
+                    pos = child->mapFrom(window, pos);
+                    event->xbutton.x = pos.x();
+                    event->xbutton.y = pos.y();
+                }
+            }
+            widget->translateMouseEvent(event);
+#if !defined(QT_NO_TABLET)
+        } else {
+            qt_tabletChokeMouse = false;
+        }
+#endif
+        break;
+
+    case XKeyPress:                                // keyboard event
+        qt_net_update_user_time(widget->window(), X11->userTime);
+        // fallthrough intended
+    case XKeyRelease:
+        {
+            if (keywidget && keywidget->isEnabled()) { // should always exist
+                // qDebug("sending key event");
+                qt_keymapper_private()->translateKeyEvent(keywidget, event, grabbed);
+            }
+            break;
+        }
+
+    case GraphicsExpose:
+    case Expose:                                // paint event
+        widget->translatePaintEvent(event);
+        break;
+
+    case ConfigureNotify:                        // window move/resize event
+        if (event->xconfigure.event == event->xconfigure.window)
+            widget->translateConfigEvent(event);
+        break;
+
+    case XFocusIn: {                                // got focus
+        if ((widget->windowType() == Qt::Desktop))
+            break;
+        if (d->inPopupMode()) // some delayed focus event to ignore
+            break;
+        if (!widget->isWindow())
+            break;
+        if (event->xfocus.detail != NotifyAncestor &&
+            event->xfocus.detail != NotifyInferior &&
+            event->xfocus.detail != NotifyNonlinear)
+            break;
+        setActiveWindow(widget);
+        if (X11->focus_model == QX11Data::FM_PointerRoot) {
+            // We got real input focus from somewhere, but we were in PointerRoot
+            // mode, so we don't trust this event.  Check the focus model to make
+            // sure we know what focus mode we are using...
+            qt_check_focus_model();
+        }
+    }
+        break;
+
+    case XFocusOut:                                // lost focus
+        if ((widget->windowType() == Qt::Desktop))
+            break;
+        if (!widget->isWindow())
+            break;
+        if (event->xfocus.mode == NotifyGrab) {
+            qt_xfocusout_grab_counter++;
+            break;
+        }
+        if (event->xfocus.detail != NotifyAncestor &&
+            event->xfocus.detail != NotifyNonlinearVirtual &&
+            event->xfocus.detail != NotifyNonlinear)
+            break;
+        if (!d->inPopupMode() && widget == QApplicationPrivate::active_window) {
+            XEvent ev;
+            bool focus_will_change = false;
+            if (XCheckTypedEvent(X11->display, XFocusIn, &ev)) {
+                // we're about to get an XFocusIn, if we know we will
+                // get a new active window, we don't want to set the
+                // active window to 0 now
+                QWidget *w2 = QWidget::find(ev.xany.window);
+                if (w2
+                    && w2->windowType() != Qt::Desktop
+                    && !d->inPopupMode() // some delayed focus event to ignore
+                    && w2->isWindow()
+                    && (ev.xfocus.detail == NotifyAncestor
+                        || ev.xfocus.detail == NotifyInferior
+                        || ev.xfocus.detail == NotifyNonlinear))
+                    focus_will_change = true;
+
+                XPutBackEvent(X11->display, &ev);
+            }
+            if (!focus_will_change)
+                setActiveWindow(0);
+        }
+        break;
+
+    case EnterNotify: {                        // enter window
+        if (QWidget::mouseGrabber() && (!d->inPopupMode() || widget->window() != activePopupWidget()))
+            break;
+        if ((event->xcrossing.mode != NotifyNormal
+             && event->xcrossing.mode != NotifyUngrab)
+            || event->xcrossing.detail == NotifyVirtual
+            || event->xcrossing.detail == NotifyNonlinearVirtual)
+            break;
+        if (event->xcrossing.focus &&
+            !(widget->windowType() == Qt::Desktop) && !widget->isActiveWindow()) {
+            if (X11->focus_model == QX11Data::FM_Unknown) // check focus model
+                qt_check_focus_model();
+            if (X11->focus_model == QX11Data::FM_PointerRoot) // PointerRoot mode
+                setActiveWindow(widget);
+        }
+
+        if (qt_button_down && !d->inPopupMode())
+            break;
+
+        QWidget *alien = widget->childAt(widget->d_func()->mapFromWS(QPoint(event->xcrossing.x,
+                                                                            event->xcrossing.y)));
+        QWidget *enter = alien ? alien : widget;
+        QWidget *leave = 0;
+        if (qt_last_mouse_receiver && !qt_last_mouse_receiver->internalWinId())
+            leave = qt_last_mouse_receiver;
+        else
+            leave = QWidget::find(curWin);
+
+        // ### Alien: enter/leave might be wrong here with overlapping siblings
+        // if the enter widget is native and stacked under a non-native widget.
+        QApplicationPrivate::dispatchEnterLeave(enter, leave);
+        curWin = widget->internalWinId();
+        qt_last_mouse_receiver = enter;
+        if (!d->inPopupMode() || widget->window() == activePopupWidget())
+            widget->translateMouseEvent(event); //we don't get MotionNotify, emulate it
+    }
+        break;
+    case LeaveNotify: {                        // leave window
+        QWidget *mouseGrabber = QWidget::mouseGrabber();
+        if (mouseGrabber && !d->inPopupMode())
+            break;
+        if (curWin && widget->internalWinId() != curWin)
+            break;
+        if ((event->xcrossing.mode != NotifyNormal
+            && event->xcrossing.mode != NotifyUngrab)
+            || event->xcrossing.detail == NotifyInferior)
+            break;
+        if (!(widget->windowType() == Qt::Desktop))
+            widget->translateMouseEvent(event); //we don't get MotionNotify, emulate it
+
+        QWidget* enter = 0;
+        QPoint enterPoint;
+        XEvent ev;
+        while (XCheckMaskEvent(X11->display, EnterWindowMask | LeaveWindowMask , &ev)
+               && !qt_x11EventFilter(&ev)) {
+            QWidget* event_widget = QWidget::find(ev.xcrossing.window);
+            if(event_widget && event_widget->x11Event(&ev))
+                break;
+            if (ev.type == LeaveNotify
+                || (ev.xcrossing.mode != NotifyNormal
+                    && ev.xcrossing.mode != NotifyUngrab)
+                || ev.xcrossing.detail == NotifyVirtual
+                || ev.xcrossing.detail == NotifyNonlinearVirtual)
+                continue;
+            enter = event_widget;
+            if (enter)
+                enterPoint = enter->d_func()->mapFromWS(QPoint(ev.xcrossing.x, ev.xcrossing.y));
+            if (ev.xcrossing.focus &&
+                enter && !(enter->windowType() == Qt::Desktop) && !enter->isActiveWindow()) {
+                if (X11->focus_model == QX11Data::FM_Unknown) // check focus model
+                    qt_check_focus_model();
+                if (X11->focus_model == QX11Data::FM_PointerRoot) // PointerRoot mode
+                    setActiveWindow(enter);
+            }
+            break;
+        }
+
+        if ((! enter || (enter->windowType() == Qt::Desktop)) &&
+            event->xcrossing.focus && widget == QApplicationPrivate::active_window &&
+            X11->focus_model == QX11Data::FM_PointerRoot // PointerRoot mode
+            ) {
+            setActiveWindow(0);
+        }
+
+        if (qt_button_down && !d->inPopupMode())
+            break;
+
+        if (!curWin)
+            QApplicationPrivate::dispatchEnterLeave(widget, 0);
+
+        if (enter) {
+            QWidget *alienEnter = enter->childAt(enterPoint);
+            if (alienEnter)
+                enter = alienEnter;
+        }
+
+        QWidget *leave = qt_last_mouse_receiver ? qt_last_mouse_receiver : widget;
+        QWidget *activePopupWidget = qApp->activePopupWidget();
+
+        if (mouseGrabber && activePopupWidget && leave == activePopupWidget)
+            enter = mouseGrabber;
+        else if (enter != widget && mouseGrabber) {
+            if (!widget->rect().contains(widget->d_func()->mapFromWS(QPoint(event->xcrossing.x,
+                                                                            event->xcrossing.y))))
+                break;
+        }
+
+        QApplicationPrivate::dispatchEnterLeave(enter, leave);
+        qt_last_mouse_receiver = enter;
+
+        if (enter && QApplicationPrivate::tryModalHelper(enter, 0)) {
+            QWidget *nativeEnter = enter->internalWinId() ? enter : enter->nativeParentWidget();
+            curWin = nativeEnter->internalWinId();
+            static_cast<QETWidget *>(nativeEnter)->translateMouseEvent(&ev); //we don't get MotionNotify, emulate it
+        } else {
+            curWin = 0;
+            qt_last_mouse_receiver = 0;
+        }
+    }
+        break;
+
+    case UnmapNotify:                                // window hidden
+        if (widget->isWindow()) {
+            Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
+            widget->d_func()->topData()->waitingForMapNotify = 0;
+
+            if (widget->windowType() != Qt::Popup && !widget->testAttribute(Qt::WA_DontShowOnScreen)) {
+                widget->setAttribute(Qt::WA_Mapped, false);
+                if (widget->isVisible()) {
+                    widget->d_func()->topData()->spont_unmapped = 1;
+                    QHideEvent e;
+                    QApplication::sendSpontaneousEvent(widget, &e);
+                    widget->d_func()->hideChildren(true);
+                }
+            }
+
+            if (!widget->d_func()->topData()->validWMState && X11->deferred_map.removeAll(widget))
+                widget->doDeferredMap();
+        }
+        break;
+
+    case MapNotify:                                // window shown
+        if (widget->isWindow()) {
+            widget->d_func()->topData()->waitingForMapNotify = 0;
+
+            if (widget->windowType() != Qt::Popup) {
+                widget->setAttribute(Qt::WA_Mapped);
+                if (widget->d_func()->topData()->spont_unmapped) {
+                    widget->d_func()->topData()->spont_unmapped = 0;
+                    widget->d_func()->showChildren(true);
+                    QShowEvent e;
+                    QApplication::sendSpontaneousEvent(widget, &e);
+
+                    // show() must have been called on this widget in
+                    // order to reach this point, but we could have
+                    // cleared these 2 attributes in case something
+                    // previously forced us into WithdrawnState
+                    // (e.g. kdocker)
+                    widget->setAttribute(Qt::WA_WState_ExplicitShowHide, true);
+                    widget->setAttribute(Qt::WA_WState_Visible, true);
+                }
+            }
+        }
+        break;
+
+    case ClientMessage:                        // client message
+        return x11ClientMessage(widget,event,False);
+
+    case ReparentNotify: {                      // window manager reparents
+        // compress old reparent events to self
+        XEvent ev;
+        while (XCheckTypedWindowEvent(X11->display,
+                                      widget->effectiveWinId(),
+                                      ReparentNotify,
+                                      &ev)) {
+            if (ev.xreparent.window != ev.xreparent.event) {
+                XPutBackEvent(X11->display, &ev);
+                break;
+            }
+        }
+        if (widget->isWindow()) {
+            QTLWExtra *topData = widget->d_func()->topData();
+
+            // store the parent. Useful for many things, embedding for instance.
+            topData->parentWinId = event->xreparent.parent;
+
+            // the widget frame strut should also be invalidated
+            widget->data->fstrut_dirty = 1;
+
+            // work around broken window managers... if we get a
+            // ReparentNotify before the MapNotify, we assume that
+            // we're being managed by a reparenting window
+            // manager.
+            //
+            // however, the WM_STATE property may not have been set
+            // yet, but we are going to assume that it will
+            // be... otherwise we could try to map again after getting
+            // an UnmapNotify... which could then, in turn, trigger a
+            // race in the window manager which causes the window to
+            // disappear when it really should be hidden.
+            if (topData->waitingForMapNotify && !topData->validWMState) {
+                topData->waitingForMapNotify = 0;
+                topData->validWMState = 1;
+            }
+
+            if (X11->focus_model != QX11Data::FM_Unknown) {
+                // toplevel reparented...
+                QWidget *newparent = QWidget::find(event->xreparent.parent);
+                if (! newparent || (newparent->windowType() == Qt::Desktop)) {
+                    // we dont' know about the new parent (or we've been
+                    // reparented to root), perhaps a window manager
+                    // has been (re)started?  reset the focus model to unknown
+                    X11->focus_model = QX11Data::FM_Unknown;
+                }
+            }
+        }
+        break;
+    }
+    case SelectionRequest: {
+        XSelectionRequestEvent *req = &event->xselectionrequest;
+        if (! req)
+            break;
+
+        if (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)) {
+            X11->xdndHandleSelectionRequest(req);
+
+        } else if (qt_clipboard) {
+            QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
+            QApplication::sendSpontaneousEvent(qt_clipboard, &e);
+        }
+        break;
+    }
+    case SelectionClear: {
+        XSelectionClearEvent *req = &event->xselectionclear;
+        // don't deliver dnd events to the clipboard, it gets confused
+        if (! req || (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)))
+            break;
+
+        if (qt_clipboard && !X11->use_xfixes) {
+            QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
+            QApplication::sendSpontaneousEvent(qt_clipboard, &e);
+        }
+        break;
+    }
+
+    case SelectionNotify: {
+        XSelectionEvent *req = &event->xselection;
+        // don't deliver dnd events to the clipboard, it gets confused
+        if (! req || (ATOM(XdndSelection) && req->selection == ATOM(XdndSelection)))
+            break;
+
+        if (qt_clipboard) {
+            QClipboardEvent e(reinterpret_cast<QEventPrivate*>(event));
+            QApplication::sendSpontaneousEvent(qt_clipboard, &e);
+        }
+        break;
+    }
+    case PropertyNotify:
+        // some properties changed
+        if (event->xproperty.window == QX11Info::appRootWindow(0)) {
+            // root properties for the first screen
+            if (!X11->use_xfixes && event->xproperty.atom == ATOM(_QT_CLIPBOARD_SENTINEL)) {
+                if (qt_check_clipboard_sentinel()) {
+                    emit clipboard()->changed(QClipboard::Clipboard);
+                    emit clipboard()->dataChanged();
+                }
+            } else if (!X11->use_xfixes && event->xproperty.atom == ATOM(_QT_SELECTION_SENTINEL)) {
+                if (qt_check_selection_sentinel()) {
+                    emit clipboard()->changed(QClipboard::Selection);
+                    emit clipboard()->selectionChanged();
+                }
+            } else if (QApplicationPrivate::obey_desktop_settings) {
+                if (event->xproperty.atom == ATOM(RESOURCE_MANAGER))
+                    qt_set_x11_resources();
+                else if (event->xproperty.atom == ATOM(_QT_SETTINGS_TIMESTAMP))
+                    qt_set_x11_resources();
+            }
+        }
+        if (event->xproperty.window == QX11Info::appRootWindow()) {
+            // root properties for the default screen
+            if (event->xproperty.atom == ATOM(_QT_INPUT_ENCODING)) {
+                qt_set_input_encoding();
+            } else if (event->xproperty.atom == ATOM(_NET_SUPPORTED)) {
+                qt_get_net_supported();
+            } else if (event->xproperty.atom == ATOM(_NET_VIRTUAL_ROOTS)) {
+                qt_get_net_virtual_roots();
+            } else if (event->xproperty.atom == ATOM(_NET_WORKAREA)) {
+                qt_desktopwidget_update_workarea();
+            }
+        } else if (widget) {
+            widget->translatePropertyEvent(event);
+        }  else {
+            return -1; // don't know this window
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return 0;
+}
+
+bool QApplication::x11EventFilter(XEvent *)
+{
+    return false;
+}
+
+
+
+/*****************************************************************************
+  Modal widgets; Since Xlib has little support for this we roll our own
+  modal widget mechanism.
+  A modal widget without a parent becomes application-modal.
+  A modal widget with a parent becomes modal to its parent and grandparents..
+
+  QApplicationPrivate::enterModal()
+        Enters modal state
+        Arguments:
+            QWidget *widget        A modal widget
+
+  QApplicationPrivate::leaveModal()
+        Leaves modal state for a widget
+        Arguments:
+            QWidget *widget        A modal widget
+ *****************************************************************************/
+
+bool QApplicationPrivate::modalState()
+{
+    return app_do_modal;
+}
+
+void QApplicationPrivate::enterModal_sys(QWidget *widget)
+{
+    if (!qt_modal_stack)
+        qt_modal_stack = new QWidgetList;
+
+    QWidget *leave = qt_last_mouse_receiver;
+    if (!leave)
+        leave = QWidget::find((WId)curWin);
+    QApplicationPrivate::dispatchEnterLeave(0, leave);
+    qt_modal_stack->insert(0, widget);
+    app_do_modal = true;
+    curWin = 0;
+    qt_last_mouse_receiver = 0;
+}
+
+void QApplicationPrivate::leaveModal_sys(QWidget *widget)
+{
+    if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
+        if (qt_modal_stack->isEmpty()) {
+            delete qt_modal_stack;
+            qt_modal_stack = 0;
+            QPoint p(QCursor::pos());
+            QWidget* w = QApplication::widgetAt(p.x(), p.y());
+            QWidget *leave = qt_last_mouse_receiver;
+            if (!leave)
+                leave = QWidget::find((WId)curWin);
+            if (QWidget *grabber = QWidget::mouseGrabber()) {
+                w = grabber;
+                if (leave == w)
+                    leave = 0;
+            }
+            QApplicationPrivate::dispatchEnterLeave(w, leave); // send synthetic enter event
+            curWin = w ? w->effectiveWinId() : 0;
+            qt_last_mouse_receiver = w;
+        }
+    }
+    app_do_modal = qt_modal_stack != 0;
+}
+
+bool qt_try_modal(QWidget *widget, XEvent *event)
+{
+    if (qt_xdnd_dragging) {
+        // allow mouse events while DnD is active
+        switch (event->type) {
+        case ButtonPress:
+        case ButtonRelease:
+        case MotionNotify:
+            return true;
+        default:
+            break;
+        }
+    }
+
+    // allow mouse release events to be sent to widgets that have been pressed
+    if (event->type == ButtonRelease) {
+        QWidget *alienWidget = widget->childAt(widget->mapFromGlobal(QPoint(event->xbutton.x_root,
+                                                                            event->xbutton.y_root)));
+        if (widget == qt_button_down || (alienWidget && alienWidget == qt_button_down))
+            return true;
+    }
+
+    if (QApplicationPrivate::tryModalHelper(widget))
+        return true;
+
+    // disallow mouse/key events
+    switch (event->type) {
+    case ButtonPress:
+    case ButtonRelease:
+    case MotionNotify:
+    case XKeyPress:
+    case XKeyRelease:
+    case EnterNotify:
+    case LeaveNotify:
+    case ClientMessage:
+        return false;
+    default:
+        break;
+    }
+
+    return true;
+}
+
+
+/*****************************************************************************
+  Popup widget mechanism
+
+  openPopup()
+        Adds a widget to the list of popup widgets
+        Arguments:
+            QWidget *widget        The popup widget to be added
+
+  closePopup()
+        Removes a widget from the list of popup widgets
+        Arguments:
+            QWidget *widget        The popup widget to be removed
+ *****************************************************************************/
+
+
+static int openPopupCount = 0;
+void QApplicationPrivate::openPopup(QWidget *popup)
+{
+    Q_Q(QApplication);
+    openPopupCount++;
+    if (!QApplicationPrivate::popupWidgets) {                        // create list
+        QApplicationPrivate::popupWidgets = new QWidgetList;
+    }
+    QApplicationPrivate::popupWidgets->append(popup);                // add to end of list
+    Display *dpy = X11->display;
+    if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()){ // grab mouse/keyboard
+        Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
+        int r = XGrabKeyboard(dpy, popup->effectiveWinId(), false,
+                              GrabModeAsync, GrabModeAsync, X11->time);
+        if ((popupGrabOk = (r == GrabSuccess))) {
+            r = XGrabPointer(dpy, popup->effectiveWinId(), true,
+                             (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
+                              | EnterWindowMask | LeaveWindowMask | PointerMotionMask),
+                             GrabModeAsync, GrabModeAsync, XNone, XNone, X11->time);
+            if (!(popupGrabOk = (r == GrabSuccess))) {
+                // transfer grab back to the keyboard grabber if any
+                if (QWidgetPrivate::keyboardGrabber != 0)
+                    QWidgetPrivate::keyboardGrabber->grabKeyboard();
+                else
+                    XUngrabKeyboard(dpy, X11->time);
+            }
+        }
+    }
+
+    // popups are not focus-handled by the window system (the first
+    // popup grabbed the keyboard), so we have to do that manually: A
+    // new popup gets the focus
+    if (popup->focusWidget()) {
+        popup->focusWidget()->setFocus(Qt::PopupFocusReason);
+    } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
+        if (QWidget *fw = QApplication::focusWidget()) {
+            QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
+            q->sendEvent(fw, &e);
+        }
+    }
+}
+
+void QApplicationPrivate::closePopup(QWidget *popup)
+{
+    Q_Q(QApplication);
+    if (!QApplicationPrivate::popupWidgets)
+        return;
+    QApplicationPrivate::popupWidgets->removeAll(popup);
+    if (popup == qt_popup_down) {
+        qt_button_down = 0;
+        qt_popup_down = 0;
+    }
+    if (QApplicationPrivate::popupWidgets->count() == 0) {                // this was the last popup
+        delete QApplicationPrivate::popupWidgets;
+        QApplicationPrivate::popupWidgets = 0;
+        if (!qt_nograb() && popupGrabOk) {        // grabbing not disabled
+            Display *dpy = X11->display;
+            if (popup->geometry().contains(QPoint(mouseGlobalXPos, mouseGlobalYPos))
+                || popup->testAttribute(Qt::WA_NoMouseReplay)) {
+                // mouse release event or inside
+                replayPopupMouseEvent = false;
+            } else {                                // mouse press event
+                mouseButtonPressTime -= 10000;        // avoid double click
+                replayPopupMouseEvent = true;
+            }
+            // transfer grab back to mouse grabber if any, otherwise release the grab
+            if (QWidgetPrivate::mouseGrabber != 0)
+                QWidgetPrivate::mouseGrabber->grabMouse();
+            else
+                XUngrabPointer(dpy, X11->time);
+
+            // transfer grab back to keyboard grabber if any, otherwise release the grab
+            if (QWidgetPrivate::keyboardGrabber != 0)
+                QWidgetPrivate::keyboardGrabber->grabKeyboard();
+            else
+                XUngrabKeyboard(dpy, X11->time);
+
+            XFlush(dpy);
+        }
+        if (QApplicationPrivate::active_window) {
+            if (QWidget *fw = QApplicationPrivate::active_window->focusWidget()) {
+                if (fw != QApplication::focusWidget()) {
+                    fw->setFocus(Qt::PopupFocusReason);
+                } else {
+                    QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
+                    q->sendEvent(fw, &e);
+                }
+            }
+        }
+    } else {
+        // popups are not focus-handled by the window system (the
+        // first popup grabbed the keyboard), so we have to do that
+        // manually: A popup was closed, so the previous popup gets
+        // the focus.
+        QWidget* aw = QApplicationPrivate::popupWidgets->last();
+        if (QWidget *fw = aw->focusWidget())
+            fw->setFocus(Qt::PopupFocusReason);
+
+        // regrab the keyboard and mouse in case 'popup' lost the grab
+        if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()){ // grab mouse/keyboard
+            Display *dpy = X11->display;
+            Q_ASSERT(aw->testAttribute(Qt::WA_WState_Created));
+            int r = XGrabKeyboard(dpy, aw->effectiveWinId(), false,
+                                  GrabModeAsync, GrabModeAsync, X11->time);
+            if ((popupGrabOk = (r == GrabSuccess))) {
+                r = XGrabPointer(dpy, aw->effectiveWinId(), true,
+                                 (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
+                                  | EnterWindowMask | LeaveWindowMask | PointerMotionMask),
+                                 GrabModeAsync, GrabModeAsync, XNone, XNone, X11->time);
+                if (!(popupGrabOk = (r == GrabSuccess))) {
+                    // transfer grab back to keyboard grabber
+                    if (QWidgetPrivate::keyboardGrabber != 0)
+                        QWidgetPrivate::keyboardGrabber->grabKeyboard();
+                    else
+                        XUngrabKeyboard(dpy, X11->time);
+                }
+            }
+        }
+    }
+}
+
+/*****************************************************************************
+  Event translation; translates X11 events to Qt events
+ *****************************************************************************/
+
+//
+// Mouse event translation
+//
+// Xlib doesn't give mouse double click events, so we generate them by
+// comparing window, time and position between two mouse press events.
+//
+
+static Qt::MouseButtons translateMouseButtons(int s)
+{
+    Qt::MouseButtons ret = 0;
+    if (s & Button1Mask)
+        ret |= Qt::LeftButton;
+    if (s & Button2Mask)
+        ret |= Qt::MidButton;
+    if (s & Button3Mask)
+        ret |= Qt::RightButton;
+    return ret;
+}
+
+Qt::KeyboardModifiers QX11Data::translateModifiers(int s)
+{
+    Qt::KeyboardModifiers ret = 0;
+    if (s & ShiftMask)
+        ret |= Qt::ShiftModifier;
+    if (s & ControlMask)
+        ret |= Qt::ControlModifier;
+    if (s & qt_alt_mask)
+        ret |= Qt::AltModifier;
+    if (s & qt_meta_mask)
+        ret |= Qt::MetaModifier;
+    if (s & qt_mode_switch_mask)
+        ret |= Qt::GroupSwitchModifier;
+    return ret;
+}
+
+bool QETWidget::translateMouseEvent(const XEvent *event)
+{
+    if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
+        Q_ASSERT(internalWinId());
+
+    Q_D(QWidget);
+    QEvent::Type type;                                // event parameters
+    QPoint pos;
+    QPoint globalPos;
+    Qt::MouseButton button = Qt::NoButton;
+    Qt::MouseButtons buttons;
+    Qt::KeyboardModifiers modifiers;
+    XEvent nextEvent;
+
+    if (qt_sm_blockUserInput) // block user interaction during session management
+        return true;
+
+    if (event->type == MotionNotify) { // mouse move
+        if (event->xmotion.root != RootWindow(X11->display, x11Info().screen()) &&
+            ! qt_xdnd_dragging)
+            return false;
+
+        XMotionEvent lastMotion = event->xmotion;
+        while(XPending(X11->display))  { // compress mouse moves
+            XNextEvent(X11->display, &nextEvent);
+            if (nextEvent.type == ConfigureNotify
+                || nextEvent.type == PropertyNotify
+                || nextEvent.type == Expose
+                || nextEvent.type == GraphicsExpose
+                || nextEvent.type == NoExpose
+                || nextEvent.type == KeymapNotify
+                || ((nextEvent.type == EnterNotify || nextEvent.type == LeaveNotify)
+                    && qt_button_down == this)
+                || (nextEvent.type == ClientMessage
+                    && (nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE) ||
+                    (nextEvent.xclient.message_type == ATOM(WM_PROTOCOLS) &&
+                     (Atom)nextEvent.xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST))))) {
+                qApp->x11ProcessEvent(&nextEvent);
+                continue;
+            } else if (nextEvent.type != MotionNotify ||
+                       nextEvent.xmotion.window != event->xmotion.window ||
+                       nextEvent.xmotion.state != event->xmotion.state) {
+                XPutBackEvent(X11->display, &nextEvent);
+                break;
+            }
+            if (!qt_x11EventFilter(&nextEvent)
+                && !x11Event(&nextEvent)) // send event through filter
+                lastMotion = nextEvent.xmotion;
+            else
+                break;
+        }
+        type = QEvent::MouseMove;
+        pos.rx() = lastMotion.x;
+        pos.ry() = lastMotion.y;
+        pos = d->mapFromWS(pos);
+        globalPos.rx() = lastMotion.x_root;
+        globalPos.ry() = lastMotion.y_root;
+        buttons = translateMouseButtons(lastMotion.state);
+        modifiers = X11->translateModifiers(lastMotion.state);
+        if (qt_button_down && !buttons)
+            qt_button_down = 0;
+    } else if (event->type == EnterNotify || event->type == LeaveNotify) {
+        XEvent *xevent = (XEvent *)event;
+        //unsigned int xstate = event->xcrossing.state;
+        type = QEvent::MouseMove;
+        pos.rx() = xevent->xcrossing.x;
+        pos.ry() = xevent->xcrossing.y;
+        pos = d->mapFromWS(pos);
+        globalPos.rx() = xevent->xcrossing.x_root;
+        globalPos.ry() = xevent->xcrossing.y_root;
+        buttons = translateMouseButtons(xevent->xcrossing.state);
+        modifiers = X11->translateModifiers(xevent->xcrossing.state);
+        if (qt_button_down && !buttons)
+            qt_button_down = 0;
+        if (qt_button_down)
+            return true;
+    } else {                                        // button press or release
+        pos.rx() = event->xbutton.x;
+        pos.ry() = event->xbutton.y;
+        pos = d->mapFromWS(pos);
+        globalPos.rx() = event->xbutton.x_root;
+        globalPos.ry() = event->xbutton.y_root;
+        buttons = translateMouseButtons(event->xbutton.state);
+        modifiers = X11->translateModifiers(event->xbutton.state);
+        switch (event->xbutton.button) {
+        case Button1: button = Qt::LeftButton; break;
+        case Button2: button = Qt::MidButton; break;
+        case Button3: button = Qt::RightButton; break;
+        case Button4:
+        case Button5:
+        case 6:
+        case 7:
+            // the fancy mouse wheel.
+
+            // We are only interested in ButtonPress.
+            if (event->type == ButtonPress){
+                // compress wheel events (the X Server will simply
+                // send a button press for each single notch,
+                // regardless whether the application can catch up
+                // or not)
+                int delta = 1;
+                XEvent xevent;
+                while (XCheckTypedWindowEvent(X11->display, effectiveWinId(), ButtonPress, &xevent)){
+                    if (xevent.xbutton.button != event->xbutton.button){
+                        XPutBackEvent(X11->display, &xevent);
+                        break;
+                    }
+                    delta++;
+                }
+
+                // the delta is defined as multiples of
+                // WHEEL_DELTA, which is set to 120. Future wheels
+                // may offer a finer-resolution. A positive delta
+                // indicates forward rotation, a negative one
+                // backward rotation respectively.
+                int btn = event->xbutton.button;
+                delta *= 120 * ((btn == Button4 || btn == 6) ? 1 : -1);
+                bool hor = (((btn == Button4 || btn == Button5) && (modifiers & Qt::AltModifier)) ||
+                            (btn == 6 || btn == 7));
+                translateWheelEvent(globalPos.x(), globalPos.y(), delta, buttons,
+                                    modifiers, (hor) ? Qt::Horizontal: Qt::Vertical);
+            }
+            return true;
+        case 8: button = Qt::XButton1; break;
+        case 9: button = Qt::XButton2; break;
+        }
+        if (event->type == ButtonPress) {        // mouse button pressed
+            buttons |= button;
+#if defined(Q_OS_IRIX) && !defined(QT_NO_TABLET)
+            QTabletDeviceDataList *tablets = qt_tablet_devices();
+            for (int i = 0; i < tablets->size(); ++i) {
+                QTabletDeviceData &tab = tablets->operator[](i);
+                XEvent myEv;
+                if (XCheckTypedEvent(X11->display, tab.xinput_button_press, &myEv)) {
+                        if (translateXinputEvent(&myEv, &tab)) {
+                            //Spontaneous event sent.  Check if we need to continue.
+                            if (qt_tabletChokeMouse) {
+                                qt_tabletChokeMouse = false;
+                                return false;
+                            }
+                        }
+                }
+            }
+#endif
+            if (!qt_button_down) {
+                qt_button_down = childAt(pos);        //magic for masked widgets
+                if (!qt_button_down)
+                    qt_button_down = this;
+            }
+            if (mouseActWindow == event->xbutton.window &&
+                mouseButtonPressed == button &&
+                (long)event->xbutton.time -(long)mouseButtonPressTime
+                < QApplication::doubleClickInterval() &&
+                qAbs(event->xbutton.x - mouseXPos) < 5 &&
+                qAbs(event->xbutton.y - mouseYPos) < 5) {
+                type = QEvent::MouseButtonDblClick;
+                mouseButtonPressTime -= 2000;        // no double-click next time
+            } else {
+                type = QEvent::MouseButtonPress;
+                mouseButtonPressTime = event->xbutton.time;
+            }
+            mouseButtonPressed = button;        // save event params for
+            mouseXPos = event->xbutton.x;                // future double click tests
+            mouseYPos = event->xbutton.y;
+            mouseGlobalXPos = globalPos.x();
+            mouseGlobalYPos = globalPos.y();
+        } else {                                // mouse button released
+            buttons &= ~button;
+#if defined(Q_OS_IRIX) && !defined(QT_NO_TABLET)
+            QTabletDeviceDataList *tablets = qt_tablet_devices();
+            for (int i = 0; i < tablets->size(); ++i) {
+                QTabletDeviceData &tab = tablets->operator[](i);
+                XEvent myEv;
+                if (XCheckTypedEvent(X11->display, tab.xinput_button_press, &myEv)) {
+                        if (translateXinputEvent(&myEv, &tab)) {
+                            //Spontaneous event sent.  Check if we need to continue.
+                            if (qt_tabletChokeMouse) {
+                                qt_tabletChokeMouse = false;
+                                return false;
+                            }
+                        }
+                }
+            }
+#endif
+            type = QEvent::MouseButtonRelease;
+        }
+    }
+    mouseActWindow = effectiveWinId();                        // save some event params
+    mouseButtonState = buttons;
+    if (type == 0)                                // don't send event
+        return false;
+
+    if (qApp->d_func()->inPopupMode()) {                        // in popup mode
+        QWidget *activePopupWidget = qApp->activePopupWidget();
+        QWidget *popup = qApp->activePopupWidget();
+        if (popup != this) {
+            if (event->type == LeaveNotify)
+                return false;
+            if ((windowType() == Qt::Popup) && rect().contains(pos) && 0)
+                popup = this;
+            else                                // send to last popup
+                pos = popup->mapFromGlobal(globalPos);
+        }
+        bool releaseAfter = false;
+        QWidget *popupChild  = popup->childAt(pos);
+
+        if (popup != qt_popup_down){
+            qt_button_down = 0;
+            qt_popup_down = 0;
+        }
+
+        switch (type) {
+        case QEvent::MouseButtonPress:
+        case QEvent::MouseButtonDblClick:
+            qt_button_down = popupChild;
+            qt_popup_down = popup;
+            break;
+        case QEvent::MouseButtonRelease:
+            releaseAfter = true;
+            break;
+        default:
+            break;                                // nothing for mouse move
+        }
+
+        int oldOpenPopupCount = openPopupCount;
+
+        if (popup->isEnabled()) {
+            // deliver event
+            replayPopupMouseEvent = false;
+            QWidget *receiver = popup;
+            QPoint widgetPos = pos;
+            if (qt_button_down)
+                receiver = qt_button_down;
+            else if (popupChild)
+                receiver = popupChild;
+            if (receiver != popup)
+                widgetPos = receiver->mapFromGlobal(globalPos);
+            QWidget *alien = childAt(mapFromGlobal(globalPos));
+            QMouseEvent e(type, widgetPos, globalPos, button, buttons, modifiers);
+            QApplicationPrivate::sendMouseEvent(receiver, &e, alien, this, &qt_button_down, qt_last_mouse_receiver);
+        } else {
+            // close disabled popups when a mouse button is pressed or released
+            switch (type) {
+            case QEvent::MouseButtonPress:
+            case QEvent::MouseButtonDblClick:
+            case QEvent::MouseButtonRelease:
+                popup->close();
+                break;
+            default:
+                break;
+            }
+        }
+
+        if (qApp->activePopupWidget() != activePopupWidget
+            && replayPopupMouseEvent) {
+            // the active popup was closed, replay the mouse event
+            if (!(windowType() == Qt::Popup)) {
+#if 1
+                qt_button_down = 0;
+#else
+                if (buttons == button)
+                    qt_button_down = this;
+                QMouseEvent e(type, mapFromGlobal(globalPos), globalPos, button,
+                              buttons, modifiers);
+                QApplication::sendSpontaneousEvent(this, &e);
+
+                if (type == QEvent::MouseButtonPress
+                    && button == Qt::RightButton
+                    && (openPopupCount == oldOpenPopupCount)) {
+                    QContextMenuEvent e(QContextMenuEvent::Mouse, mapFromGlobal(globalPos),
+                                        globalPos, modifiers);
+                    QApplication::sendSpontaneousEvent(this, &e);
+                }
+#endif
+            }
+            replayPopupMouseEvent = false;
+        } else if (type == QEvent::MouseButtonPress
+                   && button == Qt::RightButton
+                   && (openPopupCount == oldOpenPopupCount)) {
+            QWidget *popupEvent = popup;
+            if (qt_button_down)
+                popupEvent = qt_button_down;
+            else if(popupChild)
+                popupEvent = popupChild;
+            QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, modifiers);
+            QApplication::sendSpontaneousEvent(popupEvent, &e);
+        }
+
+        if (releaseAfter) {
+            qt_button_down = 0;
+            qt_popup_down = 0;
+        }
+    } else {
+        QWidget *alienWidget = childAt(pos);
+        QWidget *widget = QApplicationPrivate::pickMouseReceiver(this, globalPos, pos, type, buttons,
+                                                                 qt_button_down, alienWidget);
+        if (!widget) {
+            if (type == QEvent::MouseButtonRelease)
+                QApplicationPrivate::mouse_buttons &= ~button;
+            return false; // don't send event
+        }
+
+        int oldOpenPopupCount = openPopupCount;
+        QMouseEvent e(type, pos, globalPos, button, buttons, modifiers);
+        QApplicationPrivate::sendMouseEvent(widget, &e, alienWidget, this, &qt_button_down,
+                                            qt_last_mouse_receiver);
+        if (type == QEvent::MouseButtonPress
+            && button == Qt::RightButton
+            && (openPopupCount == oldOpenPopupCount)) {
+            QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos, modifiers);
+            QApplication::sendSpontaneousEvent(widget, &e);
+        }
+    }
+    return true;
+}
+
+
+//
+// Wheel event translation
+//
+bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta,
+                                    Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
+                                    Qt::Orientation orient)
+{
+    const QPoint globalPos = QPoint(global_x, global_y);
+    QPoint pos = mapFromGlobal(globalPos);
+    QWidget *widget = childAt(pos);
+    if (!widget)
+        widget = this;
+    else if (!widget->internalWinId())
+        pos = widget->mapFromGlobal(globalPos);
+
+#ifdef ALIEN_DEBUG
+        qDebug() << "QETWidget::translateWheelEvent: receiver:" << widget << "pos:" << pos;
+#endif
+
+    // send the event to the widget or its ancestors
+    {
+        QWidget* popup = qApp->activePopupWidget();
+        if (popup && window() != popup)
+            popup->close();
+        QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
+        if (QApplication::sendSpontaneousEvent(widget, &e))
+            return true;
+    }
+
+    // send the event to the widget that has the focus or its ancestors, if different
+    if (widget != qApp->focusWidget() && (widget = qApp->focusWidget())) {
+        if (widget && !widget->internalWinId())
+            pos = widget->mapFromGlobal(globalPos);
+        QWidget* popup = qApp->activePopupWidget();
+        if (popup && widget != popup)
+            popup->hide();
+        QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
+        if (QApplication::sendSpontaneousEvent(widget, &e))
+            return true;
+    }
+    return false;
+}
+
+
+//
+// XInput Translation Event
+//
+#if !defined (QT_NO_TABLET)
+
+#if !defined (Q_OS_IRIX)
+void fetchWacomToolId(int &deviceType, qint64 &serialId)
+{
+    if (ptrWacomConfigInit == 0) // we actually have the lib
+        return;
+    WACOMCONFIG *config = ptrWacomConfigInit(X11->display, 0);
+    if (config == 0)
+        return;
+    WACOMDEVICE *device = ptrWacomConfigOpenDevice (config, wacomDeviceName()->constData());
+    if (device == 0)
+        return;
+    unsigned keys[1];
+    int serialInt;
+    ptrWacomConfigGetRawParam (device, XWACOM_PARAM_TOOLSERIAL, &serialInt, 1, keys);
+    serialId = serialInt;
+    int toolId;
+    ptrWacomConfigGetRawParam (device, XWACOM_PARAM_TOOLID, &toolId, 1, keys);
+    switch(toolId) {
+    case 0x007: /* Mouse 4D and 2D */
+    case 0x017: /* Intuos3 2D Mouse */
+    case 0x094:
+    case 0x09c:
+        deviceType = QTabletEvent::FourDMouse;
+        break;
+    case 0x096: /* Lens cursor */
+    case 0x097: /* Intuos3 Lens cursor */
+        deviceType = QTabletEvent::Puck;
+        break;
+    case 0x0fa:
+    case 0x81b: /* Intuos3 Classic Pen Eraser */
+    case 0x82a: /* Eraser */
+    case 0x82b: /* Intuos3 Grip Pen Eraser */
+    case 0x85a:
+    case 0x91a:
+    case 0x91b: /* Intuos3 Airbrush Eraser */
+    case 0xd1a:
+        deviceType = QTabletEvent::XFreeEraser;
+        break;
+    case 0x112:
+    case 0x912:
+    case 0x913: /* Intuos3 Airbrush */
+    case 0xd12:
+        deviceType = QTabletEvent::Airbrush;
+        break;
+    case 0x012:
+    case 0x022:
+    case 0x032:
+    case 0x801: /* Intuos3 Inking pen */
+    case 0x812: /* Inking pen */
+    case 0x813: /* Intuos3 Classic Pen */
+    case 0x822: /* Pen */
+    case 0x823: /* Intuos3 Grip Pen */
+    case 0x832: /* Stroke pen */
+    case 0x842:
+    case 0x852:
+    case 0x885: /* Intuos3 Marker Pen */
+    default: /* Unknown tool */
+        deviceType = QTabletEvent::Stylus;
+    }
+
+    /* Close device and return */
+    ptrWacomConfigCloseDevice (device);
+    ptrWacomConfigTerm(config);
+}
+#endif
+
+struct qt_tablet_motion_data
+{
+    bool filterByWidget;
+    const QWidget *widget;
+    const QWidget *etWidget;
+    int tabletMotionType;
+    bool error; // found a reason to stop searching
+};
+
+static Bool qt_mouseMotion_scanner(Display *, XEvent *event, XPointer arg)
+{
+    qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
+    if (data->error)
+        return false;
+
+    if (event->type == MotionNotify)
+        return true;
+
+    data->error = event->type != data->tabletMotionType; // we stop compression when another event gets in between.
+    return false;
+}
+
+static Bool qt_tabletMotion_scanner(Display *, XEvent *event, XPointer arg)
+{
+    qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
+    if (data->error)
+        return false;
+    if (event->type == data->tabletMotionType) {
+        const XDeviceMotionEvent *const motion = reinterpret_cast<const XDeviceMotionEvent*>(event);
+        if (data->filterByWidget) {
+            const QPoint curr(motion->x, motion->y);
+            const QWidget *w = data->etWidget;
+            const QWidget *const child = w->childAt(curr);
+            if (child) {
+                w = child;
+            }
+            if (w == data->widget)
+                return true;
+        } else {
+            return true;
+        }
+    }
+
+    data->error = event->type != MotionNotify; // we stop compression when another event gets in between.
+    return false;
+}
+
+bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet)
+{
+#if defined (Q_OS_IRIX)
+    // Wacom has put defines in their wacom.h file so it would be quite wise
+    // to use them, need to think of a decent way of not using
+    // it when it doesn't exist...
+    XDeviceState *s;
+    XInputClass *iClass;
+    XValuatorState *vs;
+    int j;
+#endif
+
+    Q_ASSERT(tablet != 0);
+
+    QWidget *w = this;
+    QPoint global,
+        curr;
+    QPointF hiRes;
+    qreal pressure = 0;
+    int xTilt = 0,
+        yTilt = 0,
+        z = 0;
+    qreal tangentialPressure = 0;
+    qreal rotation = 0;
+    int deviceType = QTabletEvent::NoDevice;
+    int pointerType = QTabletEvent::UnknownPointer;
+    const XDeviceMotionEvent *motion = 0;
+    XDeviceButtonEvent *button = 0;
+    const XProximityNotifyEvent *proximity = 0;
+    QEvent::Type t;
+    Qt::KeyboardModifiers modifiers = 0;
+#if !defined (Q_OS_IRIX)
+    XID device_id;
+#endif
+
+    if (ev->type == tablet->xinput_motion) {
+        motion = reinterpret_cast<const XDeviceMotionEvent*>(ev);
+        t = QEvent::TabletMove;
+        global = QPoint(motion->x_root, motion->y_root);
+        curr = QPoint(motion->x, motion->y);
+#if !defined (Q_OS_IRIX)
+        device_id = motion->deviceid;
+#endif
+    } else if (ev->type == tablet->xinput_button_press || ev->type == tablet->xinput_button_release) {
+        if (ev->type == tablet->xinput_button_press) {
+            t = QEvent::TabletPress;
+        } else {
+            t = QEvent::TabletRelease;
+        }
+        button = (XDeviceButtonEvent*)ev;
+
+        global = QPoint(button->x_root, button->y_root);
+        curr = QPoint(button->x, button->y);
+#if !defined (Q_OS_IRIX)
+        device_id = button->deviceid;
+#endif
+    } else { // Proximity
+        if (ev->type == tablet->xinput_proximity_in)
+            t = QEvent::TabletEnterProximity;
+        else
+            t = QEvent::TabletLeaveProximity;
+        proximity = (const XProximityNotifyEvent*)ev;
+#if !defined (Q_OS_IRIX)
+        device_id = proximity->deviceid;
+#endif
+    }
+
+    qint64 uid = 0;
+#if defined (Q_OS_IRIX)
+    QRect screenArea = qApp->desktop()->screenGeometry(this);
+    s = XQueryDeviceState(X11->display, static_cast<XDevice *>(tablet->device));
+    if (!s)
+        return false;
+    iClass = s->data;
+    for (j = 0; j < s->num_classes; j++) {
+        if (iClass->c_class == ValuatorClass) {
+            vs = reinterpret_cast<XValuatorState *>(iClass);
+            // figure out what device we have, based on bitmasking...
+            if (vs->valuators[WAC_TRANSDUCER_I]
+                 & WAC_TRANSDUCER_PROX_MSK) {
+                switch (vs->valuators[WAC_TRANSDUCER_I]
+                         & WAC_TRANSDUCER_MSK) {
+                case WAC_PUCK_ID:
+                    pointerType = QTabletEvent::Puck;
+                    break;
+                case WAC_STYLUS_ID:
+                    pointerType = QTabletEvent::Pen;
+                    break;
+                case WAC_ERASER_ID:
+                    pointerType = QTabletEvent::Eraser;
+                    break;
+                }
+                // Get a Unique Id for the device, Wacom gives us this ability
+                uid = vs->valuators[WAC_TRANSDUCER_I] & WAC_TRANSDUCER_ID_MSK;
+                uid = (uid << 24) | vs->valuators[WAC_SERIAL_NUM_I];
+                switch (WAC_TRANSDUCER_I & 0x0F0600) {
+                case 0x080200:
+                    deviceType = QTabletEvent::Stylus;
+                    break;
+                case 0x090200:
+                    deviceType = QTabletEvent::Airbrush;
+                    break;
+                case 0x000400:
+                    deviceType = QTabletEvent::FourDMouse;
+                    break;
+                case 0x000600:
+                    deviceType = QTabletEvent::Puck;
+                    break;
+                case 0x080400:
+                    deviceType = QTabletEvent::RotationStylus;
+                    break;
+                }
+            } else {
+                pointerType = QTabletEvent::UnknownPointer;
+                deviceType = QTabletEvent::NoDevice;
+                uid = 0;
+            }
+
+            if (!proximity) {
+                // apparently Wacom needs a cast for the +/- values to make sense
+                xTilt = short(vs->valuators[WAC_XTILT_I]);
+                yTilt = short(vs->valuators[WAC_YTILT_I]);
+                pressure = vs->valuators[WAC_PRESSURE_I];
+                if (deviceType == QTabletEvent::FourDMouse
+                        || deviceType == QTabletEvent::RotationStylus) {
+                    rotation = vs->valuators[WAC_ROTATION_I] / 64.0;
+                    if (deviceType == QTabletEvent::FourDMouse)
+                        z = vs->valuators[WAC_ZCOORD_I];
+                } else if (deviceType == QTabletEvent::Airbrush) {
+                    tangentialPressure = vs->valuators[WAC_TAN_PRESSURE_I]
+                                            / qreal(tablet->maxTanPressure - tablet->minTanPressure);
+                }
+
+                hiRes = tablet->scaleCoord(vs->valuators[WAC_XCOORD_I], vs->valuators[WAC_YCOORD_I],
+                                           screenArea.x(), screenArea.width(),
+                                           screenArea.y(), screenArea.height());
+            }
+            break;
+        }
+        iClass = reinterpret_cast<XInputClass*>(reinterpret_cast<char*>(iClass) + iClass->length);
+    }
+    XFreeDeviceState(s);
+#else
+    QTabletDeviceDataList *tablet_list = qt_tablet_devices();
+    for (int i = 0; i < tablet_list->size(); ++i) {
+        const QTabletDeviceData &t = tablet_list->at(i);
+        if (device_id == static_cast<XDevice *>(t.device)->device_id) {
+            deviceType = t.deviceType;
+            if (t.deviceType == QTabletEvent::XFreeEraser) {
+                deviceType = QTabletEvent::Stylus;
+                pointerType = QTabletEvent::Eraser;
+            } else if (t.deviceType == QTabletEvent::Stylus) {
+                pointerType = QTabletEvent::Pen;
+            }
+            break;
+        }
+    }
+
+    fetchWacomToolId(deviceType, uid);
+
+    QRect screenArea = qApp->desktop()->rect();
+    if (motion) {
+        xTilt = (short) motion->axis_data[3];
+        yTilt = (short) motion->axis_data[4];
+        rotation = ((short) motion->axis_data[5]) / 64.0;
+        pressure = (short) motion->axis_data[2];
+        modifiers = X11->translateModifiers(motion->state);
+        hiRes = tablet->scaleCoord(motion->axis_data[0], motion->axis_data[1],
+                                    screenArea.x(), screenArea.width(),
+                                    screenArea.y(), screenArea.height());
+    } else if (button) {
+        xTilt = (short) button->axis_data[3];
+        yTilt = (short) button->axis_data[4];
+        rotation = ((short) button->axis_data[5]) / 64.0;
+        pressure = (short) button->axis_data[2];
+        modifiers = X11->translateModifiers(button->state);
+        hiRes = tablet->scaleCoord(button->axis_data[0], button->axis_data[1],
+                                    screenArea.x(), screenArea.width(),
+                                    screenArea.y(), screenArea.height());
+    } else if (proximity) {
+        pressure = 0;
+        modifiers = 0;
+    }
+    if (deviceType == QTabletEvent::Airbrush) {
+        tangentialPressure = rotation;
+        rotation = 0.;
+    }
+#endif
+
+    if (tablet->widgetToGetPress) {
+        w = tablet->widgetToGetPress;
+    } else {
+        QWidget *child = w->childAt(curr);
+        if (child)
+            w = child;
+    }
+    curr = w->mapFromGlobal(global);
+
+    if (t == QEvent::TabletPress) {
+        tablet->widgetToGetPress = w;
+    } else if (t == QEvent::TabletRelease && tablet->widgetToGetPress) {
+        w = tablet->widgetToGetPress;
+        curr = w->mapFromGlobal(global);
+        tablet->widgetToGetPress = 0;
+    }
+
+    QTabletEvent e(t, curr, global, hiRes,
+                   deviceType, pointerType,
+                   qreal(pressure / qreal(tablet->maxPressure - tablet->minPressure)),
+                   xTilt, yTilt, tangentialPressure, rotation, z, modifiers, uid);
+    if (proximity) {
+        QApplication::sendSpontaneousEvent(qApp, &e);
+    } else {
+        QApplication::sendSpontaneousEvent(w, &e);
+        const bool accepted = e.isAccepted();
+        if (!accepted && ev->type == tablet->xinput_motion) {
+            // If the widget does not accept tablet events, we drop the next ones from the event queue
+            // for this widget so it is not overloaded with the numerous tablet events.
+            qt_tablet_motion_data tabletMotionData;
+            tabletMotionData.tabletMotionType = tablet->xinput_motion;
+            tabletMotionData.widget = w;
+            tabletMotionData.etWidget = this;
+            // if nothing is pressed, the events are filtered by position
+            tabletMotionData.filterByWidget = (tablet->widgetToGetPress == 0);
+
+            bool reinsertMouseEvent = false;
+            XEvent mouseMotionEvent;
+            while (true) {
+                // Find first mouse event since we expect them in pairs inside Qt
+                tabletMotionData.error =false;
+                if (XCheckIfEvent(X11->display, &mouseMotionEvent, &qt_mouseMotion_scanner, (XPointer) &tabletMotionData)) {
+                    reinsertMouseEvent = true;
+                } else {
+                    break;
+                }
+
+                // Now discard any duplicate tablet events.
+                tabletMotionData.error = false;
+                XEvent dummy;
+                while (XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) {
+                    // just discard the event
+                }
+            }
+
+            if (reinsertMouseEvent) {
+                XPutBackEvent(X11->display, &mouseMotionEvent);
+            }
+        }
+    }
+    return true;
+}
+#endif
+
+bool QETWidget::translatePropertyEvent(const XEvent *event)
+{
+    Q_D(QWidget);
+    if (!isWindow()) return true;
+
+    Atom ret;
+    int format, e;
+    unsigned char *data = 0;
+    unsigned long nitems, after;
+
+    if (event->xproperty.atom == ATOM(_KDE_NET_WM_FRAME_STRUT)) {
+        this->data->fstrut_dirty = 1;
+
+        if (event->xproperty.state == PropertyNewValue) {
+            e = XGetWindowProperty(X11->display, event->xproperty.window, ATOM(_KDE_NET_WM_FRAME_STRUT),
+                                   0, 4, // struts are 4 longs
+                                   False, XA_CARDINAL, &ret, &format, &nitems, &after, &data);
+
+            if (e == Success && ret == XA_CARDINAL &&
+                format == 32 && nitems == 4) {
+                long *strut = (long *) data;
+                d->topData()->frameStrut.setCoords(strut[0], strut[2], strut[1], strut[3]);
+                this->data->fstrut_dirty = 0;
+            }
+        }
+    } else if (event->xproperty.atom == ATOM(_NET_WM_STATE)) {
+        bool max = false;
+        bool full = false;
+        Qt::WindowStates oldState = Qt::WindowStates(this->data->window_state);
+
+        if (event->xproperty.state == PropertyNewValue) {
+            // using length of 1024 should be safe for all current and
+            // possible NET states...
+            e = XGetWindowProperty(X11->display, event->xproperty.window, ATOM(_NET_WM_STATE), 0, 1024,
+                                   False, XA_ATOM, &ret, &format, &nitems, &after, &data);
+
+            if (e == Success && ret == XA_ATOM && format == 32 && nitems > 0) {
+                Atom *states = (Atom *) data;
+
+                unsigned long i;
+                uint maximized = 0;
+                for (i = 0; i < nitems; i++) {
+                    if (states[i] == ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
+                        maximized |= 1;
+                    else if (states[i] == ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
+                        maximized |= 2;
+                    else if (states[i] == ATOM(_NET_WM_STATE_FULLSCREEN))
+                        full = true;
+                }
+                if (maximized == 3) {
+                    // only set maximized if both horizontal and vertical properties are set
+                    max = true;
+                }
+            }
+        }
+
+        bool send_event = false;
+
+        if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
+            && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))) {
+            if (max && !isMaximized()) {
+                this->data->window_state = this->data->window_state | Qt::WindowMaximized;
+                send_event = true;
+            } else if (!max && isMaximized()) {
+                this->data->window_state &= ~Qt::WindowMaximized;
+                send_event = true;
+            }
+        }
+
+        if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
+            if (full && !isFullScreen()) {
+                this->data->window_state = this->data->window_state | Qt::WindowFullScreen;
+                send_event = true;
+            } else if (!full && isFullScreen()) {
+                this->data->window_state &= ~Qt::WindowFullScreen;
+                send_event = true;
+            }
+        }
+
+        if (send_event) {
+            QWindowStateChangeEvent e(oldState);
+            QApplication::sendSpontaneousEvent(this, &e);
+        }
+    } else if (event->xproperty.atom == ATOM(WM_STATE)) {
+        // the widget frame strut should also be invalidated
+        this->data->fstrut_dirty = 1;
+
+        if (event->xproperty.state == PropertyDelete) {
+            // the window manager has removed the WM State property,
+            // so it is now in the withdrawn state (ICCCM 4.1.3.1) and
+            // we are free to reuse this window
+            d->topData()->parentWinId = 0;
+            d->topData()->validWMState = 0;
+            // map the window if we were waiting for a transition to
+            // withdrawn
+            if (X11->deferred_map.removeAll(this)) {
+                doDeferredMap();
+            } else if (isVisible()
+                       && !testAttribute(Qt::WA_Mapped)
+                       && !testAttribute(Qt::WA_OutsideWSRange)) {
+                // so that show() will work again. As stated in the
+                // ICCCM section 4.1.4: "Only the client can effect a
+                // transition into or out of the Withdrawn state.",
+                // but apparently this particular window manager
+                // doesn't seem to care
+                setAttribute(Qt::WA_WState_ExplicitShowHide, false);
+                setAttribute(Qt::WA_WState_Visible, false);
+            }
+        } else {
+            // the window manager has changed the WM State property...
+            // we are wanting to see if we are withdrawn so that we
+            // can reuse this window...
+            e = XGetWindowProperty(X11->display, internalWinId(), ATOM(WM_STATE), 0, 2, False,
+                                   ATOM(WM_STATE), &ret, &format, &nitems, &after, &data);
+
+            if (e == Success && ret == ATOM(WM_STATE) && format == 32 && nitems > 0) {
+                long *state = (long *) data;
+                switch (state[0]) {
+                case WithdrawnState:
+                    // if we are in the withdrawn state, we are free
+                    // to reuse this window provided we remove the
+                    // WM_STATE property (ICCCM 4.1.3.1)
+                    XDeleteProperty(X11->display, internalWinId(), ATOM(WM_STATE));
+
+                    // set the parent id to zero, so that show() will
+                    // work again
+                    d->topData()->parentWinId = 0;
+                    d->topData()->validWMState = 0;
+                    // map the window if we were waiting for a
+                    // transition to withdrawn
+                    if (X11->deferred_map.removeAll(this)) {
+                        doDeferredMap();
+                    } else if (isVisible()
+                               && !testAttribute(Qt::WA_Mapped)
+                               && !testAttribute(Qt::WA_OutsideWSRange)) {
+                        // so that show() will work again. As stated
+                        // in the ICCCM section 4.1.4: "Only the
+                        // client can effect a transition into or out
+                        // of the Withdrawn state.", but apparently
+                        // this particular window manager doesn't seem
+                        // to care
+                        setAttribute(Qt::WA_WState_ExplicitShowHide, false);
+                        setAttribute(Qt::WA_WState_Visible, false);
+                    }
+                    break;
+
+                case IconicState:
+                    d->topData()->validWMState = 1;
+                    if (!isMinimized()) {
+                        // window was minimized
+                        this->data->window_state = this->data->window_state | Qt::WindowMinimized;
+                        QWindowStateChangeEvent e(Qt::WindowStates(this->data->window_state & ~Qt::WindowMinimized));
+                        QApplication::sendSpontaneousEvent(this, &e);
+                    }
+                    break;
+
+                default:
+                    d->topData()->validWMState = 1;
+                    if (isMinimized()) {
+                        // window was un-minimized
+                        this->data->window_state &= ~Qt::WindowMinimized;
+                        QWindowStateChangeEvent e(Qt::WindowStates(this->data->window_state | Qt::WindowMinimized));
+                        QApplication::sendSpontaneousEvent(this, &e);
+                    }
+                    break;
+                }
+            }
+        }
+    } else if (event->xproperty.atom == ATOM(_NET_WM_WINDOW_OPACITY)) {
+        // the window opacity was changed
+        if (event->xproperty.state == PropertyNewValue) {
+            e = XGetWindowProperty(event->xclient.display,
+                                   event->xclient.window,
+                                   ATOM(_NET_WM_WINDOW_OPACITY),
+                                   0, 1, False, XA_CARDINAL,
+                                   &ret, &format, &nitems, &after, &data);
+
+            if (e == Success && ret == XA_CARDINAL && format == 32 && nitems == 1
+                && after == 0 && data) {
+                ulong value = *(ulong*)(data);
+                d->topData()->opacity = uint(value >> 24);
+            }
+        } else
+            d->topData()->opacity = 255;
+    }
+
+    if (data)
+        XFree(data);
+
+    return true;
+}
+
+
+//
+// Paint event translation
+//
+// When receiving many expose events, we compress them (union of all expose
+// rectangles) into one event which is sent to the widget.
+
+struct PaintEventInfo {
+    Window window;
+};
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static Bool isPaintOrScrollDoneEvent(Display *, XEvent *ev, XPointer a)
+{
+    PaintEventInfo *info = (PaintEventInfo *)a;
+    if (ev->type == Expose || ev->type == GraphicsExpose
+        || (ev->type == ClientMessage && ev->xclient.message_type == ATOM(_QT_SCROLL_DONE)))
+    {
+        if (ev->xexpose.window == info->window)
+            return True;
+    }
+    return False;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+
+
+static
+bool translateBySips(QWidget* that, QRect& paintRect)
+{
+    int dx=0, dy=0;
+    int sips=0;
+    for (int i = 0; i < X11->sip_list.size(); ++i) {
+        const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
+        if (sip.scrolled_widget == that) {
+            if (sips) {
+                dx += sip.dx;
+                dy += sip.dy;
+            }
+            sips++;
+        }
+    }
+    if (sips > 1) {
+        paintRect.translate(dx, dy);
+        return true;
+    }
+    return false;
+}
+
+void QETWidget::translatePaintEvent(const XEvent *event)
+{
+    if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
+        Q_ASSERT(internalWinId());
+
+    Q_D(QWidget);
+    QRect  paintRect(event->xexpose.x, event->xexpose.y,
+                     event->xexpose.width, event->xexpose.height);
+    XEvent xevent;
+    PaintEventInfo info;
+    info.window = internalWinId();
+    translateBySips(this, paintRect);
+    paintRect = d->mapFromWS(paintRect);
+
+    QRegion paintRegion = paintRect;
+
+    // WARNING: this is O(number_of_events * number_of_matching_events)
+    while (XCheckIfEvent(X11->display,&xevent,isPaintOrScrollDoneEvent,
+                         (XPointer)&info) &&
+           !qt_x11EventFilter(&xevent)  &&
+           !x11Event(&xevent)) // send event through filter
+    {
+        if (xevent.type == Expose || xevent.type == GraphicsExpose) {
+            QRect exposure(xevent.xexpose.x,
+                           xevent.xexpose.y,
+                           xevent.xexpose.width,
+                           xevent.xexpose.height);
+            translateBySips(this, exposure);
+            exposure = d->mapFromWS(exposure);
+            paintRegion |= exposure;
+        } else {
+            translateScrollDoneEvent(&xevent);
+        }
+    }
+
+    if (!paintRegion.isEmpty() && !testAttribute(Qt::WA_WState_ConfigPending))
+        d->syncBackingStore(paintRegion);
+}
+
+//
+// Scroll-done event translation.
+//
+
+bool QETWidget::translateScrollDoneEvent(const XEvent *event)
+{
+    long id = event->xclient.data.l[0];
+
+    // Remove any scroll-in-progress record for the given id.
+    for (int i = 0; i < X11->sip_list.size(); ++i) {
+        const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
+        if (sip.id == id) {
+            X11->sip_list.removeAt(i);
+            return true;
+        }
+    }
+
+    return false;
+}
+
+//
+// ConfigureNotify (window move and resize) event translation
+
+bool QETWidget::translateConfigEvent(const XEvent *event)
+{
+    Q_ASSERT((!isWindow() && !testAttribute(Qt::WA_NativeWindow)) ? internalWinId() : true);
+
+    Q_D(QWidget);
+    bool wasResize = testAttribute(Qt::WA_WState_ConfigPending); // set in QWidget::setGeometry_sys()
+    setAttribute(Qt::WA_WState_ConfigPending, false);
+
+    if (testAttribute(Qt::WA_OutsideWSRange)) {
+        // discard events for windows that have a geometry X can't handle
+        XEvent xevent;
+        while (XCheckTypedWindowEvent(X11->display,internalWinId(), ConfigureNotify,&xevent) &&
+               !qt_x11EventFilter(&xevent)  &&
+               !x11Event(&xevent)) // send event through filter
+            ;
+        return true;
+    }
+
+    const QSize oldSize = size();
+
+    if (isWindow()) {
+        QPoint newCPos(geometry().topLeft());
+        QSize  newSize(event->xconfigure.width, event->xconfigure.height);
+
+        bool trust = isVisible()
+                     && (d->topData()->parentWinId == XNone ||
+                         d->topData()->parentWinId == QX11Info::appRootWindow());
+
+        if (event->xconfigure.send_event || trust) {
+            // if a ConfigureNotify comes from a real sendevent request, we can
+            // trust its values.
+            newCPos.rx() = event->xconfigure.x + event->xconfigure.border_width;
+            newCPos.ry() = event->xconfigure.y + event->xconfigure.border_width;
+        }
+
+        if (isVisible())
+            QApplication::syncX();
+
+        if (d->extra->compress_events) {
+            // ConfigureNotify compression for faster opaque resizing
+            XEvent otherEvent;
+            while (XCheckTypedWindowEvent(X11->display, internalWinId(), ConfigureNotify,
+                                          &otherEvent)) {
+                if (qt_x11EventFilter(&otherEvent))
+                    continue;
+
+                if (x11Event(&otherEvent))
+                    continue;
+
+                if (otherEvent.xconfigure.event != otherEvent.xconfigure.window)
+                    continue;
+
+                newSize.setWidth(otherEvent.xconfigure.width);
+                newSize.setHeight(otherEvent.xconfigure.height);
+
+                if (otherEvent.xconfigure.send_event || trust) {
+                    newCPos.rx() = otherEvent.xconfigure.x +
+                                   otherEvent.xconfigure.border_width;
+                    newCPos.ry() = otherEvent.xconfigure.y +
+                                   otherEvent.xconfigure.border_width;
+                }
+            }
+#ifndef QT_NO_XSYNC
+            qt_sync_request_event_data sync_event;
+            sync_event.window = internalWinId();
+            for (XEvent ev;;) {
+                if (!XCheckIfEvent(X11->display, &ev, &qt_sync_request_scanner, (XPointer)&sync_event))
+                    break;
+            }
+#endif // QT_NO_XSYNC
+        }
+
+        QRect cr (geometry());
+        if (newCPos != cr.topLeft()) { // compare with cpos (exluding frame)
+            QPoint oldPos = geometry().topLeft();
+            cr.moveTopLeft(newCPos);
+            data->crect = cr;
+            if (isVisible()) {
+                QMoveEvent e(newCPos, oldPos); // pos (including frame), not cpos
+                QApplication::sendSpontaneousEvent(this, &e);
+            } else {
+                setAttribute(Qt::WA_PendingMoveEvent, true);
+            }
+        }
+        if (newSize != cr.size()) { // size changed
+            cr.setSize(newSize);
+            data->crect = cr;
+
+            uint old_state = data->window_state;
+            if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
+                && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
+                data->window_state &= ~Qt::WindowMaximized;
+            if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN)))
+                data->window_state &= ~Qt::WindowFullScreen;
+
+            if (old_state != data->window_state) {
+                QWindowStateChangeEvent e((Qt::WindowStates) old_state);
+                QApplication::sendEvent(this, &e);
+            }
+
+            if (!isVisible())
+                setAttribute(Qt::WA_PendingResizeEvent, true);
+            wasResize = true;
+        }
+
+    } else {
+        XEvent xevent;
+        while (XCheckTypedWindowEvent(X11->display,internalWinId(), ConfigureNotify,&xevent) &&
+               !qt_x11EventFilter(&xevent)  &&
+               !x11Event(&xevent)) // send event through filter
+            ;
+    }
+
+    if (wasResize) {
+        static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
+        if (d->extra->compress_events && !slowResize && !data->in_show && isVisible()) {
+            QApplication::syncX();
+            XEvent otherEvent;
+            while (XCheckTypedWindowEvent(X11->display, internalWinId(), ConfigureNotify, &otherEvent)
+                   && !qt_x11EventFilter(&otherEvent) && !x11Event(&otherEvent)
+                   && otherEvent.xconfigure.event == otherEvent.xconfigure.window) {
+                data->crect.setWidth(otherEvent.xconfigure.width);
+                data->crect.setHeight(otherEvent.xconfigure.height);
+            }
+        }
+
+        if (isVisible() && data->crect.size() != oldSize) {
+            Q_ASSERT(d->extra->topextra);
+            QWidgetBackingStore *bs = d->extra->topextra->backingStore;
+            const bool hasStaticContents = bs && bs->hasStaticContents();
+            // If we have a backing store with static contents, we have to disable the top-level
+            // resize optimization in order to get invalidated regions for resized widgets.
+            // The optimization discards all invalidateBuffer() calls since we're going to
+            // repaint everything anyways, but that's not the case with static contents.
+            if (!slowResize && !hasStaticContents)
+                d->extra->topextra->inTopLevelResize = true;
+            QResizeEvent e(data->crect.size(), oldSize);
+            QApplication::sendSpontaneousEvent(this, &e);
+        }
+
+        const bool waitingForMapNotify = d->extra->topextra && d->extra->topextra->waitingForMapNotify;
+        if (!waitingForMapNotify) {
+            if (d->paintOnScreen()) {
+                QRegion updateRegion(rect());
+                if (testAttribute(Qt::WA_StaticContents))
+                    updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height());
+                d->syncBackingStore(updateRegion);
+            } else {
+                d->syncBackingStore();
+            }
+        }
+
+        if (d->extra && d->extra->topextra)
+            d->extra->topextra->inTopLevelResize = false;
+    }
+#ifndef QT_NO_XSYNC
+    if (QTLWExtra *tlwExtra = d->maybeTopData()) {
+        if (tlwExtra->newCounterValueLo != 0 || tlwExtra->newCounterValueHi != 0) {
+            XSyncValue value;
+            XSyncIntsToValue(&value,
+                             tlwExtra->newCounterValueLo,
+                             tlwExtra->newCounterValueHi);
+
+            XSyncSetCounter(X11->display, tlwExtra->syncUpdateCounter, value);
+            tlwExtra->newCounterValueHi = 0;
+            tlwExtra->newCounterValueLo = 0;
+        }
+    }
+#endif
+    return true;
+}
+
+//
+// Close window event translation.
+//
+bool QETWidget::translateCloseEvent(const XEvent *)
+{
+    Q_D(QWidget);
+    return d->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
+}
+
+
+void QApplication::setCursorFlashTime(int msecs)
+{
+    QApplicationPrivate::cursor_flash_time = msecs;
+}
+
+int QApplication::cursorFlashTime()
+{
+    return QApplicationPrivate::cursor_flash_time;
+}
+
+void QApplication::setDoubleClickInterval(int ms)
+{
+    QApplicationPrivate::mouse_double_click_time = ms;
+}
+
+int QApplication::doubleClickInterval()
+{
+    return QApplicationPrivate::mouse_double_click_time;
+}
+
+void QApplication::setKeyboardInputInterval(int ms)
+{
+    QApplicationPrivate::keyboard_input_time = ms;
+}
+
+int QApplication::keyboardInputInterval()
+{
+    return QApplicationPrivate::keyboard_input_time;
+}
+
+void QApplication::setWheelScrollLines(int n)
+{
+    QApplicationPrivate::wheel_scroll_lines = n;
+}
+
+int QApplication::wheelScrollLines()
+{
+    return QApplicationPrivate::wheel_scroll_lines;
+}
+
+void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
+{
+    switch (effect) {
+    case Qt::UI_AnimateMenu:
+        if (enable) QApplicationPrivate::fade_menu = false;
+        QApplicationPrivate::animate_menu = enable;
+        break;
+    case Qt::UI_FadeMenu:
+        if (enable)
+            QApplicationPrivate::animate_menu = true;
+        QApplicationPrivate::fade_menu = enable;
+        break;
+    case Qt::UI_AnimateCombo:
+        QApplicationPrivate::animate_combo = enable;
+        break;
+    case Qt::UI_AnimateTooltip:
+        if (enable) QApplicationPrivate::fade_tooltip = false;
+        QApplicationPrivate::animate_tooltip = enable;
+        break;
+    case Qt::UI_FadeTooltip:
+        if (enable)
+            QApplicationPrivate::animate_tooltip = true;
+        QApplicationPrivate::fade_tooltip = enable;
+        break;
+    case Qt::UI_AnimateToolBox:
+        QApplicationPrivate::animate_toolbox = enable;
+        break;
+    default:
+        QApplicationPrivate::animate_ui = enable;
+        break;
+    }
+}
+
+bool QApplication::isEffectEnabled(Qt::UIEffect effect)
+{
+    if (QColormap::instance().depth() < 16 || !QApplicationPrivate::animate_ui)
+        return false;
+
+    switch(effect) {
+    case Qt::UI_AnimateMenu:
+        return QApplicationPrivate::animate_menu;
+    case Qt::UI_FadeMenu:
+        return QApplicationPrivate::fade_menu;
+    case Qt::UI_AnimateCombo:
+        return QApplicationPrivate::animate_combo;
+    case Qt::UI_AnimateTooltip:
+        return QApplicationPrivate::animate_tooltip;
+    case Qt::UI_FadeTooltip:
+        return QApplicationPrivate::fade_tooltip;
+    case Qt::UI_AnimateToolBox:
+        return QApplicationPrivate::animate_toolbox;
+    default:
+        return QApplicationPrivate::animate_ui;
+    }
+}
+
+/*****************************************************************************
+  Session management support
+ *****************************************************************************/
+
+#ifndef QT_NO_SESSIONMANAGER
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <X11/SM/SMlib.h>
+QT_END_INCLUDE_NAMESPACE
+
+class QSessionManagerPrivate : public QObjectPrivate
+{
+public:
+    QSessionManagerPrivate(QSessionManager* mgr, QString& id, QString& key)
+        : QObjectPrivate(), sm(mgr), sessionId(id), sessionKey(key),
+            restartHint(QSessionManager::RestartIfRunning), eventLoop(0) {}
+    QSessionManager* sm;
+    QStringList restartCommand;
+    QStringList discardCommand;
+    QString& sessionId;
+    QString& sessionKey;
+    QSessionManager::RestartHint restartHint;
+    QEventLoop *eventLoop;
+};
+
+class QSmSocketReceiver : public QObject
+{
+    Q_OBJECT
+public:
+    QSmSocketReceiver(int socket)
+        {
+            QSocketNotifier* sn = new QSocketNotifier(socket, QSocketNotifier::Read, this);
+            connect(sn, SIGNAL(activated(int)), this, SLOT(socketActivated(int)));
+        }
+
+public slots:
+     void socketActivated(int);
+};
+
+
+static SmcConn smcConnection = 0;
+static bool sm_interactionActive;
+static bool sm_smActive;
+static int sm_interactStyle;
+static int sm_saveType;
+static bool sm_cancel;
+// static bool sm_waitingForPhase2;  ### never used?!?
+static bool sm_waitingForInteraction;
+static bool sm_isshutdown;
+// static bool sm_shouldbefast;  ### never used?!?
+static bool sm_phase2;
+static bool sm_in_phase2;
+
+static QSmSocketReceiver* sm_receiver = 0;
+
+static void resetSmState();
+static void sm_setProperty(const char* name, const char* type,
+                            int num_vals, SmPropValue* vals);
+static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
+                                  int saveType, Bool shutdown , int interactStyle, Bool fast);
+static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData) ;
+static void sm_dieCallback(SmcConn smcConn, SmPointer clientData) ;
+static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData);
+static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer clientData);
+static void sm_interactCallback(SmcConn smcConn, SmPointer clientData);
+static void sm_performSaveYourself(QSessionManagerPrivate*);
+
+static void resetSmState()
+{
+//    sm_waitingForPhase2 = false; ### never used?!?
+    sm_waitingForInteraction = false;
+    sm_interactionActive = false;
+    sm_interactStyle = SmInteractStyleNone;
+    sm_smActive = false;
+    qt_sm_blockUserInput = false;
+    sm_isshutdown = false;
+//    sm_shouldbefast = false; ### never used?!?
+    sm_phase2 = false;
+    sm_in_phase2 = false;
+}
+
+
+// theoretically it's possible to set several properties at once. For
+// simplicity, however, we do just one property at a time
+static void sm_setProperty(const char* name, const char* type,
+                            int num_vals, SmPropValue* vals)
+{
+    if (num_vals) {
+      SmProp prop;
+      prop.name = (char*)name;
+      prop.type = (char*)type;
+      prop.num_vals = num_vals;
+      prop.vals = vals;
+
+      SmProp* props[1];
+      props[0] = &prop;
+      SmcSetProperties(smcConnection, 1, props);
+    }
+    else {
+      char* names[1];
+      names[0] = (char*) name;
+      SmcDeleteProperties(smcConnection, 1, names);
+    }
+}
+
+static void sm_setProperty(const QString& name, const QString& value)
+{
+    QByteArray v = value.toUtf8();
+    SmPropValue prop;
+    prop.length = v.length();
+    prop.value = (SmPointer) v.constData();
+    sm_setProperty(name.toLatin1().data(), SmARRAY8, 1, &prop);
+}
+
+static void sm_setProperty(const QString& name, const QStringList& value)
+{
+    SmPropValue *prop = new SmPropValue[value.count()];
+    int count = 0;
+    QList<QByteArray> vl;
+    for (QStringList::ConstIterator it = value.begin(); it != value.end(); ++it) {
+      prop[count].length = (*it).length();
+      vl.append((*it).toUtf8());
+      prop[count].value = (char*)vl.last().data();
+      ++count;
+    }
+    sm_setProperty(name.toLatin1().data(), SmLISTofARRAY8, count, prop);
+    delete [] prop;
+}
+
+
+// workaround for broken libsm, see below
+struct QT_smcConn {
+    unsigned int save_yourself_in_progress : 1;
+    unsigned int shutdown_in_progress : 1;
+};
+
+static void sm_saveYourselfCallback(SmcConn smcConn, SmPointer clientData,
+                                  int saveType, Bool shutdown , int interactStyle, Bool /*fast*/)
+{
+    if (smcConn != smcConnection)
+        return;
+    sm_cancel = false;
+    sm_smActive = true;
+    sm_isshutdown = shutdown;
+    sm_saveType = saveType;
+    sm_interactStyle = interactStyle;
+//    sm_shouldbefast = fast; ### never used?!?
+
+    // ugly workaround for broken libSM. libSM should do that _before_
+    // actually invoking the callback in sm_process.c
+    ((QT_smcConn*)smcConn)->save_yourself_in_progress = true;
+    if (sm_isshutdown)
+        ((QT_smcConn*)smcConn)->shutdown_in_progress = true;
+
+    sm_performSaveYourself((QSessionManagerPrivate*) clientData);
+    if (!sm_isshutdown) // we cannot expect a confirmation message in that case
+        resetSmState();
+}
+
+static void sm_performSaveYourself(QSessionManagerPrivate* smd)
+{
+    if (sm_isshutdown)
+        qt_sm_blockUserInput = true;
+
+    QSessionManager* sm = smd->sm;
+
+    // generate a new session key
+    timeval tv;
+    gettimeofday(&tv, 0);
+    smd->sessionKey  = QString::number(qulonglong(tv.tv_sec)) + QLatin1Char('_') + QString::number(qulonglong(tv.tv_usec));
+
+    QStringList arguments = qApp->arguments();
+    QString argument0 = arguments.isEmpty() ? qApp->applicationFilePath() : arguments.at(0);
+
+    // tell the session manager about our program in best POSIX style
+    sm_setProperty(QString::fromLatin1(SmProgram), argument0);
+    // tell the session manager about our user as well.
+    struct passwd *entryPtr = 0;
+#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
+    QVarLengthArray<char, 1024> buf(sysconf(_SC_GETPW_R_SIZE_MAX));
+    struct passwd entry;
+    getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr);
+#else
+    entryPtr = getpwuid(geteuid());
+#endif
+    if (entryPtr)
+        sm_setProperty(QString::fromLatin1(SmUserID), QString::fromLatin1(entryPtr->pw_name));
+
+    // generate a restart and discard command that makes sense
+    QStringList restart;
+    restart  << argument0 << QLatin1String("-session")
+             << smd->sessionId + QLatin1Char('_') + smd->sessionKey;
+    if (qstricmp(appName, QX11Info::appClass()) != 0)
+        restart << QLatin1String("-name") << qAppName();
+    sm->setRestartCommand(restart);
+    QStringList discard;
+    sm->setDiscardCommand(discard);
+
+    switch (sm_saveType) {
+    case SmSaveBoth:
+        qApp->commitData(*sm);
+        if (sm_isshutdown && sm_cancel)
+            break; // we cancelled the shutdown, no need to save state
+    // fall through
+    case SmSaveLocal:
+        qApp->saveState(*sm);
+        break;
+    case SmSaveGlobal:
+        qApp->commitData(*sm);
+        break;
+    default:
+        break;
+    }
+
+    if (sm_phase2 && !sm_in_phase2) {
+        SmcRequestSaveYourselfPhase2(smcConnection, sm_saveYourselfPhase2Callback, (SmPointer*) smd);
+        qt_sm_blockUserInput = false;
+    }
+    else {
+        // close eventual interaction monitors and cancel the
+        // shutdown, if required. Note that we can only cancel when
+        // performing a shutdown, it does not work for checkpoints
+        if (sm_interactionActive) {
+            SmcInteractDone(smcConnection, sm_isshutdown && sm_cancel);
+            sm_interactionActive = false;
+        }
+        else if (sm_cancel && sm_isshutdown) {
+            if (sm->allowsErrorInteraction()) {
+                SmcInteractDone(smcConnection, True);
+                sm_interactionActive = false;
+            }
+        }
+
+        // set restart and discard command in session manager
+        sm_setProperty(QString::fromLatin1(SmRestartCommand), sm->restartCommand());
+        sm_setProperty(QString::fromLatin1(SmDiscardCommand), sm->discardCommand());
+
+        // set the restart hint
+        SmPropValue prop;
+        prop.length = sizeof(int);
+        int value = sm->restartHint();
+        prop.value = (SmPointer) &value;
+        sm_setProperty(SmRestartStyleHint, SmCARD8, 1, &prop);
+
+        // we are done
+        SmcSaveYourselfDone(smcConnection, !sm_cancel);
+    }
+}
+
+static void sm_dieCallback(SmcConn smcConn, SmPointer /* clientData */)
+{
+    if (smcConn != smcConnection)
+        return;
+    resetSmState();
+    QEvent quitEvent(QEvent::Quit);
+    QApplication::sendEvent(qApp, &quitEvent);
+}
+
+static void sm_shutdownCancelledCallback(SmcConn smcConn, SmPointer clientData)
+{
+    if (smcConn != smcConnection)
+        return;
+    if (sm_waitingForInteraction)
+        ((QSessionManagerPrivate *) clientData)->eventLoop->exit();
+    resetSmState();
+}
+
+static void sm_saveCompleteCallback(SmcConn smcConn, SmPointer /*clientData */)
+{
+    if (smcConn != smcConnection)
+        return;
+    resetSmState();
+}
+
+static void sm_interactCallback(SmcConn smcConn, SmPointer clientData)
+{
+    if (smcConn != smcConnection)
+        return;
+    if (sm_waitingForInteraction)
+        ((QSessionManagerPrivate *) clientData)->eventLoop->exit();
+}
+
+static void sm_saveYourselfPhase2Callback(SmcConn smcConn, SmPointer clientData)
+{
+    if (smcConn != smcConnection)
+        return;
+    sm_in_phase2 = true;
+    sm_performSaveYourself((QSessionManagerPrivate*) clientData);
+}
+
+
+void QSmSocketReceiver::socketActivated(int)
+{
+    IceProcessMessages(SmcGetIceConnection(smcConnection), 0, 0);
+}
+
+
+#undef Bool
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "qapplication_x11.moc"
+QT_END_INCLUDE_NAMESPACE
+
+QSessionManager::QSessionManager(QApplication * app, QString &id, QString& key)
+    : QObject(*new QSessionManagerPrivate(this, id, key), app)
+{
+    Q_D(QSessionManager);
+    d->restartHint = RestartIfRunning;
+
+    resetSmState();
+    char cerror[256];
+    char* myId = 0;
+    QByteArray b_id = id.toLatin1();
+    char* prevId = b_id.data();
+
+    SmcCallbacks cb;
+    cb.save_yourself.callback = sm_saveYourselfCallback;
+    cb.save_yourself.client_data = (SmPointer) d;
+    cb.die.callback = sm_dieCallback;
+    cb.die.client_data = (SmPointer) d;
+    cb.save_complete.callback = sm_saveCompleteCallback;
+    cb.save_complete.client_data = (SmPointer) d;
+    cb.shutdown_cancelled.callback = sm_shutdownCancelledCallback;
+    cb.shutdown_cancelled.client_data = (SmPointer) d;
+
+    // avoid showing a warning message below
+    if (qgetenv("SESSION_MANAGER").isEmpty())
+        return;
+
+    smcConnection = SmcOpenConnection(0, 0, 1, 0,
+                                       SmcSaveYourselfProcMask |
+                                       SmcDieProcMask |
+                                       SmcSaveCompleteProcMask |
+                                       SmcShutdownCancelledProcMask,
+                                       &cb,
+                                       prevId,
+                                       &myId,
+                                       256, cerror);
+
+    id = QString::fromLatin1(myId);
+    ::free(myId); // it was allocated by C
+
+    QString error = QString::fromLocal8Bit(cerror);
+    if (!smcConnection) {
+        qWarning("Qt: Session management error: %s", qPrintable(error));
+    }
+    else {
+        sm_receiver = new QSmSocketReceiver(IceConnectionNumber(SmcGetIceConnection(smcConnection)));
+    }
+}
+
+QSessionManager::~QSessionManager()
+{
+    if (smcConnection)
+        SmcCloseConnection(smcConnection, 0, 0);
+    smcConnection = 0;
+    delete sm_receiver;
+}
+
+QString QSessionManager::sessionId() const
+{
+    Q_D(const QSessionManager);
+    return d->sessionId;
+}
+
+QString QSessionManager::sessionKey() const
+{
+    Q_D(const QSessionManager);
+    return d->sessionKey;
+}
+
+
+void* QSessionManager::handle() const
+{
+    return (void*) smcConnection;
+}
+
+
+bool QSessionManager::allowsInteraction()
+{
+    Q_D(QSessionManager);
+    if (sm_interactionActive)
+        return true;
+
+    if (sm_waitingForInteraction)
+        return false;
+
+    if (sm_interactStyle == SmInteractStyleAny) {
+        sm_waitingForInteraction =  SmcInteractRequest(smcConnection, SmDialogNormal,
+                                                        sm_interactCallback, (SmPointer*) d);
+    }
+    if (sm_waitingForInteraction) {
+        QEventLoop eventLoop;
+        d->eventLoop = &eventLoop;
+        (void) eventLoop.exec();
+        d->eventLoop = 0;
+
+        sm_waitingForInteraction = false;
+        if (sm_smActive) { // not cancelled
+            sm_interactionActive = true;
+            qt_sm_blockUserInput = false;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool QSessionManager::allowsErrorInteraction()
+{
+    Q_D(QSessionManager);
+    if (sm_interactionActive)
+        return true;
+
+    if (sm_waitingForInteraction)
+        return false;
+
+    if (sm_interactStyle == SmInteractStyleAny || sm_interactStyle == SmInteractStyleErrors) {
+        sm_waitingForInteraction =  SmcInteractRequest(smcConnection, SmDialogError,
+                                                        sm_interactCallback, (SmPointer*) d);
+    }
+    if (sm_waitingForInteraction) {
+        QEventLoop eventLoop;
+        d->eventLoop = &eventLoop;
+        (void) eventLoop.exec();
+        d->eventLoop = 0;
+
+        sm_waitingForInteraction = false;
+        if (sm_smActive) { // not cancelled
+            sm_interactionActive = true;
+            qt_sm_blockUserInput = false;
+            return true;
+        }
+    }
+    return false;
+}
+
+void QSessionManager::release()
+{
+    if (sm_interactionActive) {
+        SmcInteractDone(smcConnection, False);
+        sm_interactionActive = false;
+        if (sm_smActive && sm_isshutdown)
+            qt_sm_blockUserInput = true;
+    }
+}
+
+void QSessionManager::cancel()
+{
+    sm_cancel = true;
+}
+
+void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
+{
+    Q_D(QSessionManager);
+    d->restartHint = hint;
+}
+
+QSessionManager::RestartHint QSessionManager::restartHint() const
+{
+    Q_D(const QSessionManager);
+    return d->restartHint;
+}
+
+void QSessionManager::setRestartCommand(const QStringList& command)
+{
+    Q_D(QSessionManager);
+    d->restartCommand = command;
+}
+
+QStringList QSessionManager::restartCommand() const
+{
+    Q_D(const QSessionManager);
+    return d->restartCommand;
+}
+
+void QSessionManager::setDiscardCommand(const QStringList& command)
+{
+    Q_D(QSessionManager);
+    d->discardCommand = command;
+}
+
+QStringList QSessionManager::discardCommand() const
+{
+    Q_D(const QSessionManager);
+    return d->discardCommand;
+}
+
+void QSessionManager::setManagerProperty(const QString& name, const QString& value)
+{
+    sm_setProperty(name, value);
+}
+
+void QSessionManager::setManagerProperty(const QString& name, const QStringList& value)
+{
+    sm_setProperty(name, value);
+}
+
+bool QSessionManager::isPhase2() const
+{
+    return sm_in_phase2;
+}
+
+void QSessionManager::requestPhase2()
+{
+    sm_phase2 = true;
+}
+
+#endif // QT_NO_SESSIONMANAGER
+
+#if defined(QT_RX71_MULTITOUCH)
+
+static inline int testBit(const char *array, int bit)
+{
+    return (array[bit/8] & (1<<(bit%8)));
+}
+
+static int openRX71Device(const QByteArray &deviceName)
+{
+    int fd = open(deviceName, O_RDONLY | O_NONBLOCK);
+    if (fd == -1) {
+        fd = -errno;
+        return fd;
+    }
+
+    // fetch the event type mask and check that the device reports absolute coordinates
+    char eventTypeMask[(EV_MAX + sizeof(char) - 1) * sizeof(char) + 1];
+    memset(eventTypeMask, 0, sizeof(eventTypeMask));
+    if (ioctl(fd, EVIOCGBIT(0, sizeof(eventTypeMask)), eventTypeMask) < 0) {
+        close(fd);
+        return -1;
+    }
+    if (!testBit(eventTypeMask, EV_ABS)) {
+        close(fd);
+        return -1;
+    }
+
+    // make sure that we can get the absolute X and Y positions from the device
+    char absMask[(ABS_MAX + sizeof(char) - 1) * sizeof(char) + 1];
+    memset(absMask, 0, sizeof(absMask));
+    if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absMask)), absMask) < 0) {
+        close(fd);
+        return -1;
+    }
+    if (!testBit(absMask, ABS_X) || !testBit(absMask, ABS_Y)) {
+        close(fd);
+        return -1;
+    }
+
+    return fd;
+}
+
+void QApplicationPrivate::initializeMultitouch_sys()
+{
+    Q_Q(QApplication);
+
+    QByteArray deviceName = QByteArray("/dev/input/event");
+    int currentDeviceNumber = 0;
+    for (;;) {
+        int fd = openRX71Device(QByteArray(deviceName + QByteArray::number(currentDeviceNumber++)));
+        if (fd == -ENOENT) {
+            // no more devices
+            break;
+        }
+        if (fd < 0) {
+            // not a touch device
+            continue;
+        }
+
+        struct input_absinfo abs_x, abs_y, abs_z;
+        ioctl(fd, EVIOCGABS(ABS_X), &abs_x);
+        ioctl(fd, EVIOCGABS(ABS_Y), &abs_y);
+        ioctl(fd, EVIOCGABS(ABS_Z), &abs_z);
+
+        int deviceNumber = allRX71TouchPoints.count();
+
+        QSocketNotifier *socketNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, q);
+        QObject::connect(socketNotifier, SIGNAL(activated(int)), q, SLOT(_q_readRX71MultiTouchEvents()));
+
+        RX71TouchPointState touchPointState = {
+            socketNotifier,
+            QTouchEvent::TouchPoint(deviceNumber),
+
+            abs_x.minimum, abs_x.maximum, q->desktop()->screenGeometry().width(),
+            abs_y.minimum, abs_y.maximum, q->desktop()->screenGeometry().height(),
+            abs_z.minimum, abs_z.maximum
+        };
+        allRX71TouchPoints.append(touchPointState);
+    }
+
+    hasRX71MultiTouch = allRX71TouchPoints.count() > 1;
+    if (!hasRX71MultiTouch) {
+        for (int i = 0; i < allRX71TouchPoints.count(); ++i) {
+            QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier;
+            close(socketNotifier->socket());
+            delete socketNotifier;
+        }
+        allRX71TouchPoints.clear();
+    }
+}
+
+void QApplicationPrivate::cleanupMultitouch_sys()
+{
+    hasRX71MultiTouch = false;
+    for (int i = 0; i < allRX71TouchPoints.count(); ++i) {
+        QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier;
+        close(socketNotifier->socket());
+        delete socketNotifier;
+    }
+    allRX71TouchPoints.clear();
+}
+
+bool QApplicationPrivate::readRX71MultiTouchEvents(int deviceNumber)
+{
+    RX71TouchPointState &touchPointState = allRX71TouchPoints[deviceNumber];
+    QSocketNotifier *socketNotifier = touchPointState.socketNotifier;
+    int fd = socketNotifier->socket();
+
+    QTouchEvent::TouchPoint &touchPoint = touchPointState.touchPoint;
+
+    bool down = touchPoint.state() != Qt::TouchPointReleased;
+    if (down)
+        touchPoint.setState(Qt::TouchPointStationary);
+
+    bool changed = false;
+    for (;;) {
+        struct input_event inputEvent;
+        int bytesRead = read(fd, &inputEvent, sizeof(inputEvent));
+        if (bytesRead <= 0)
+            break;
+        if (bytesRead != sizeof(inputEvent)) {
+            qWarning("Qt: INTERNAL ERROR: short read in readRX71MultiTouchEvents()");
+            return false;
+        }
+
+        switch (inputEvent.type) {
+        case EV_SYN:
+            changed = true;
+            switch (touchPoint.state()) {
+            case Qt::TouchPointPressed:
+            case Qt::TouchPointReleased:
+                // make sure we don't compress pressed and releases with any other events
+                return changed;
+            default:
+                break;
+            }
+            continue;
+        case EV_KEY:
+        case EV_ABS:
+            break;
+        default:
+            qWarning("Qt: WARNING: unknown event type %d on multitouch device", inputEvent.type);
+            continue;
+        }
+
+        QPointF screenPos = touchPoint.screenPos();
+        switch (inputEvent.code) {
+        case BTN_TOUCH:
+            if (!down && inputEvent.value != 0)
+                touchPoint.setState(Qt::TouchPointPressed);
+            else if (down && inputEvent.value == 0)
+                touchPoint.setState(Qt::TouchPointReleased);
+            break;
+        case ABS_TOOL_WIDTH:
+        case ABS_VOLUME:
+        case ABS_PRESSURE:
+            // ignore for now
+            break;
+        case ABS_X:
+        {
+            qreal newValue = ((qreal(inputEvent.value - touchPointState.minX)
+                              / qreal(touchPointState.maxX - touchPointState.minX))
+                              * touchPointState.scaleX);
+            screenPos.rx() = newValue;
+            touchPoint.setScreenPos(screenPos);
+            break;
+        }
+        case ABS_Y:
+        {
+            qreal newValue = ((qreal(inputEvent.value - touchPointState.minY)
+                              / qreal(touchPointState.maxY - touchPointState.minY))
+                              * touchPointState.scaleY);
+            screenPos.ry() = newValue;
+            touchPoint.setScreenPos(screenPos);
+            break;
+        }
+        case ABS_Z:
+        {
+            // map Z (signal strength) to pressure for now
+            qreal newValue = (qreal(inputEvent.value - touchPointState.minZ)
+                              / qreal(touchPointState.maxZ - touchPointState.minZ));
+            touchPoint.setPressure(newValue);
+            break;
+        }
+        default:
+            qWarning("Qt: WARNING: unknown event code %d on multitouch device", inputEvent.code);
+            continue;
+        }
+    }
+
+    if (down && touchPoint.state() != Qt::TouchPointReleased)
+        touchPoint.setState(changed ? Qt::TouchPointMoved : Qt::TouchPointStationary);
+
+    return changed;
+}
+
+void QApplicationPrivate::_q_readRX71MultiTouchEvents()
+{
+    // read touch events from all devices
+    bool changed = false;
+    for (int i = 0; i < allRX71TouchPoints.count(); ++i)
+        changed = readRX71MultiTouchEvents(i) || changed;
+    if (!changed)
+        return;
+
+    QList<QTouchEvent::TouchPoint> touchPoints;
+    for (int i = 0; i < allRX71TouchPoints.count(); ++i)
+        touchPoints.append(allRX71TouchPoints.at(i).touchPoint);
+
+    translateRawTouchEvent(0, QTouchEvent::TouchScreen, touchPoints);
+}
+
+#else // !QT_RX71_MULTITOUCH
+
+void QApplicationPrivate::initializeMultitouch_sys()
+{ }
+void QApplicationPrivate::cleanupMultitouch_sys()
+{ }
+
+#endif // QT_RX71_MULTITOUCH
+
+QT_END_NAMESPACE