Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/kernel/qapplication_x11.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7979#include <private/qcolor_p.h>
    8080#include <private/qcursor_p.h>
     81#include <private/qiconloader_p.h>
     82#include <qgtkstyle.h>
    8183#include "qstyle.h"
    8284#include "qmetaobject.h"
     
    8486#include "qlibrary.h"
    8587#include <private/qgraphicssystemfactory_p.h>
     88#include "qguiplatformplugin_p.h"
     89#include "qkde_p.h"
    8690
    8791#if !defined (QT_NO_TABLET)
     
    118122#define XK_MISCELLANY
    119123#include <X11/keysymdef.h>
     124#if !defined(QT_NO_XINPUT)
    120125#include <X11/extensions/XI.h>
     126#endif
    121127
    122128#include <stdlib.h>
     
    128134
    129135#include <private/qbackingstore_p.h>
     136
     137#ifdef QT_RX71_MULTITOUCH
     138#  include <qsocketnotifier.h>
     139#  include <linux/input.h>
     140#  include <errno.h>
     141#endif
     142
     143#if _POSIX_VERSION+0 < 200112L && !defined(Q_OS_BSD4)
     144# define QT_NO_UNSETENV
     145#endif
    130146
    131147QT_BEGIN_NAMESPACE
     
    158174    "_NET_WM_PING\0"
    159175    "_NET_WM_CONTEXT_HELP\0"
     176    "_NET_WM_SYNC_REQUEST\0"
     177    "_NET_WM_SYNC_REQUEST_COUNTER\0"
    160178
    161179    // ICCCM window state
     
    174192    "MULTIPLE\0"
    175193    "TIMESTAMP\0"
     194    "SAVE_TARGETS\0"
    176195    "CLIP_TEMPORARY\0"
    177196    "_QT_SELECTION\0"
    178197    "_QT_CLIPBOARD_SENTINEL\0"
    179198    "_QT_SELECTION_SENTINEL\0"
     199    "CLIPBOARD_MANAGER\0"
    180200
    181201    "RESOURCE_MANAGER\0"
     
    295315    "_XEMBED\0"
    296316    "_XEMBED_INFO\0"
     317
     318    "Wacom Stylus\0"
     319    "Wacom Cursor\0"
     320    "Wacom Eraser\0"
    297321};
    298322
     
    399423extern bool qt_is_gui_used;
    400424
    401 /*! 
     425/*!
    402426    \internal
    403427    Try to resolve a \a symbol from \a library with the version specified
     
    505529{
    506530public:
     531    QWidgetPrivate* d_func() { return QWidget::d_func(); }
    507532    bool translateMouseEvent(const XEvent *);
    508533    void translatePaintEvent(const XEvent *);
     
    639664
    640665    default:
     666#if !defined(QT_NO_XINPUT)
    641667        if (err->request_code == X11->xinput_major
    642668            && err->error_code == (X11->xinput_errorbase + XI_BadDevice)
     
    644670            return 0;
    645671        }
     672#endif
    646673        break;
    647674    }
     
    715742#endif
    716743
     744#ifndef QT_NO_XSYNC
     745struct qt_sync_request_event_data
     746{
     747    WId window;
     748};
     749
     750#if defined(Q_C_CALLBACKS)
     751extern "C" {
     752#endif
     753
     754static Bool qt_sync_request_scanner(Display*, XEvent *event, XPointer arg)
     755{
     756    qt_sync_request_event_data *data =
     757        reinterpret_cast<qt_sync_request_event_data*>(arg);
     758    if (event->type == ClientMessage &&
     759        event->xany.window == data->window &&
     760        event->xclient.message_type == ATOM(WM_PROTOCOLS) &&
     761        (Atom)event->xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST)) {
     762        QWidget *w = QWidget::find(event->xany.window);
     763        if (QTLWExtra *tlw = ((QETWidget*)w)->d_func()->maybeTopData()) {
     764            const ulong timestamp = (const ulong) event->xclient.data.l[1];
     765            if (timestamp > X11->time)
     766                X11->time = timestamp;
     767            if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
     768                tlw->syncRequestTimestamp = timestamp;
     769                tlw->newCounterValueLo = event->xclient.data.l[2];
     770                tlw->newCounterValueHi = event->xclient.data.l[3];
     771            }
     772        }
     773        return true;
     774    }
     775    return false;
     776}
     777
     778#if defined(Q_C_CALLBACKS)
     779}
     780#endif
     781#endif // QT_NO_XSYNC
    717782
    718783static void qt_x11_create_intern_atoms()
     
    753818                    ATOM(_QT_SETTINGS_TIMESTAMP), ATOM(_QT_SETTINGS_TIMESTAMP), 8,
    754819                    PropModeReplace, (unsigned char *)stamp.data(), stamp.size());
    755 }
    756 
    757 /*! \internal
    758     Gets the current KDE 3 or 4 home path
    759 */
    760 QString QApplicationPrivate::kdeHome()
    761 {
    762     static QString kdeHomePath;
    763     if (kdeHomePath.isEmpty()) {
    764         kdeHomePath = QString::fromLocal8Bit(qgetenv("KDEHOME"));
    765         if (kdeHomePath.isEmpty()) {
    766             int kdeSessionVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt();
    767             QDir homeDir(QDir::homePath());
    768             QString kdeConfDir(QLatin1String("/.kde"));
    769             if (4 == kdeSessionVersion && homeDir.exists(QLatin1String(".kde4")))
    770                 kdeConfDir = QLatin1String("/.kde4");
    771             kdeHomePath = QDir::homePath() + kdeConfDir;
    772         }
    773     }
    774     return kdeHomePath;
    775820}
    776821
     
    831876
    832877    // ### Fix properly for 4.6
    833     if (!(QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle"))) {
     878    bool usingGtkSettings = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle");
     879    if (!usingGtkSettings) {
    834880        if (groupCount == QPalette::NColorGroups)
    835881            QApplicationPrivate::setSystemPalette(pal);
    836882    }
    837883
    838     int kdeSessionVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt();
    839  
    840884    if (!appFont) {
    841         QFont font(QApplication::font());
    842         QString fontDescription;
    843         // Override Qt font if KDE4 settings can be used
    844         if (4 == kdeSessionVersion) {
    845             QSettings kdeSettings(kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
    846             fontDescription = kdeSettings.value(QLatin1String("font")).toString();
    847             if (fontDescription.isEmpty()) {
    848                 // KDE stores fonts without quotes
    849                 fontDescription = kdeSettings.value(QLatin1String("font")).toStringList().join(QLatin1String(","));
    850             }
    851         }
    852         if (fontDescription.isEmpty())
    853             fontDescription = settings.value(QLatin1String("font")).toString();
    854         if (!fontDescription .isEmpty()) {
    855             font.fromString(fontDescription );
    856             QApplicationPrivate::setSystemFont(font);
     885        // ### Fix properly for 4.6
     886        if (!usingGtkSettings) {
     887            QFont font(QApplication::font());
     888            QString fontDescription;
     889            // Override Qt font if KDE4 settings can be used
     890            if (X11->desktopVersion == 4) {
     891                QSettings kdeSettings(QKde::kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
     892                fontDescription = kdeSettings.value(QLatin1String("font")).toString();
     893                if (fontDescription.isEmpty()) {
     894                    // KDE stores fonts without quotes
     895                    fontDescription = kdeSettings.value(QLatin1String("font")).toStringList().join(QLatin1String(","));
     896                }
     897            }
     898            if (fontDescription.isEmpty())
     899                fontDescription = settings.value(QLatin1String("font")).toString();
     900            if (!fontDescription .isEmpty()) {
     901                font.fromString(fontDescription );
     902                QApplicationPrivate::setSystemFont(font);
     903            }
    857904        }
    858905    }
     
    872919    // read new QStyle
    873920    QString stylename = settings.value(QLatin1String("style")).toString();
    874     if (stylename.isEmpty() && !QApplicationPrivate::styleOverride && X11->use_xrender) {
    875         QStringList availableStyles = QStyleFactory::keys();
    876         // Override Qt style if KDE4 settings can be used
    877         if (4 == kdeSessionVersion) {
    878             QSettings kdeSettings(kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
    879             QString kde4Style = kdeSettings.value(QLatin1String("widgetStyle"),
    880                                                   QLatin1String("Oxygen")).toString();
    881             foreach (const QString &style, availableStyles) {
    882                 if (style.toLower() == kde4Style.toLower())
    883                     stylename = kde4Style;
    884             }
    885         // Set QGtkStyle for GNOME
    886         } else if (X11->desktopEnvironment == DE_GNOME) {
    887             QString gtkStyleKey = QString::fromLatin1("GTK+");
    888             if (availableStyles.contains(gtkStyleKey))
    889                 stylename = gtkStyleKey;
    890         }
     921
     922    if (stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull() && X11->use_xrender) {
     923        stylename = qt_guiPlatformPlugin()->styleName();
    891924    }
    892925
    893926    static QString currentStyleName = stylename;
    894927    if (QCoreApplication::startingUp()) {
    895         if (!stylename.isEmpty() && !QApplicationPrivate::styleOverride)
    896             QApplicationPrivate::styleOverride = new QString(stylename);
     928        if (!stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull())
     929            QApplicationPrivate::styleOverride = stylename;
    897930    } else {
    898931        if (currentStyleName != stylename) {
     
    10441077}
    10451078
    1046 // Reads a KDE color setting
    1047 static QColor kdeColor(const QString &key)
    1048 {
    1049     QSettings kdeSettings(QApplicationPrivate::kdeHome() +
    1050                           QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
    1051     QVariant variant = kdeSettings.value(key);
    1052     if (variant.isValid()) {
    1053         QStringList values = variant.toStringList();
    1054         if (values.size() == 3) {
    1055             int r = values[0].toInt();
    1056             int g = values[1].toInt();
    1057             int b = values[2].toInt();
    1058             return QColor(r, g, b);
    1059         }
    1060     }
    1061     return QColor();
    1062 }
    1063 
    10641079// set font, foreground and background from x11 resources. The
    10651080// arguments may override the resource settings.
     
    10821097        // first, read from settings
    10831098        QApplicationPrivate::x11_apply_settings();
    1084 
    10851099        // the call to QApplication::style() below creates the system
    10861100        // palette, which breaks the logic after the RESOURCE_MANAGER
     
    12281242        QApplicationPrivate::setSystemFont(fnt);
    12291243    }
     1244    // QGtkStyle sets it's own system palette
     1245    bool gtkStyle = QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle");
    12301246    bool kdeColors = (QApplication::desktopSettingsAware() && X11->desktopEnvironment == DE_KDE);
    1231 
    1232     if (kdeColors || (button || !resBG.isEmpty() || !resFG.isEmpty())) {// set app colors
     1247    if (!gtkStyle && (kdeColors || (button || !resBG.isEmpty() || !resFG.isEmpty()))) {// set app colors
    12331248        bool allowX11ColorNames = QColor::allowX11ColorNames();
    12341249        QColor::setAllowX11ColorNames(true);
     
    12661281        }
    12671282
    1268         if (kdeColors) {
    1269             // Setup KDE palette
    1270             QColor color;
    1271             color = kdeColor(QLatin1String("buttonBackground"));
    1272             if (!color.isValid())
    1273                 color = kdeColor(QLatin1String("Colors:Button/BackgroundNormal"));
    1274             if (color.isValid())
    1275                 btn = color;
    1276 
    1277             color = kdeColor(QLatin1String("background"));
    1278             if (!color.isValid())
    1279                 color = kdeColor(QLatin1String("Colors:Window/BackgroundNormal"));
    1280             if (color.isValid())
    1281                 bg = color;
    1282 
    1283             color = kdeColor(QLatin1String("foreground"));
    1284             if (!color.isValid())
    1285                 color = kdeColor(QLatin1String("Colors:View/ForegroundNormal"));
    1286             if (color.isValid()) {
    1287                 fg = color;
    1288             }
    1289 
    1290             color = kdeColor(QLatin1String("windowForeground"));
    1291             if (!color.isValid())
    1292                 color = kdeColor(QLatin1String("Colors:Window/ForegroundNormal"));
    1293             if (color.isValid())
    1294                 wfg = color;
    1295 
    1296             color = kdeColor(QLatin1String("windowBackground"));
    1297             if (!color.isValid())
    1298                 color = kdeColor(QLatin1String("Colors:View/BackgroundNormal"));
    1299             if (color.isValid())
    1300                 base = color;
    1301         }
    1302 
    13031283        QPalette pal(fg, btn, btn.lighter(125), btn.darker(130), btn.darker(120), wfg.isValid() ? wfg : fg, Qt::white, base, bg);
    13041284        QColor disabled((fg.red()   + btn.red())  / 2,
     
    13121292            highlight = QColor(selectBackground);
    13131293            highlightText = QColor(selectForeground);
    1314         }
    1315         // Use KDE3 or KDE4 color settings if present
    1316         if (kdeColors) {
    1317             QColor color = kdeColor(QLatin1String("selectBackground"));
    1318             if (!color.isValid())
    1319                 color = kdeColor(QLatin1String("Colors:Selection/BackgroundNormal"));
    1320             if (color.isValid())
    1321                 highlight = color;
    1322 
    1323             color = kdeColor(QLatin1String("selectForeground"));
    1324             if (!color.isValid())
    1325                 color = kdeColor(QLatin1String("Colors:Selection/ForegroundNormal"));
    1326             if (color.isValid())
    1327                 highlightText = color;
    1328 
    1329             color = kdeColor(QLatin1String("alternateBackground"));
    1330             if (!color.isValid())
    1331                 color = kdeColor(QLatin1String("Colors:View/BackgroundAlternate"));
    1332             if (color.isValid())
    1333                 pal.setColor(QPalette::AlternateBase, color);
    1334             else
    1335                 pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(110));
    1336 
    1337             color = kdeColor(QLatin1String("buttonForeground"));
    1338             if (!color.isValid())
    1339                 color = kdeColor(QLatin1String("Colors:Button/ForegroundNormal"));
    1340             if (color.isValid())
    1341                 pal.setColor(QPalette::ButtonText, color);
    13421294        }
    13431295
     
    13631315        }
    13641316
    1365         // QGtkStyle sets it's own system palette
    1366         if (!(QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle"))) {
    1367             QApplicationPrivate::setSystemPalette(pal);
    1368         }
     1317        pal = qt_guiPlatformPlugin()->palette().resolve(pal);
     1318        QApplicationPrivate::setSystemPalette(pal);
    13691319        QColor::setAllowX11ColorNames(allowX11ColorNames);
    13701320    }
     
    13861336                                       effects.contains(QLatin1String("animatetoolbox")));
    13871337    }
     1338
     1339    QIconLoader::instance()->updateSystemTheme();
    13881340}
    13891341
     
    15801532static PtrWacomConfigCloseDevice ptrWacomConfigCloseDevice = 0;
    15811533static PtrWacomConfigTerm ptrWacomConfigTerm = 0;
     1534Q_GLOBAL_STATIC(QByteArray, wacomDeviceName)
    15821535#endif
    15831536
     
    16731626    // MIT-SHM
    16741627    X11->use_mitshm = false;
     1628    X11->use_mitshm_pixmaps = false;
    16751629    X11->mitshm_major = 0;
    16761630
     
    17201674#endif
    17211675
    1722     X11->startupId = X11->originalStartupId = 0;
     1676    X11->startupId = 0;
    17231677
    17241678    int argc = priv->argc;
     
    19021856            screen->ref = 1; // ensures it doesn't get deleted
    19031857            screen->screen = s;
    1904             screen->dpiX = (DisplayWidth(X11->display, s) * 254 + DisplayWidthMM(X11->display, s)*5)
    1905                            / (DisplayWidthMM(X11->display, s)*10);
    1906             screen->dpiY = (DisplayHeight(X11->display, s) * 254 + DisplayHeightMM(X11->display, s)*5)
    1907                            / (DisplayHeightMM(X11->display, s)*10);
     1858
     1859            int widthMM = DisplayWidthMM(X11->display, s);
     1860            if (widthMM != 0) {
     1861                screen->dpiX = (DisplayWidth(X11->display, s) * 254 + widthMM * 5) / (widthMM * 10);
     1862            } else {
     1863                screen->dpiX = 72;
     1864            }
     1865
     1866            int heightMM = DisplayHeightMM(X11->display, s);
     1867            if (heightMM != 0) {
     1868                screen->dpiY = (DisplayHeight(X11->display, s) * 254 + heightMM * 5) / (heightMM * 10);
     1869            } else {
     1870                screen->dpiY = 72;
     1871            }
    19081872
    19091873            X11->argbVisuals[s] = 0;
     
    19491913            QString displayName = QLatin1String(XDisplayName(NULL));
    19501914
    1951             // apparently MITSHM only works for local displays, so do a quick check here
    1952             // to determine whether the display is local or not (not 100 % accurate)
     1915            // MITSHM only works for local displays, so do a quick check here
     1916            // to determine whether the display is local or not (not 100 % accurate).
     1917            // BGR server layouts are not supported either, since it requires the raster
     1918            // engine to work on a QImage with BGR layout.
    19531919            bool local = displayName.isEmpty() || displayName.lastIndexOf(QLatin1Char(':')) == 0;
    1954             if (local && (qgetenv("QT_X11_NO_MITSHM").toInt() == 0))
    1955                 X11->use_mitshm = mitshm_pixmaps;
     1920            if (local && (qgetenv("QT_X11_NO_MITSHM").toInt() == 0)) {
     1921                Visual *defaultVisual = DefaultVisual(X11->display, DefaultScreen(X11->display));
     1922                X11->use_mitshm = ((defaultVisual->red_mask == 0xff0000
     1923                                    || defaultVisual->red_mask == 0xf800)
     1924                                   && (defaultVisual->green_mask == 0xff00
     1925                                       || defaultVisual->green_mask == 0x7e0)
     1926                                   && (defaultVisual->blue_mask == 0xff
     1927                                       || defaultVisual->blue_mask == 0x1f));
     1928                X11->use_mitshm_pixmaps = X11->use_mitshm && mitshm_pixmaps;
     1929            }
    19561930        }
    19571931#endif // QT_NO_MITSHM
     
    20522026            }
    20532027        }
    2054         if (X11->use_xfixes && X11->ptrXFixesSelectSelectionInput) {
    2055             const unsigned long eventMask =
    2056                 XFixesSetSelectionOwnerNotifyMask | XFixesSelectionWindowDestroyNotifyMask | XFixesSelectionClientCloseNotifyMask;
    2057             X11->ptrXFixesSelectSelectionInput(X11->display, QX11Info::appRootWindow(0),
    2058                                                XA_PRIMARY, eventMask);
    2059             X11->ptrXFixesSelectSelectionInput(X11->display, QX11Info::appRootWindow(0),
    2060                                                ATOM(CLIPBOARD), eventMask);
    2061         }
    20622028#endif // QT_NO_XFIXES
    20632029
     
    20792045#endif // QT_RUNTIME_XCURSOR
    20802046#endif // QT_NO_XCURSOR
     2047
     2048#ifndef QT_NO_XSYNC
     2049        int xsync_evbase, xsync_errbase;
     2050        int major, minor;
     2051        if (XSyncQueryExtension(X11->display, &xsync_evbase, &xsync_errbase))
     2052            XSyncInitialize(X11->display, &major, &minor);
     2053#endif // QT_NO_XSYNC
    20812054
    20822055#ifndef QT_NO_XINERAMA
     
    22412214                                                            ATOM(_NET_WM_CM_S0));
    22422215        X11->desktopEnvironment = DE_UNKNOWN;
     2216        X11->desktopVersion = 0;
    22432217
    22442218        // See if the current window manager is using the freedesktop.org spec to give its name
     
    22852259            uchar *data = 0;
    22862260
    2287             if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
    2288                                    0, 1, False, AnyPropertyType, &type, &format, &length,
     2261            QString session = QString::fromLocal8Bit(qgetenv("DESKTOP_SESSION"));
     2262            if (session == QLatin1String("kde")) {
     2263                X11->desktopEnvironment = DE_KDE;
     2264            } else if (session == QLatin1String("gnome") || session == QLatin1String("xfce")) {
     2265                X11->desktopEnvironment = DE_GNOME;
     2266            } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
     2267                                          0, 1, False, AnyPropertyType, &type, &format, &length,
    22892268                                   &after, &data) == Success && length) {
    22902269                // DTWM is running, meaning most likely CDE is running...
     
    23162295        }
    23172296
     2297        if (X11->desktopEnvironment == DE_KDE)
     2298            X11->desktopVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt();
     2299
     2300#if !defined(QT_NO_STYLE_GTK)
     2301        if (X11->desktopEnvironment == DE_GNOME) {
     2302            static bool menusHaveIcons = QGtkStyle::getGConfBool(QLatin1String("/desktop/gnome/interface/menus_have_icons"), true);
     2303            QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !menusHaveIcons);
     2304        }
     2305#endif
    23182306        qt_set_input_encoding();
    23192307
     
    23512339            XDevice *dev = 0;
    23522340
    2353 #if !defined(Q_OS_IRIX)
    2354             // XFree86 divides a stylus and eraser into 2 devices, so we must do for both...
    2355             const QString XFREENAMESTYLUS = QLatin1String("stylus");
    2356             const QString XFREENAMEPEN = QLatin1String("pen");
    2357             const QString XFREENAMEERASER = QLatin1String("eraser");
    2358 #endif
    2359 
    23602341            if (X11->ptrXListInputDevices) {
    23612342                devices = X11->ptrXListInputDevices(X11->display, &ndev);
     
    23722353                gotEraser = false;
    23732354
     2355#if defined(Q_OS_IRIX)
    23742356                QString devName = QString::fromLocal8Bit(devs->name).toLower();
    2375 #if defined(Q_OS_IRIX)
    23762357                if (devName == QLatin1String(WACOM_NAME)) {
    23772358                    deviceType = QTabletEvent::Stylus;
     
    23792360                }
    23802361#else
    2381                 if (devName.startsWith(XFREENAMEPEN)
    2382                     || devName.startsWith(XFREENAMESTYLUS)) {
     2362                if (devs->type == ATOM(XWacomStylus)) {
    23832363                    deviceType = QTabletEvent::Stylus;
     2364                    if (wacomDeviceName()->isEmpty())
     2365                        wacomDeviceName()->append(devs->name);
    23842366                    gotStylus = true;
    2385                 } else if (devName.startsWith(XFREENAMEERASER)) {
     2367                } else if (devs->type == ATOM(XWacomEraser)) {
    23862368                    deviceType = QTabletEvent::XFreeEraser;
    23872369                    gotEraser = true;
     
    25192501
    25202502        X11->startupId = getenv("DESKTOP_STARTUP_ID");
    2521         X11->originalStartupId = X11->startupId;
    2522         static char desktop_startup_id[] = "DESKTOP_STARTUP_ID=";
    2523         putenv(desktop_startup_id);
    2524 
     2503        if (X11->startupId) {
     2504#ifndef QT_NO_UNSETENV
     2505            unsetenv("DESKTOP_STARTUP_ID");
     2506#else
     2507            // it's a small memory leak, however we won't crash if Qt is
     2508            // unloaded and someones tries to use the envoriment.
     2509            putenv(strdup("DESKTOP_STARTUP_ID="));
     2510#endif
     2511        }
    25252512   } else {
    25262513        // read some non-GUI settings when not using the X server...
     
    25762563}
    25772564
    2578 
    2579     // run-time search for default style
    2580 /*!
    2581     \internal
    2582 */
    2583 void QApplicationPrivate::x11_initialize_style()
    2584 {
    2585     if (QApplicationPrivate::app_style)
    2586         return;
    2587 
    2588     switch(X11->desktopEnvironment) {
    2589         case DE_KDE:
    2590             if (X11->use_xrender)
    2591                 QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("plastique"));
    2592             else
    2593                 QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("windows"));
    2594             break;
    2595         case DE_GNOME:
    2596             if (X11->use_xrender)
    2597                 QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("cleanlooks"));
    2598             else
    2599                 QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("windows"));
    2600             break;
    2601         case DE_CDE:
    2602             QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("cde"));
    2603             break;
    2604         default:
    2605             // Don't do anything
    2606             break;
    2607     }
    2608 }
    2609 
    26102565void QApplicationPrivate::initializeWidgetPaletteHash()
    26112566{
     
    26352590#endif
    26362591    }
    2637 
    2638     // restore original value back. This is also done in QWidgetPrivate::show_sys.
    2639     if (X11->originalStartupId)
    2640         putenv(X11->originalStartupId);
    26412592
    26422593#ifndef QT_NO_XRENDER
     
    28432794 *****************************************************************************/
    28442795
    2845 extern void qt_x11_enforce_cursor(QWidget * w);
    2846 
    28472796void QApplication::setOverrideCursor(const QCursor &cursor)
    28482797{
     
    29502899                    while (ctarget && !w) {
    29512900                        X11->ignoreBadwindow();
    2952                         XTranslateCoordinates(X11->display,
    2953                                               QX11Info::appRootWindow(screen),
    2954                                               ctarget, x, y, &unused, &unused, &ctarget);
    2955                         if (X11->badwindow())
     2901                        if (!XTranslateCoordinates(X11->display,
     2902                                                   QX11Info::appRootWindow(screen),
     2903                                                   ctarget, x, y, &unused, &unused, &ctarget)
     2904                                || X11->badwindow())
    29562905                            break;
    29572906                        if (ctarget == wid) {
     
    29712920}
    29722921
    2973 /*!
    2974     Synchronizes with the X server in the X11 implementation. This
    2975     normally takes some time. Does nothing on other platforms.
    2976 */
    2977 
    29782922void QApplication::syncX()
    29792923{
    29802924    if (X11->display)
    2981         XSync(X11->display, False);                        // don't discard events
     2925        XSync(X11->display, False);  // don't discard events
    29822926}
    29832927
     
    30813025}
    30823026
    3083 /*!
    3084     \internal
    3085 */
    30863027int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
    30873028{
     
    31203061                                False, SubstructureNotifyMask|SubstructureRedirectMask, event);
    31213062                }
     3063#ifndef QT_NO_XSYNC
     3064            } else if (a == ATOM(_NET_WM_SYNC_REQUEST)) {
     3065                const ulong timestamp = (const ulong) event->xclient.data.l[1];
     3066                if (timestamp > X11->time)
     3067                    X11->time = timestamp;
     3068                if (QTLWExtra *tlw = w->d_func()->maybeTopData()) {
     3069                    if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) {
     3070                        tlw->syncRequestTimestamp = timestamp;
     3071                        tlw->newCounterValueLo = event->xclient.data.l[2];
     3072                        tlw->newCounterValueHi = event->xclient.data.l[3];
     3073                    }
     3074                }
     3075#endif
    31223076            }
    31233077        } else if (event->xclient.message_type == ATOM(_QT_SCROLL_DONE)) {
     
    31463100}
    31473101
    3148 /*!
    3149     This function does the core processing of individual X
    3150     \a{event}s, normally by dispatching Qt events to the right
    3151     destination.
    3152 
    3153     It returns 1 if the event was consumed by special handling, 0 if
    3154     the \a event was consumed by normal handling, and -1 if the \a
    3155     event was for an unrecognized widget.
    3156 
    3157     \sa x11EventFilter()
    3158 */
    31593102int QApplication::x11ProcessEvent(XEvent* event)
    31603103{
    31613104    Q_D(QApplication);
    31623105    QScopedLoopLevelCounter loopLevelCounter(d->threadData);
     3106
    31633107#ifdef ALIEN_DEBUG
    31643108    //qDebug() << "QApplication::x11ProcessEvent:" << event->type;
     
    33663310        w->data->crect.setWidth(DisplayWidth(X11->display, scr));
    33673311        w->data->crect.setHeight(DisplayHeight(X11->display, scr));
    3368         QVarLengthArray<QRect> oldSizes(desktop->numScreens());
    3369         for (int i = 0; i < desktop->numScreens(); ++i)
    3370             oldSizes[i] = desktop->screenGeometry(i);
    33713312        QResizeEvent e(w->size(), oldSize);
    33723313        QApplication::sendEvent(w, &e);
    3373         for (int i = 0; i < qMin(oldSizes.count(), desktop->numScreens()); ++i) {
    3374             if (oldSizes[i] != desktop->screenGeometry(i))
    3375                 emit desktop->resized(i);
    3376         }
    3377         for (int i = oldSizes.count(); i < desktop->numScreens(); ++i)
    3378             emit desktop->resized(i); // added
    3379         for (int i = desktop->numScreens(); i < oldSizes.count(); ++i)
    3380             emit desktop->resized(i); // removed
     3314        if (w != desktop)
     3315            QApplication::sendEvent(desktop, &e);
    33813316    }
    33823317#endif // QT_NO_XRANDR
     
    38183753            } else if (event->xproperty.atom == ATOM(_NET_WORKAREA)) {
    38193754                qt_desktopwidget_update_workarea();
     3755
     3756                // emit the workAreaResized() signal
     3757                QDesktopWidget *desktop = QApplication::desktop();
     3758                int numScreens = desktop->numScreens();
     3759                for (int i = 0; i < numScreens; ++i)
     3760                    emit desktop->workAreaResized(i);
    38203761            }
    38213762        } else if (widget) {
     
    38323773    return 0;
    38333774}
    3834 
    3835 /*!
    3836     \fn bool QApplication::x11EventFilter(XEvent *event)
    3837 
    3838     \warning This virtual function is only implemented under X11.
    3839 
    3840     If you create an application that inherits QApplication and
    3841     reimplement this function, you get direct access to all X events
    3842     that the are received from the X server. The events are passed in
    3843     the \a event parameter.
    3844 
    3845     Return true if you want to stop the event from being processed.
    3846     Return false for normal event dispatching. The default
    3847     implementation returns false.
    3848 
    3849     It is only the directly addressed messages that are filtered.
    3850     You must install an event filter directly on the event
    3851     dispatcher, which is returned by
    3852     QAbstractEventDispatcher::instance(), to handle system wide
    3853     messages.
    3854 
    3855     \sa x11ProcessEvent()
    3856 */
    38573775
    38583776bool QApplication::x11EventFilter(XEvent *)
     
    41774095                    && qt_button_down == this)
    41784096                || (nextEvent.type == ClientMessage
    4179                     && nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE))) {
     4097                    && (nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE) ||
     4098                    (nextEvent.xclient.message_type == ATOM(WM_PROTOCOLS) &&
     4099                     (Atom)nextEvent.xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST))))) {
    41804100                qApp->x11ProcessEvent(&nextEvent);
    41814101                continue;
     
    44474367        QApplicationPrivate::sendMouseEvent(widget, &e, alienWidget, this, &qt_button_down,
    44484368                                            qt_last_mouse_receiver);
    4449 
    44504369        if (type == QEvent::MouseButtonPress
    44514370            && button == Qt::RightButton
     
    45164435    if (config == 0)
    45174436        return;
    4518     const char *name = "stylus"; // TODO get this from the X config instead (users may have called it differently)
    4519     WACOMDEVICE *device = ptrWacomConfigOpenDevice (config, name);
     4437    WACOMDEVICE *device = ptrWacomConfigOpenDevice (config, wacomDeviceName()->constData());
    45204438    if (device == 0)
    45214439        return;
     
    45754493#endif
    45764494
     4495struct qt_tablet_motion_data
     4496{
     4497    bool filterByWidget;
     4498    const QWidget *widget;
     4499    const QWidget *etWidget;
     4500    int tabletMotionType;
     4501    bool error; // found a reason to stop searching
     4502};
     4503
     4504static Bool qt_mouseMotion_scanner(Display *, XEvent *event, XPointer arg)
     4505{
     4506    qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
     4507    if (data->error)
     4508        return false;
     4509
     4510    if (event->type == MotionNotify)
     4511        return true;
     4512
     4513    data->error = event->type != data->tabletMotionType; // we stop compression when another event gets in between.
     4514    return false;
     4515}
     4516
     4517static Bool qt_tabletMotion_scanner(Display *, XEvent *event, XPointer arg)
     4518{
     4519    qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg;
     4520    if (data->error)
     4521        return false;
     4522    if (event->type == data->tabletMotionType) {
     4523        const XDeviceMotionEvent *const motion = reinterpret_cast<const XDeviceMotionEvent*>(event);
     4524        if (data->filterByWidget) {
     4525            const QPoint curr(motion->x, motion->y);
     4526            const QWidget *w = data->etWidget;
     4527            const QWidget *const child = w->childAt(curr);
     4528            if (child) {
     4529                w = child;
     4530            }
     4531            if (w == data->widget)
     4532                return true;
     4533        } else {
     4534            return true;
     4535        }
     4536    }
     4537
     4538    data->error = event->type != MotionNotify; // we stop compression when another event gets in between.
     4539    return false;
     4540}
     4541
    45774542bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet)
    45784543{
     
    46014566    int deviceType = QTabletEvent::NoDevice;
    46024567    int pointerType = QTabletEvent::UnknownPointer;
    4603     XEvent xinputMotionEvent;
    4604     XEvent mouseMotionEvent;
    46054568    const XDeviceMotionEvent *motion = 0;
    46064569    XDeviceButtonEvent *button = 0;
     
    46084571    QEvent::Type t;
    46094572    Qt::KeyboardModifiers modifiers = 0;
    4610     bool reinsertMouseEvent = false;
    4611     bool neverFoundMouseEvent = true;
    4612     XEvent xinputMotionEventNext;
    4613     XEvent mouseMotionEventSave;
    46144573#if !defined (Q_OS_IRIX)
    46154574    XID device_id;
     
    46184577    if (ev->type == tablet->xinput_motion) {
    46194578        motion = reinterpret_cast<const XDeviceMotionEvent*>(ev);
    4620         for (;;) {
    4621             // get the corresponding mouseMotionEvent for motion
    4622             if (XCheckTypedWindowEvent(X11->display, internalWinId(), MotionNotify, &mouseMotionEvent)) {
    4623                 mouseMotionEventSave = mouseMotionEvent;
    4624                 reinsertMouseEvent = true;
    4625                 neverFoundMouseEvent = false;
    4626 
    4627                 if (mouseMotionEvent.xmotion.time > motion->time) {
    4628                     XEvent xinputMotionEventLoop = *ev;
    4629 
    4630                     // xinput event is older than the mouse event --> search for the corresponding xinput event for the given mouse event
    4631                     while (mouseMotionEvent.xmotion.time > (reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEventLoop))->time) {
    4632                         if (XCheckTypedWindowEvent(X11->display, internalWinId(), tablet->xinput_motion, &xinputMotionEventLoop)) {
    4633                             xinputMotionEvent = xinputMotionEventLoop;
    4634                         }
    4635                         else {
    4636                             break;
    4637                         }
    4638                     }
    4639                     motion = reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEvent);
    4640                 }
    4641 
    4642                 // get the next xinputMotionEvent, for the next loop run
    4643                 if (!XCheckTypedWindowEvent(X11->display, internalWinId(), tablet->xinput_motion, &xinputMotionEventNext)) {
    4644                     XPutBackEvent(X11->display, &mouseMotionEvent);
    4645                     reinsertMouseEvent = false;
    4646                     break;
    4647                 }
    4648 
    4649                 if (mouseMotionEvent.xmotion.time != motion->time) {
    4650                     // reinsert in order
    4651                     if (mouseMotionEvent.xmotion.time >= motion->time) {
    4652                         XPutBackEvent(X11->display, &mouseMotionEvent);
    4653                         XPutBackEvent(X11->display, &xinputMotionEventNext);
    4654                         // next entry in queue is xinputMotionEventNext
    4655                     }
    4656                     else {
    4657                         XPutBackEvent(X11->display, &xinputMotionEventNext);
    4658                         XPutBackEvent(X11->display, &mouseMotionEvent);
    4659                         // next entry in queue is mouseMotionEvent
    4660                     }
    4661                     reinsertMouseEvent = false;
    4662                     break;
    4663                 }
    4664             }
    4665             else {
    4666                 break;
    4667             }
    4668 
    4669             xinputMotionEvent = xinputMotionEventNext;
    4670             motion = (reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEvent));
    4671         }
    4672 
    4673         if (reinsertMouseEvent) {
    4674           XPutBackEvent(X11->display, &mouseMotionEventSave);
    4675         }
    4676 
    4677         if (neverFoundMouseEvent) {
    4678             XEvent xinputMotionEventLoop;
    4679             bool eventFound = false;
    4680             // xinput event without mouseMotionEvent --> search the newest xinputMotionEvent
    4681             while (XCheckTypedWindowEvent(X11->display, internalWinId(), tablet->xinput_motion, &xinputMotionEventLoop)) {
    4682                 xinputMotionEvent = xinputMotionEventLoop;
    4683                 eventFound = true;
    4684             }
    4685             if (eventFound) motion = reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEvent);
    4686         }
    4687 
    46884579        t = QEvent::TabletMove;
    46894580        global = QPoint(motion->x_root, motion->y_root);
     
    48384729#endif
    48394730
    4840     QWidget *child = w->childAt(curr);
    4841     if (child) {
    4842         w = child;
    4843         curr = w->mapFromGlobal(global);
    4844     }
     4731    if (tablet->widgetToGetPress) {
     4732        w = tablet->widgetToGetPress;
     4733    } else {
     4734        QWidget *child = w->childAt(curr);
     4735        if (child)
     4736            w = child;
     4737    }
     4738    curr = w->mapFromGlobal(global);
    48454739
    48464740    if (t == QEvent::TabletPress) {
     
    48564750                   qreal(pressure / qreal(tablet->maxPressure - tablet->minPressure)),
    48574751                   xTilt, yTilt, tangentialPressure, rotation, z, modifiers, uid);
    4858     if (proximity)
     4752    if (proximity) {
    48594753        QApplication::sendSpontaneousEvent(qApp, &e);
    4860     else
     4754    } else {
    48614755        QApplication::sendSpontaneousEvent(w, &e);
     4756        const bool accepted = e.isAccepted();
     4757        if (!accepted && ev->type == tablet->xinput_motion) {
     4758            // If the widget does not accept tablet events, we drop the next ones from the event queue
     4759            // for this widget so it is not overloaded with the numerous tablet events.
     4760            qt_tablet_motion_data tabletMotionData;
     4761            tabletMotionData.tabletMotionType = tablet->xinput_motion;
     4762            tabletMotionData.widget = w;
     4763            tabletMotionData.etWidget = this;
     4764            // if nothing is pressed, the events are filtered by position
     4765            tabletMotionData.filterByWidget = (tablet->widgetToGetPress == 0);
     4766
     4767            bool reinsertMouseEvent = false;
     4768            XEvent mouseMotionEvent;
     4769            while (true) {
     4770                // Find first mouse event since we expect them in pairs inside Qt
     4771                tabletMotionData.error =false;
     4772                if (XCheckIfEvent(X11->display, &mouseMotionEvent, &qt_mouseMotion_scanner, (XPointer) &tabletMotionData)) {
     4773                    reinsertMouseEvent = true;
     4774                } else {
     4775                    break;
     4776                }
     4777
     4778                // Now discard any duplicate tablet events.
     4779                tabletMotionData.error = false;
     4780                XEvent dummy;
     4781                while (XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) {
     4782                    // just discard the event
     4783                }
     4784            }
     4785
     4786            if (reinsertMouseEvent) {
     4787                XPutBackEvent(X11->display, &mouseMotionEvent);
     4788            }
     4789        }
     4790    }
    48624791    return true;
    48634792}
     
    50564985}
    50574986
     4987
    50584988//
    50594989// Paint event translation
     
    52345164                }
    52355165            }
     5166#ifndef QT_NO_XSYNC
     5167            qt_sync_request_event_data sync_event;
     5168            sync_event.window = internalWinId();
     5169            for (XEvent ev;;) {
     5170                if (!XCheckIfEvent(X11->display, &ev, &qt_sync_request_scanner, (XPointer)&sync_event))
     5171                    break;
     5172            }
     5173#endif // QT_NO_XSYNC
    52365174        }
    52375175
     
    53195257            d->extra->topextra->inTopLevelResize = false;
    53205258    }
     5259#ifndef QT_NO_XSYNC
     5260    if (QTLWExtra *tlwExtra = d->maybeTopData()) {
     5261        if (tlwExtra->newCounterValueLo != 0 || tlwExtra->newCounterValueHi != 0) {
     5262            XSyncValue value;
     5263            XSyncIntsToValue(&value,
     5264                             tlwExtra->newCounterValueLo,
     5265                             tlwExtra->newCounterValueHi);
     5266
     5267            XSyncSetCounter(X11->display, tlwExtra->syncUpdateCounter, value);
     5268            tlwExtra->newCounterValueHi = 0;
     5269            tlwExtra->newCounterValueLo = 0;
     5270        }
     5271    }
     5272#endif
    53215273    return true;
    53225274}
     
    54425394public:
    54435395    QSessionManagerPrivate(QSessionManager* mgr, QString& id, QString& key)
    5444         : QObjectPrivate(), sm(mgr), sessionId(id), sessionKey(key), eventLoop(0) {}
     5396        : QObjectPrivate(), sm(mgr), sessionId(id), sessionKey(key),
     5397            restartHint(QSessionManager::RestartIfRunning), eventLoop(0) {}
    54455398    QSessionManager* sm;
    54465399    QStringList restartCommand;
     
    59355888#endif // QT_NO_SESSIONMANAGER
    59365889
     5890#if defined(QT_RX71_MULTITOUCH)
     5891
     5892static inline int testBit(const char *array, int bit)
     5893{
     5894    return (array[bit/8] & (1<<(bit%8)));
     5895}
     5896
     5897static int openRX71Device(const QByteArray &deviceName)
     5898{
     5899    int fd = open(deviceName, O_RDONLY | O_NONBLOCK);
     5900    if (fd == -1) {
     5901        fd = -errno;
     5902        return fd;
     5903    }
     5904
     5905    // fetch the event type mask and check that the device reports absolute coordinates
     5906    char eventTypeMask[(EV_MAX + sizeof(char) - 1) * sizeof(char) + 1];
     5907    memset(eventTypeMask, 0, sizeof(eventTypeMask));
     5908    if (ioctl(fd, EVIOCGBIT(0, sizeof(eventTypeMask)), eventTypeMask) < 0) {
     5909        close(fd);
     5910        return -1;
     5911    }
     5912    if (!testBit(eventTypeMask, EV_ABS)) {
     5913        close(fd);
     5914        return -1;
     5915    }
     5916
     5917    // make sure that we can get the absolute X and Y positions from the device
     5918    char absMask[(ABS_MAX + sizeof(char) - 1) * sizeof(char) + 1];
     5919    memset(absMask, 0, sizeof(absMask));
     5920    if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absMask)), absMask) < 0) {
     5921        close(fd);
     5922        return -1;
     5923    }
     5924    if (!testBit(absMask, ABS_X) || !testBit(absMask, ABS_Y)) {
     5925        close(fd);
     5926        return -1;
     5927    }
     5928
     5929    return fd;
     5930}
     5931
     5932void QApplicationPrivate::initializeMultitouch_sys()
     5933{
     5934    Q_Q(QApplication);
     5935
     5936    QByteArray deviceName = QByteArray("/dev/input/event");
     5937    int currentDeviceNumber = 0;
     5938    for (;;) {
     5939        int fd = openRX71Device(QByteArray(deviceName + QByteArray::number(currentDeviceNumber++)));
     5940        if (fd == -ENOENT) {
     5941            // no more devices
     5942            break;
     5943        }
     5944        if (fd < 0) {
     5945            // not a touch device
     5946            continue;
     5947        }
     5948
     5949        struct input_absinfo abs_x, abs_y, abs_z;
     5950        ioctl(fd, EVIOCGABS(ABS_X), &abs_x);
     5951        ioctl(fd, EVIOCGABS(ABS_Y), &abs_y);
     5952        ioctl(fd, EVIOCGABS(ABS_Z), &abs_z);
     5953
     5954        int deviceNumber = allRX71TouchPoints.count();
     5955
     5956        QSocketNotifier *socketNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, q);
     5957        QObject::connect(socketNotifier, SIGNAL(activated(int)), q, SLOT(_q_readRX71MultiTouchEvents()));
     5958
     5959        RX71TouchPointState touchPointState = {
     5960            socketNotifier,
     5961            QTouchEvent::TouchPoint(deviceNumber),
     5962
     5963            abs_x.minimum, abs_x.maximum, q->desktop()->screenGeometry().width(),
     5964            abs_y.minimum, abs_y.maximum, q->desktop()->screenGeometry().height(),
     5965            abs_z.minimum, abs_z.maximum
     5966        };
     5967        allRX71TouchPoints.append(touchPointState);
     5968    }
     5969
     5970    hasRX71MultiTouch = allRX71TouchPoints.count() > 1;
     5971    if (!hasRX71MultiTouch) {
     5972        for (int i = 0; i < allRX71TouchPoints.count(); ++i) {
     5973            QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier;
     5974            close(socketNotifier->socket());
     5975            delete socketNotifier;
     5976        }
     5977        allRX71TouchPoints.clear();
     5978    }
     5979}
     5980
     5981void QApplicationPrivate::cleanupMultitouch_sys()
     5982{
     5983    hasRX71MultiTouch = false;
     5984    for (int i = 0; i < allRX71TouchPoints.count(); ++i) {
     5985        QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier;
     5986        close(socketNotifier->socket());
     5987        delete socketNotifier;
     5988    }
     5989    allRX71TouchPoints.clear();
     5990}
     5991
     5992bool QApplicationPrivate::readRX71MultiTouchEvents(int deviceNumber)
     5993{
     5994    RX71TouchPointState &touchPointState = allRX71TouchPoints[deviceNumber];
     5995    QSocketNotifier *socketNotifier = touchPointState.socketNotifier;
     5996    int fd = socketNotifier->socket();
     5997
     5998    QTouchEvent::TouchPoint &touchPoint = touchPointState.touchPoint;
     5999
     6000    bool down = touchPoint.state() != Qt::TouchPointReleased;
     6001    if (down)
     6002        touchPoint.setState(Qt::TouchPointStationary);
     6003
     6004    bool changed = false;
     6005    for (;;) {
     6006        struct input_event inputEvent;
     6007        int bytesRead = read(fd, &inputEvent, sizeof(inputEvent));
     6008        if (bytesRead <= 0)
     6009            break;
     6010        if (bytesRead != sizeof(inputEvent)) {
     6011            qWarning("Qt: INTERNAL ERROR: short read in readRX71MultiTouchEvents()");
     6012            return false;
     6013        }
     6014
     6015        switch (inputEvent.type) {
     6016        case EV_SYN:
     6017            changed = true;
     6018            switch (touchPoint.state()) {
     6019            case Qt::TouchPointPressed:
     6020            case Qt::TouchPointReleased:
     6021                // make sure we don't compress pressed and releases with any other events
     6022                return changed;
     6023            default:
     6024                break;
     6025            }
     6026            continue;
     6027        case EV_KEY:
     6028        case EV_ABS:
     6029            break;
     6030        default:
     6031            qWarning("Qt: WARNING: unknown event type %d on multitouch device", inputEvent.type);
     6032            continue;
     6033        }
     6034
     6035        QPointF screenPos = touchPoint.screenPos();
     6036        switch (inputEvent.code) {
     6037        case BTN_TOUCH:
     6038            if (!down && inputEvent.value != 0)
     6039                touchPoint.setState(Qt::TouchPointPressed);
     6040            else if (down && inputEvent.value == 0)
     6041                touchPoint.setState(Qt::TouchPointReleased);
     6042            break;
     6043        case ABS_TOOL_WIDTH:
     6044        case ABS_VOLUME:
     6045        case ABS_PRESSURE:
     6046            // ignore for now
     6047            break;
     6048        case ABS_X:
     6049        {
     6050            qreal newValue = ((qreal(inputEvent.value - touchPointState.minX)
     6051                              / qreal(touchPointState.maxX - touchPointState.minX))
     6052                              * touchPointState.scaleX);
     6053            screenPos.rx() = newValue;
     6054            touchPoint.setScreenPos(screenPos);
     6055            break;
     6056        }
     6057        case ABS_Y:
     6058        {
     6059            qreal newValue = ((qreal(inputEvent.value - touchPointState.minY)
     6060                              / qreal(touchPointState.maxY - touchPointState.minY))
     6061                              * touchPointState.scaleY);
     6062            screenPos.ry() = newValue;
     6063            touchPoint.setScreenPos(screenPos);
     6064            break;
     6065        }
     6066        case ABS_Z:
     6067        {
     6068            // map Z (signal strength) to pressure for now
     6069            qreal newValue = (qreal(inputEvent.value - touchPointState.minZ)
     6070                              / qreal(touchPointState.maxZ - touchPointState.minZ));
     6071            touchPoint.setPressure(newValue);
     6072            break;
     6073        }
     6074        default:
     6075            qWarning("Qt: WARNING: unknown event code %d on multitouch device", inputEvent.code);
     6076            continue;
     6077        }
     6078    }
     6079
     6080    if (down && touchPoint.state() != Qt::TouchPointReleased)
     6081        touchPoint.setState(changed ? Qt::TouchPointMoved : Qt::TouchPointStationary);
     6082
     6083    return changed;
     6084}
     6085
     6086void QApplicationPrivate::_q_readRX71MultiTouchEvents()
     6087{
     6088    // read touch events from all devices
     6089    bool changed = false;
     6090    for (int i = 0; i < allRX71TouchPoints.count(); ++i)
     6091        changed = readRX71MultiTouchEvents(i) || changed;
     6092    if (!changed)
     6093        return;
     6094
     6095    QList<QTouchEvent::TouchPoint> touchPoints;
     6096    for (int i = 0; i < allRX71TouchPoints.count(); ++i)
     6097        touchPoints.append(allRX71TouchPoints.at(i).touchPoint);
     6098
     6099    translateRawTouchEvent(0, QTouchEvent::TouchScreen, touchPoints);
     6100}
     6101
     6102#else // !QT_RX71_MULTITOUCH
     6103
     6104void QApplicationPrivate::initializeMultitouch_sys()
     6105{ }
     6106void QApplicationPrivate::cleanupMultitouch_sys()
     6107{ }
     6108
     6109#endif // QT_RX71_MULTITOUCH
     6110
    59376111QT_END_NAMESPACE
Note: See TracChangeset for help on using the changeset viewer.