summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qapplication_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qapplication_x11.cpp')
-rw-r--r--src/gui/kernel/qapplication_x11.cpp6254
1 files changed, 0 insertions, 6254 deletions
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
deleted file mode 100644
index 311b147976..0000000000
--- a/src/gui/kernel/qapplication_x11.cpp
+++ /dev/null
@@ -1,6254 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $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/qcrashhandler_p.h>
-#include <private/qcolor_p.h>
-#include <private/qcursor_p.h>
-#include <private/qiconloader_p.h>
-#include <qgtkstyle.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
-
-#ifndef QT_GUI_DOUBLE_CLICK_RADIUS
-#define QT_GUI_DOUBLE_CLICK_RADIUS 5
-#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"
- "ENLIGHTENMENT_DESKTOP\0"
- "_DT_SAVE_MODE\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"
-
- "_NET_ACTIVE_WINDOW\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 old. (before version 0.10)
- "Wacom Stylus\0"
- "Wacom Cursor\0"
- "Wacom Eraser\0"
-
- // Tablet
- "STYLUS\0"
- "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
-
-typedef bool(*QX11FilterFunction)(XEvent *event);
-
-Q_GLOBAL_STATIC(QList<QX11FilterFunction>, x11Filters)
-
-Q_GUI_EXPORT void qt_installX11EventFilter(QX11FilterFunction func)
-{
- Q_ASSERT(func);
-
- if (QList<QX11FilterFunction> *list = x11Filters())
- list->append(func);
-}
-
-Q_GUI_EXPORT void qt_removeX11EventFilter(QX11FilterFunction func)
-{
- Q_ASSERT(func);
-
- if (QList<QX11FilterFunction> *list = x11Filters())
- list->removeOne(func);
-}
-
-
-static bool qt_x11EventFilter(XEvent* ev)
-{
- long unused;
- if (qApp->filterEvent(ev, &unused))
- return true;
- if (const QList<QX11FilterFunction> *list = x11Filters()) {
- for (QList<QX11FilterFunction>::const_iterator it = list->constBegin(); it != list->constEnd(); ++it) {
- if ((*it)(ev))
- 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 QFunctionPointer 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);
- QFunctionPointer 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)
-{
- if (X11->display != dpy) {
- // only handle X errors for our display
- return 0;
- }
-
- 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(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;
-
- 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";
-#ifndef QT_NO_XKB
- else if(err->request_code == X11->xkb_major)
- extensionName = "XKEYBOARD";
-#endif
-
- 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);
-
-#ifndef QT_NO_WHEELEVENT
- num =
- settings.value(QLatin1String("wheelScrollLines"),
- QApplication::wheelScrollLines()).toInt();
- QApplication::setWheelScrollLines(num);
-#endif
-
- 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;
- // otherwise use fontconfig to convert the string to integer
- else
- FcNameConstant((FcChar8 *) str, val);
- }
-}
-
-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;
-
- X11->use_xkb = false;
- X11->xkb_major = 0;
- X11->xkb_eventbase = 0;
- X11->xkb_errorbase = 0;
-
- // MIT-SHM
- X11->use_mitshm = false;
- X11->use_mitshm_pixmaps = 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)
-
- // With the threaded QML renderer, we always need this.
- XInitThreads();
-
- // 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 = ((defaultVisual->red_mask == 0xff0000
- || defaultVisual->red_mask == 0xf800)
- && (defaultVisual->green_mask == 0xff00
- || defaultVisual->green_mask == 0x7e0)
- && (defaultVisual->blue_mask == 0xff
- || defaultVisual->blue_mask == 0x1f));
- X11->use_mitshm_pixmaps = X11->use_mitshm && mitshm_pixmaps;
- }
- }
-#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");
- X11->ptrXRRSizes =
- (PtrXRRSizes) xrandrLib.resolve("XRRSizes");
- }
-# else
- X11->ptrXRRSelectInput = XRRSelectInput;
- X11->ptrXRRUpdateConfiguration = XRRUpdateConfiguration;
- X11->ptrXRRRootToScreen = XRRRootToScreen;
- X11->ptrXRRQueryExtension = XRRQueryExtension;
- X11->ptrXRRSizes = XRRSizes;
-# 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
-
-#ifndef QT_NO_XKB
- int xkblibMajor = XkbMajorVersion;
- int xkblibMinor = XkbMinorVersion;
- X11->use_xkb = XkbQueryExtension(X11->display,
- &X11->xkb_major,
- &X11->xkb_eventbase,
- &X11->xkb_errorbase,
- &xkblibMajor,
- &xkblibMinor);
- if (X11->use_xkb) {
- // 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);
-
- // select for group change events
- XkbSelectEventDetails(X11->display,
- XkbUseCoreKbd,
- XkbStateNotify,
- XkbAllStateComponentsMask,
- XkbGroupStateMask);
-
- // current group state is queried when creating the keymapper, no need to do it here
- }
-#endif
-
-
-#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 !defined(QT_NO_XRENDER) && (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
- X11->fc_hint_style = -1;
- 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();
-
- // 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
-
-#ifndef QT_NO_XFIXES
- if (X11->ptrXFixesSelectSelectionInput)
- X11->ptrXFixesSelectSelectionInput(X11->display, QX11Info::appRootWindow(), ATOM(_NET_WM_CM_S0),
- XFixesSetSelectionOwnerNotifyMask
- | XFixesSelectionWindowDestroyNotifyMask
- | XFixesSelectionClientCloseNotifyMask);
-#endif // QT_NO_XFIXES
- X11->compositingManagerRunning = XGetSelectionOwner(X11->display,
- ATOM(_NET_WM_CM_S0));
- X11->desktopEnvironment = DE_UNKNOWN;
- X11->desktopVersion = 0;
-
- Atom type;
- int format;
- unsigned long length, after;
- uchar *data = 0;
- int rc;
-
- do {
- if (!qgetenv("KDE_FULL_SESSION").isEmpty()) {
- X11->desktopEnvironment = DE_KDE;
- X11->desktopVersion = qgetenv("KDE_SESSION_VERSION").toInt();
- break;
- }
-
- if (qgetenv("DESKTOP_SESSION") == "gnome") {
- X11->desktopEnvironment = DE_GNOME;
- break;
- }
-
- // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it
- if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) {
- X11->desktopEnvironment = DE_GNOME;
- break;
- }
-
- rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_DT_SAVE_MODE),
- 0, 2, False, XA_STRING, &type, &format, &length,
- &after, &data);
- if (rc == Success && length) {
- if (!strcmp(reinterpret_cast<char *>(data), "xfce4")) {
- // Pretend that xfce4 is gnome, as it uses the same libraries.
- // The detection above is stolen from xdg-open.
- X11->desktopEnvironment = DE_GNOME;
- break;
- }
-
- // We got the property but it wasn't xfce4. Free data before it gets overwritten.
- XFree(data);
- data = 0;
- }
-
- rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
- 0, 1, False, AnyPropertyType, &type, &format, &length,
- &after, &data);
- if (rc == Success && length) {
- // DTWM is running, meaning most likely CDE is running...
- X11->desktopEnvironment = DE_CDE;
- break;
- }
-
- rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_SGI_DESKS_MANAGER), 0, 1, False, XA_WINDOW,
- &type, &format, &length, &after, &data);
- if (rc == Success && length) {
- X11->desktopEnvironment = DE_4DWM;
- break;
- }
-
- if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
- ATOM(_NET_SUPPORTING_WM_CHECK),
- 0, 1024, False, XA_WINDOW, &type,
- &format, &length, &after, &data) == Success) {
- if (type == XA_WINDOW && format == 32) {
- Window windowManagerWindow = *((Window*) data);
- XFree(data);
- data = 0;
-
- if (windowManagerWindow != XNone) {
- Atom utf8atom = ATOM(UTF8_STRING);
- if (XGetWindowProperty(QX11Info::display(), windowManagerWindow, ATOM(_NET_WM_NAME),
- 0, 1024, False, utf8atom, &type,
- &format, &length, &after, &data) == Success) {
- if (type == utf8atom && format == 8) {
- if (qstrcmp((const char *)data, "MCompositor") == 0)
- X11->desktopEnvironment = DE_MEEGO_COMPOSITOR;
- }
- }
- }
- }
- }
-
- } while(0);
-
- if (data)
- XFree((char *)data);
-
-#if !defined(QT_NO_STYLE_GTK)
- if (X11->desktopEnvironment == DE_GNOME) {
- static bool menusHaveIcons = QGtkStyle::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) || devs->type == ATOM(XTabletStylus)) {
- deviceType = QTabletEvent::Stylus;
- if (wacomDeviceName()->isEmpty())
- wacomDeviceName()->append(devs->name);
- gotStylus = true;
- } else if (devs->type == ATOM(XWacomEraser) || devs->type == ATOM(XTabletEraser)) {
- 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.
- // 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;
- }
- }
-}
-
-Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
-{
- Window root;
- Window child;
- int root_x, root_y, win_x, win_y;
- uint keybstate;
- for (int i = 0; i < ScreenCount(X11->display); ++i) {
- if (XQueryPointer(X11->display, QX11Info::appRootWindow(i), &root, &child,
- &root_x, &root_y, &win_x, &win_y, &keybstate))
- return X11->translateModifiers(keybstate & 0x00ff);
- }
- return 0;
-
-}
-
-/*****************************************************************************
- 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 && amw->testAttribute(Qt::WA_X11DoNotAcceptFocus))
- amw = 0;
- 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;
- if (req->selection == ATOM(_NET_WM_CM_S0))
- X11->compositingManagerRunning = req->owner;
- }
-#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;
- }
-#ifndef QT_NO_XKB
- else if (X11->use_xkb && event->type == X11->xkb_eventbase) {
- XkbAnyEvent *xkbevent = (XkbAnyEvent *) event;
- switch (xkbevent->xkb_type) {
- case XkbStateNotify:
- {
- XkbStateNotifyEvent *xkbstateevent = (XkbStateNotifyEvent *) xkbevent;
- if ((xkbstateevent->changed & XkbGroupStateMask) != 0) {
- qt_keymapper_private()->xkb_currentGroup = xkbstateevent->group;
- QKeyMapper::changeKeyboard();
- }
- break;
- }
- default:
- break;
- }
- }
-#endif
-
- 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()) {
- // if we got a MapNotify when we were not waiting for it, it most
- // likely means the user has already asked to hide the window before
- // it ever being shown, so we try to withdraw a window after sending
- // the QShowEvent.
- bool pendingHide = widget->testAttribute(Qt::WA_WState_ExplicitShowHide) && widget->testAttribute(Qt::WA_WState_Hidden);
- 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);
- }
- }
- if (pendingHide) // hide the window
- XWithdrawWindow(X11->display, widget->internalWinId(), widget->x11Info().screen());
- }
- 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 don't 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();
-
- // emit the workAreaResized() signal
- QDesktopWidget *desktop = QApplication::desktop();
- int numScreens = desktop->numScreens();
- for (int i = 0; i < numScreens; ++i)
- emit desktop->workAreaResized(i);
- }
- } 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) < QT_GUI_DOUBLE_CLICK_RADIUS &&
- qAbs(event->xbutton.y - mouseYPos) < QT_GUI_DOUBLE_CLICK_RADIUS) {
- 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();
-#ifndef QT_NO_WHEELEVENT
- QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
- if (QApplication::sendSpontaneousEvent(widget, &e))
-#endif
- 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();
-#ifndef QT_NO_WHEELEVENT
- QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient);
- if (QApplication::sendSpontaneousEvent(widget, &e))
-#endif
- 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());
- bool isCPos = false;
-
- 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;
- isCPos = true;
- }
- 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;
- isCPos = true;
- }
- }
-#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
- }
-
- if (!isCPos) {
- // we didn't get an updated position of the toplevel.
- // either we haven't moved or there is a bug in the window manager.
- // anyway, let's query the position to be certain.
- int x, y;
- Window child;
- XTranslateCoordinates(X11->display, internalWinId(),
- QApplication::desktop()->screen(d->xinfo.screen())->internalWinId(),
- 0, 0, &x, &y, &child);
- newCPos.rx() = x;
- newCPos.ry() = y;
- }
-
- 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) {
- if (isVisible() && data->crect.size() != oldSize) {
- Q_ASSERT(d->extra->topextra);
- QWidgetBackingStore *bs = d->extra->topextra->backingStore.data();
- 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 (!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;
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QApplication::setWheelScrollLines(int n)
-{
- QApplicationPrivate::wheel_scroll_lines = n;
-}
-
-int QApplication::wheelScrollLines()
-{
- return QApplicationPrivate::wheel_scroll_lines;
-}
-#endif
-
-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(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS - 0 > 0)
- QVarLengthArray<char, 1024> buf(qMax<long>(sysconf(_SC_GETPW_R_SIZE_MAX), 1024L));
- struct passwd entry;
- while (getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr) == ERANGE) {
- if (buf.size() >= 32768) {
- // too big already, fail
- static char badusername[] = "";
- entryPtr = &entry;
- entry.pw_name = badusername;
- break;
- }
-
- // retry with a bigger buffer
- buf.resize(buf.size() * 2);
- }
-#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