src/gui/kernel/qwidget_x11.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    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.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qevent.h"
       
    43 #include "qwidget.h"
       
    44 #include "qdesktopwidget.h"
       
    45 #include "qapplication.h"
       
    46 #include "qapplication_p.h"
       
    47 #include "qnamespace.h"
       
    48 #include "qpainter.h"
       
    49 #include "qbitmap.h"
       
    50 #include "qlayout.h"
       
    51 #include "qtextcodec.h"
       
    52 #include "qdatetime.h"
       
    53 #include "qcursor.h"
       
    54 #include "qstack.h"
       
    55 #include "qcolormap.h"
       
    56 #include "qdebug.h"
       
    57 #include "qmenu.h"
       
    58 #include "private/qmenu_p.h"
       
    59 #include "private/qbackingstore_p.h"
       
    60 #include "private/qwindowsurface_x11_p.h"
       
    61 
       
    62 //extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); //qapplication_x11.cpp
       
    63 
       
    64 #include <private/qpixmap_x11_p.h>
       
    65 #include <private/qpaintengine_x11_p.h>
       
    66 #include "qt_x11_p.h"
       
    67 #include "qx11info_x11.h"
       
    68 
       
    69 #include <stdlib.h>
       
    70 
       
    71 //#define ALIEN_DEBUG
       
    72 
       
    73 // defined in qapplication_x11.cpp
       
    74 //bool qt_wstate_iconified(WId);
       
    75 //void qt_updated_rootinfo();
       
    76 
       
    77 
       
    78 #if !defined(QT_NO_IM)
       
    79 #include "qinputcontext.h"
       
    80 #include "qinputcontextfactory.h"
       
    81 #endif
       
    82 
       
    83 #include "qwidget_p.h"
       
    84 
       
    85 #define XCOORD_MAX 16383
       
    86 #define WRECT_MAX 8191
       
    87 
       
    88 QT_BEGIN_NAMESPACE
       
    89 
       
    90 extern bool qt_nograb();
       
    91 
       
    92 QWidget *QWidgetPrivate::mouseGrabber = 0;
       
    93 QWidget *QWidgetPrivate::keyboardGrabber = 0;
       
    94 
       
    95 void qt_net_remove_user_time(QWidget *tlw);
       
    96 void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
       
    97 
       
    98 int qt_x11_create_desktop_on_screen = -1;
       
    99 
       
   100 extern void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
       
   101 
       
   102 // MWM support
       
   103 struct QtMWMHints {
       
   104     ulong flags, functions, decorations;
       
   105     long input_mode;
       
   106     ulong status;
       
   107 };
       
   108 
       
   109 enum {
       
   110     MWM_HINTS_FUNCTIONS   = (1L << 0),
       
   111 
       
   112     MWM_FUNC_ALL      = (1L << 0),
       
   113     MWM_FUNC_RESIZE   = (1L << 1),
       
   114     MWM_FUNC_MOVE     = (1L << 2),
       
   115     MWM_FUNC_MINIMIZE = (1L << 3),
       
   116     MWM_FUNC_MAXIMIZE = (1L << 4),
       
   117     MWM_FUNC_CLOSE    = (1L << 5),
       
   118 
       
   119     MWM_HINTS_DECORATIONS = (1L << 1),
       
   120 
       
   121     MWM_DECOR_ALL      = (1L << 0),
       
   122     MWM_DECOR_BORDER   = (1L << 1),
       
   123     MWM_DECOR_RESIZEH  = (1L << 2),
       
   124     MWM_DECOR_TITLE    = (1L << 3),
       
   125     MWM_DECOR_MENU     = (1L << 4),
       
   126     MWM_DECOR_MINIMIZE = (1L << 5),
       
   127     MWM_DECOR_MAXIMIZE = (1L << 6),
       
   128 
       
   129     MWM_HINTS_INPUT_MODE = (1L << 2),
       
   130 
       
   131     MWM_INPUT_MODELESS                  = 0L,
       
   132     MWM_INPUT_PRIMARY_APPLICATION_MODAL = 1L,
       
   133     MWM_INPUT_FULL_APPLICATION_MODAL    = 3L
       
   134 };
       
   135 
       
   136 
       
   137 static QtMWMHints GetMWMHints(Display *display, Window window)
       
   138 {
       
   139     QtMWMHints mwmhints;
       
   140 
       
   141     Atom type;
       
   142     int format;
       
   143     ulong nitems, bytesLeft;
       
   144     uchar *data = 0;
       
   145     if ((XGetWindowProperty(display, window, ATOM(_MOTIF_WM_HINTS), 0, 5, false,
       
   146                             ATOM(_MOTIF_WM_HINTS), &type, &format, &nitems, &bytesLeft,
       
   147                             &data) == Success)
       
   148         && (type == ATOM(_MOTIF_WM_HINTS)
       
   149             && format == 32
       
   150             && nitems >= 5)) {
       
   151         mwmhints = *(reinterpret_cast<QtMWMHints *>(data));
       
   152     } else {
       
   153         mwmhints.flags = 0L;
       
   154         mwmhints.functions = MWM_FUNC_ALL;
       
   155         mwmhints.decorations = MWM_DECOR_ALL;
       
   156         mwmhints.input_mode = 0L;
       
   157         mwmhints.status = 0L;
       
   158     }
       
   159 
       
   160     if (data)
       
   161         XFree(data);
       
   162 
       
   163     return mwmhints;
       
   164 }
       
   165 
       
   166 static void SetMWMHints(Display *display, Window window, const QtMWMHints &mwmhints)
       
   167 {
       
   168     if (mwmhints.flags != 0l) {
       
   169         XChangeProperty(display, window, ATOM(_MOTIF_WM_HINTS), ATOM(_MOTIF_WM_HINTS), 32,
       
   170                         PropModeReplace, (unsigned char *) &mwmhints, 5);
       
   171     } else {
       
   172         XDeleteProperty(display, window, ATOM(_MOTIF_WM_HINTS));
       
   173     }
       
   174 }
       
   175 
       
   176 // Returns true if we should set WM_TRANSIENT_FOR on \a w
       
   177 static inline bool isTransient(const QWidget *w)
       
   178 {
       
   179     return ((w->windowType() == Qt::Dialog
       
   180              || w->windowType() == Qt::Sheet
       
   181              || w->windowType() == Qt::Tool
       
   182              || w->windowType() == Qt::SplashScreen
       
   183              || w->windowType() == Qt::ToolTip
       
   184              || w->windowType() == Qt::Drawer
       
   185              || w->windowType() == Qt::Popup)
       
   186             && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
       
   187 }
       
   188 
       
   189 static void do_size_hints(QWidget* widget, QWExtra *x);
       
   190 
       
   191 /*****************************************************************************
       
   192   QWidget member functions
       
   193  *****************************************************************************/
       
   194 
       
   195 const uint stdWidgetEventMask =                        // X event mask
       
   196         (uint)(
       
   197             KeyPressMask | KeyReleaseMask |
       
   198             ButtonPressMask | ButtonReleaseMask |
       
   199             KeymapStateMask |
       
   200             ButtonMotionMask | PointerMotionMask |
       
   201             EnterWindowMask | LeaveWindowMask |
       
   202             FocusChangeMask |
       
   203             ExposureMask |
       
   204             PropertyChangeMask |
       
   205             StructureNotifyMask
       
   206        );
       
   207 
       
   208 const uint stdDesktopEventMask =                        // X event mask
       
   209        (uint)(
       
   210            KeymapStateMask |
       
   211            EnterWindowMask | LeaveWindowMask |
       
   212            PropertyChangeMask
       
   213       );
       
   214 
       
   215 
       
   216 /*
       
   217   The qt_ functions below are implemented in qwidgetcreate_x11.cpp.
       
   218 */
       
   219 
       
   220 Window qt_XCreateWindow(const QWidget *creator,
       
   221                          Display *display, Window parent,
       
   222                          int x, int y, uint w, uint h,
       
   223                          int borderwidth, int depth,
       
   224                          uint windowclass, Visual *visual,
       
   225                          ulong valuemask, XSetWindowAttributes *attributes);
       
   226 Window qt_XCreateSimpleWindow(const QWidget *creator,
       
   227                                Display *display, Window parent,
       
   228                                int x, int y, uint w, uint h, int borderwidth,
       
   229                                ulong border, ulong background);
       
   230 void qt_XDestroyWindow(const QWidget *destroyer,
       
   231                         Display *display, Window window);
       
   232 
       
   233 
       
   234 static void qt_insert_sip(QWidget* scrolled_widget, int dx, int dy)
       
   235 {
       
   236     if (!scrolled_widget->isWindow() && !scrolled_widget->internalWinId())
       
   237         return;
       
   238     QX11Data::ScrollInProgress sip = { X11->sip_serial++, scrolled_widget, dx, dy };
       
   239     X11->sip_list.append(sip);
       
   240 
       
   241     XClientMessageEvent client_message;
       
   242     client_message.type = ClientMessage;
       
   243     client_message.window = scrolled_widget->internalWinId();
       
   244     client_message.format = 32;
       
   245     client_message.message_type = ATOM(_QT_SCROLL_DONE);
       
   246     client_message.data.l[0] = sip.id;
       
   247 
       
   248     XSendEvent(X11->display, scrolled_widget->internalWinId(), False, NoEventMask,
       
   249         (XEvent*)&client_message);
       
   250 }
       
   251 
       
   252 static int qt_sip_count(QWidget* scrolled_widget)
       
   253 {
       
   254     int sips=0;
       
   255 
       
   256     for (int i = 0; i < X11->sip_list.size(); ++i) {
       
   257         const QX11Data::ScrollInProgress &sip = X11->sip_list.at(i);
       
   258         if (sip.scrolled_widget == scrolled_widget)
       
   259             sips++;
       
   260     }
       
   261 
       
   262     return sips;
       
   263 }
       
   264 
       
   265 static void create_wm_client_leader()
       
   266 {
       
   267     if (X11->wm_client_leader) return;
       
   268 
       
   269     X11->wm_client_leader =
       
   270         XCreateSimpleWindow(X11->display,
       
   271                              QX11Info::appRootWindow(),
       
   272                              0, 0, 1, 1, 0, 0, 0);
       
   273 
       
   274     // set client leader property to itself
       
   275     XChangeProperty(X11->display,
       
   276                      X11->wm_client_leader, ATOM(WM_CLIENT_LEADER),
       
   277                      XA_WINDOW, 32, PropModeReplace,
       
   278                      (unsigned char *)&X11->wm_client_leader, 1);
       
   279 
       
   280 #ifndef QT_NO_SESSIONMANAGER
       
   281     // If we are session managed, inform the window manager about it
       
   282     QByteArray session = qApp->sessionId().toLatin1();
       
   283     if (!session.isEmpty()) {
       
   284         XChangeProperty(X11->display,
       
   285                          X11->wm_client_leader, ATOM(SM_CLIENT_ID),
       
   286                          XA_STRING, 8, PropModeReplace,
       
   287                          (unsigned char *)session.data(), session.size());
       
   288     }
       
   289 #endif
       
   290 }
       
   291 
       
   292 /*!
       
   293    \internal
       
   294    Update the X11 cursor of the widget w.
       
   295    \a force is true if this function is called from dispatchEnterLeave, it means that the
       
   296    mouse is actually directly under this widget.
       
   297  */
       
   298 void qt_x11_enforce_cursor(QWidget * w, bool force)
       
   299 {
       
   300     if (!w->testAttribute(Qt::WA_WState_Created))
       
   301         return;
       
   302 
       
   303     static QPointer<QWidget> lastUnderMouse = 0;
       
   304     if (force) {
       
   305         lastUnderMouse = w;
       
   306     } else if (lastUnderMouse && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
       
   307         w = lastUnderMouse;
       
   308     } else if (!w->internalWinId()) {
       
   309         return; //the mouse is not under this widget, and it's not native, so don't change it
       
   310     }
       
   311 
       
   312     while (!w->internalWinId() && w->parentWidget() && !w->isWindow() && !w->testAttribute(Qt::WA_SetCursor))
       
   313         w = w->parentWidget();
       
   314 
       
   315     QWidget *nativeParent = w;
       
   316     if (!w->internalWinId())
       
   317         nativeParent = w->nativeParentWidget();
       
   318     // This does the same as effectiveWinId(), but since it is possible
       
   319     // to not have a native parent widget due to a special hack in
       
   320     // qwidget for reparenting widgets to a different X11 screen,
       
   321     // added additional check to make sure native parent widget exists.
       
   322     if (!nativeParent || !nativeParent->internalWinId())
       
   323         return;
       
   324     WId winid = nativeParent->internalWinId();
       
   325 
       
   326     if (w->isWindow() || w->testAttribute(Qt::WA_SetCursor)) {
       
   327 #ifndef QT_NO_CURSOR
       
   328         QCursor *oc = QApplication::overrideCursor();
       
   329         if (oc) {
       
   330             XDefineCursor(X11->display, winid, oc->handle());
       
   331         } else if (w->isEnabled()) {
       
   332             XDefineCursor(X11->display, winid, w->cursor().handle());
       
   333         } else {
       
   334             // enforce the windows behavior of clearing the cursor on
       
   335             // disabled widgets
       
   336             XDefineCursor(X11->display, winid, XNone);
       
   337         }
       
   338 #endif
       
   339     } else {
       
   340         XDefineCursor(X11->display, winid, XNone);
       
   341     }
       
   342 }
       
   343 
       
   344 Q_GUI_EXPORT void qt_x11_enforce_cursor(QWidget * w)
       
   345 {
       
   346     qt_x11_enforce_cursor(w, false);
       
   347 }
       
   348 
       
   349 static Bool checkForConfigureAndExpose(Display *, XEvent *e, XPointer)
       
   350 {
       
   351     return e->type == ConfigureNotify || e->type == Expose;
       
   352 }
       
   353 
       
   354 Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
       
   355 {
       
   356     if (!w || (!w->isWindow() && !w->internalWinId()))
       
   357         return;
       
   358     QApplication::flush();
       
   359     XEvent ev;
       
   360     QTime t;
       
   361     t.start();
       
   362     static const int maximumWaitTime = 2000;
       
   363     if (!w->testAttribute(Qt::WA_WState_Created))
       
   364         return;
       
   365 
       
   366     if (!(w->windowFlags() & Qt::X11BypassWindowManagerHint)) {
       
   367         // if the window is not override-redirect, then the window manager
       
   368         // will reparent us to the frame decoration window.
       
   369         while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ReparentNotify, &ev)) {
       
   370             if (t.elapsed() > maximumWaitTime)
       
   371                 return;
       
   372             qApp->syncX(); // non-busy wait
       
   373         }
       
   374     }
       
   375 
       
   376     while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), MapNotify, &ev)) {
       
   377         if (t.elapsed() > maximumWaitTime)
       
   378             return;
       
   379         qApp->syncX(); // non-busy wait
       
   380     }
       
   381 
       
   382     qApp->x11ProcessEvent(&ev);
       
   383 
       
   384     // ok, seems like the window manager successfully reparented us, we'll wait
       
   385     // for the first paint event to arrive, while handling ConfigureNotify in
       
   386     // the arrival order
       
   387     while(1)
       
   388     {
       
   389         if (XCheckIfEvent(X11->display, &ev, checkForConfigureAndExpose, 0)) {
       
   390             qApp->x11ProcessEvent(&ev);
       
   391             if (ev.type == Expose)
       
   392                 return;
       
   393         }
       
   394         if (t.elapsed() > maximumWaitTime)
       
   395             return;
       
   396         qApp->syncX(); // non-busy wait
       
   397     }
       
   398 }
       
   399 
       
   400 void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0)
       
   401 {
       
   402     if (!w->isVisible()) // not managed by the window manager
       
   403         return;
       
   404 
       
   405     XEvent e;
       
   406     e.xclient.type = ClientMessage;
       
   407     e.xclient.message_type = ATOM(_NET_WM_STATE);
       
   408     e.xclient.display = X11->display;
       
   409     e.xclient.window = w->internalWinId();
       
   410     e.xclient.format = 32;
       
   411     e.xclient.data.l[0] = set ? 1 : 0;
       
   412     e.xclient.data.l[1] = one;
       
   413     e.xclient.data.l[2] = two;
       
   414     e.xclient.data.l[3] = 0;
       
   415     e.xclient.data.l[4] = 0;
       
   416     XSendEvent(X11->display, RootWindow(X11->display, w->x11Info().screen()),
       
   417                false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
       
   418 }
       
   419 
       
   420 struct QX11WindowAttributes {
       
   421     const XWindowAttributes *att;
       
   422 };
       
   423 
       
   424 void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const XWindowAttributes &a)
       
   425 {
       
   426     QX11WindowAttributes att;
       
   427     att.att = &a;
       
   428     qt_x11_getX11InfoForWindow(xinfo,att);
       
   429 }
       
   430 
       
   431 
       
   432 static QVector<Atom> getNetWmState(QWidget *w)
       
   433 {
       
   434     QVector<Atom> returnValue;
       
   435 
       
   436     // Don't read anything, just get the size of the property data
       
   437     Atom actualType;
       
   438     int actualFormat;
       
   439     ulong propertyLength;
       
   440     ulong bytesLeft;
       
   441     uchar *propertyData = 0;
       
   442     if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0, 0,
       
   443                            False, XA_ATOM, &actualType, &actualFormat,
       
   444                            &propertyLength, &bytesLeft, &propertyData) == Success
       
   445         && actualType == XA_ATOM && actualFormat == 32) {
       
   446         returnValue.resize(bytesLeft / 4);
       
   447         XFree((char*) propertyData);
       
   448 
       
   449         // fetch all data
       
   450         if (XGetWindowProperty(X11->display, w->internalWinId(), ATOM(_NET_WM_STATE), 0,
       
   451                                returnValue.size(), False, XA_ATOM, &actualType, &actualFormat,
       
   452                                &propertyLength, &bytesLeft, &propertyData) != Success) {
       
   453             returnValue.clear();
       
   454         } else if (propertyLength != (ulong)returnValue.size()) {
       
   455             returnValue.resize(propertyLength);
       
   456         }
       
   457 
       
   458         // put it into netWmState
       
   459         if (!returnValue.isEmpty()) {
       
   460             memcpy(returnValue.data(), propertyData, returnValue.size() * sizeof(Atom));
       
   461         }
       
   462         XFree((char*) propertyData);
       
   463     }
       
   464 
       
   465     return returnValue;
       
   466 }
       
   467 
       
   468 void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
       
   469 {
       
   470     Q_Q(QWidget);
       
   471     Qt::WindowType type = q->windowType();
       
   472     Qt::WindowFlags &flags = data.window_flags;
       
   473     QWidget *parentWidget = q->parentWidget();
       
   474 
       
   475     if (type == Qt::ToolTip)
       
   476         flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint;
       
   477     if (type == Qt::Popup)
       
   478         flags |= Qt::X11BypassWindowManagerHint;
       
   479 
       
   480     bool topLevel = (flags & Qt::Window);
       
   481     bool popup = (type == Qt::Popup);
       
   482     bool dialog = (type == Qt::Dialog
       
   483                    || type == Qt::Sheet);
       
   484     bool desktop = (type == Qt::Desktop);
       
   485     bool tool = (type == Qt::Tool || type == Qt::SplashScreen
       
   486                  || type == Qt::ToolTip || type == Qt::Drawer);
       
   487 
       
   488 #ifdef ALIEN_DEBUG
       
   489     qDebug() << "QWidgetPrivate::create_sys START:" << q << "topLevel?" << topLevel << "WId:"
       
   490              << window << "initializeWindow:" << initializeWindow << "destroyOldWindow" << destroyOldWindow;
       
   491 #endif
       
   492     if (topLevel) {
       
   493         if (parentWidget) { // if our parent stays on top, so must we
       
   494             QWidget *ptl = parentWidget->window();
       
   495             if(ptl && (ptl->windowFlags() & Qt::WindowStaysOnTopHint))
       
   496                 flags |= Qt::WindowStaysOnTopHint;
       
   497         }
       
   498 
       
   499         if (type == Qt::SplashScreen) {
       
   500             if (X11->isSupportedByWM(ATOM(_NET_WM_WINDOW_TYPE_SPLASH))) {
       
   501                 flags &= ~Qt::X11BypassWindowManagerHint;
       
   502             } else {
       
   503                 flags |= Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint;
       
   504             }
       
   505         }
       
   506         // All these buttons depend on the system menu, so we enable it
       
   507         if (flags & (Qt::WindowMinimizeButtonHint
       
   508                      | Qt::WindowMaximizeButtonHint
       
   509                      | Qt::WindowContextHelpButtonHint))
       
   510             flags |= Qt::WindowSystemMenuHint;
       
   511     }
       
   512 
       
   513 
       
   514     Window parentw, destroyw = 0;
       
   515     WId id = 0;
       
   516 
       
   517     // always initialize
       
   518     if (!window)
       
   519         initializeWindow = true;
       
   520 
       
   521     QX11Info *parentXinfo = parentWidget ? &parentWidget->d_func()->xinfo : 0;
       
   522 
       
   523     if (desktop &&
       
   524         qt_x11_create_desktop_on_screen >= 0 &&
       
   525         qt_x11_create_desktop_on_screen != xinfo.screen()) {
       
   526         // desktop on a certain screen other than the default requested
       
   527         QX11InfoData *xd = &X11->screens[qt_x11_create_desktop_on_screen];
       
   528         xinfo.setX11Data(xd);
       
   529     } else if (parentXinfo && (parentXinfo->screen() != xinfo.screen()
       
   530                                || parentXinfo->visual() != xinfo.visual()))
       
   531     {
       
   532         xinfo = *parentXinfo;
       
   533     }
       
   534 
       
   535     //get display, screen number, root window and desktop geometry for
       
   536     //the current screen
       
   537     Display *dpy = X11->display;
       
   538     int scr = xinfo.screen();
       
   539     Window root_win = RootWindow(dpy, scr);
       
   540     int sw = DisplayWidth(dpy,scr);
       
   541     int sh = DisplayHeight(dpy,scr);
       
   542 
       
   543     if (desktop) {                                // desktop widget
       
   544         dialog = popup = false;                        // force these flags off
       
   545         data.crect.setRect(0, 0, sw, sh);
       
   546     } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) {
       
   547         QDesktopWidget *desktopWidget = qApp->desktop();
       
   548         if (desktopWidget->isVirtualDesktop()) {
       
   549             QRect r = desktopWidget->screenGeometry();
       
   550             sw = r.width();
       
   551             sh = r.height();
       
   552         }
       
   553 
       
   554         int width = sw / 2;
       
   555         int height = 4 * sh / 10;
       
   556         if (extra) {
       
   557             width = qMax(qMin(width, extra->maxw), extra->minw);
       
   558             height = qMax(qMin(height, extra->maxh), extra->minh);
       
   559         }
       
   560         data.crect.setSize(QSize(width, height));
       
   561     }
       
   562 
       
   563     parentw = topLevel ? root_win : parentWidget->effectiveWinId();
       
   564 
       
   565     XSetWindowAttributes wsa;
       
   566 
       
   567     if (window) {                                // override the old window
       
   568         if (destroyOldWindow) {
       
   569             if (topLevel)
       
   570                 X11->dndEnable(q, false);
       
   571             destroyw = data.winid;
       
   572         }
       
   573         id = window;
       
   574         setWinId(window);
       
   575         XWindowAttributes a;
       
   576         XGetWindowAttributes(dpy, window, &a);
       
   577         data.crect.setRect(a.x, a.y, a.width, a.height);
       
   578 
       
   579         if (a.map_state == IsUnmapped)
       
   580             q->setAttribute(Qt::WA_WState_Visible, false);
       
   581         else
       
   582             q->setAttribute(Qt::WA_WState_Visible);
       
   583 
       
   584         qt_x11_getX11InfoForWindow(&xinfo,a);
       
   585 
       
   586     } else if (desktop) {                        // desktop widget
       
   587 #ifdef QWIDGET_EXTRA_DEBUG
       
   588         qDebug() << "create desktop";
       
   589 #endif
       
   590         id = (WId)parentw;                        // id = root window
       
   591 //         QWidget *otherDesktop = find(id);        // is there another desktop?
       
   592 //         if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
       
   593 //             otherDesktop->d->setWinId(0);        // remove id from widget mapper
       
   594 //             d->setWinId(id);                     // make sure otherDesktop is
       
   595 //             otherDesktop->d->setWinId(id);       // found first
       
   596 //         } else {
       
   597         setWinId(id);
       
   598 //         }
       
   599     } else if (topLevel || q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) {
       
   600 #ifdef QWIDGET_EXTRA_DEBUG
       
   601         static int topLevels = 0;
       
   602         static int children = 0;
       
   603         if (parentw == root_win)
       
   604             qDebug() << "create toplevel" << ++topLevels;
       
   605         else
       
   606             qDebug() << "create child" << ++children;
       
   607 #endif
       
   608         QRect safeRect = data.crect; //##### must handle huge sizes as well.... i.e. wrect
       
   609         if (safeRect.width() < 1|| safeRect.height() < 1) {
       
   610             if (topLevel) {
       
   611                 // top-levels must be at least 1x1
       
   612                 safeRect.setSize(safeRect.size().expandedTo(QSize(1, 1)));
       
   613             } else {
       
   614                 // create it way off screen, and rely on
       
   615                 // setWSGeometry() to do the right thing with it later
       
   616                 safeRect = QRect(-1000,-1000,1,1);
       
   617             }
       
   618         }
       
   619 #ifndef QT_NO_XRENDER
       
   620         int screen = xinfo.screen();
       
   621         if (topLevel && X11->use_xrender
       
   622             && xinfo.depth() != 32 && X11->argbVisuals[screen]
       
   623             && q->testAttribute(Qt::WA_TranslucentBackground))
       
   624         {
       
   625             QX11InfoData *xd = xinfo.getX11Data(true);
       
   626 
       
   627             xd->screen = screen;
       
   628             xd->visual = X11->argbVisuals[screen];
       
   629             xd->colormap = X11->argbColormaps[screen];
       
   630             xd->depth = 32;
       
   631             xd->defaultVisual = false;
       
   632             xd->defaultColormap = false;
       
   633             xd->cells = xd->visual->map_entries;
       
   634             xinfo.setX11Data(xd);
       
   635         }
       
   636 #endif
       
   637         if (xinfo.defaultVisual() && xinfo.defaultColormap()) {
       
   638             id = (WId)qt_XCreateSimpleWindow(q, dpy, parentw,
       
   639                                              safeRect.left(), safeRect.top(),
       
   640                                              safeRect.width(), safeRect.height(),
       
   641                                              0,
       
   642                                              BlackPixel(dpy, xinfo.screen()),
       
   643                                              WhitePixel(dpy, xinfo.screen()));
       
   644         } else {
       
   645             wsa.background_pixel = WhitePixel(dpy, xinfo.screen());
       
   646             wsa.border_pixel = BlackPixel(dpy, xinfo.screen());
       
   647             wsa.colormap = xinfo.colormap();
       
   648             id = (WId)qt_XCreateWindow(q, dpy, parentw,
       
   649                                        safeRect.left(), safeRect.top(),
       
   650                                        safeRect.width(), safeRect.height(),
       
   651                                        0, xinfo.depth(), InputOutput,
       
   652                                        (Visual *) xinfo.visual(),
       
   653                                        CWBackPixel|CWBorderPixel|CWColormap,
       
   654                                        &wsa);
       
   655         }
       
   656 
       
   657         setWinId(id);                                // set widget id/handle + hd
       
   658     }
       
   659 
       
   660 #ifndef QT_NO_XRENDER
       
   661     if (picture) {
       
   662         XRenderFreePicture(X11->display, picture);
       
   663         picture = 0;
       
   664     }
       
   665 
       
   666     if (X11->use_xrender && !desktop && q->internalWinId()) {
       
   667         XRenderPictFormat *format = XRenderFindVisualFormat(dpy, (Visual *) xinfo.visual());
       
   668         if (format)
       
   669             picture = XRenderCreatePicture(dpy, id, format, 0, 0);
       
   670     }
       
   671 #endif // QT_NO_XRENDER
       
   672 
       
   673     QtMWMHints mwmhints;
       
   674     mwmhints.flags = 0L;
       
   675     mwmhints.functions = 0L;
       
   676     mwmhints.decorations = 0;
       
   677     mwmhints.input_mode = 0L;
       
   678     mwmhints.status = 0L;
       
   679 
       
   680     if (topLevel) {
       
   681         ulong wsa_mask = 0;
       
   682         if (type != Qt::SplashScreen) { // && customize) {
       
   683             mwmhints.flags |= MWM_HINTS_DECORATIONS;
       
   684 
       
   685             bool customize = flags & Qt::CustomizeWindowHint;
       
   686             if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
       
   687                 mwmhints.decorations |= MWM_DECOR_BORDER;
       
   688                 mwmhints.decorations |= MWM_DECOR_RESIZEH;
       
   689 
       
   690                 if (flags & Qt::WindowTitleHint)
       
   691                     mwmhints.decorations |= MWM_DECOR_TITLE;
       
   692 
       
   693                 if (flags & Qt::WindowSystemMenuHint)
       
   694                     mwmhints.decorations |= MWM_DECOR_MENU;
       
   695 
       
   696                 if (flags & Qt::WindowMinimizeButtonHint) {
       
   697                     mwmhints.decorations |= MWM_DECOR_MINIMIZE;
       
   698                     mwmhints.functions |= MWM_FUNC_MINIMIZE;
       
   699                 }
       
   700 
       
   701                 if (flags & Qt::WindowMaximizeButtonHint) {
       
   702                     mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
       
   703                     mwmhints.functions |= MWM_FUNC_MAXIMIZE;
       
   704                 }
       
   705 
       
   706                 if (flags & Qt::WindowCloseButtonHint)
       
   707                      mwmhints.functions |= MWM_FUNC_CLOSE;
       
   708             }
       
   709         } else {
       
   710             // if type == Qt::SplashScreen
       
   711             mwmhints.decorations = MWM_DECOR_ALL;
       
   712         }
       
   713 
       
   714         if (tool) {
       
   715             wsa.save_under = True;
       
   716             wsa_mask |= CWSaveUnder;
       
   717         }
       
   718 
       
   719         if (flags & Qt::X11BypassWindowManagerHint) {
       
   720             wsa.override_redirect = True;
       
   721             wsa_mask |= CWOverrideRedirect;
       
   722         }
       
   723 
       
   724         if (wsa_mask && initializeWindow) {
       
   725             Q_ASSERT(id);
       
   726             XChangeWindowAttributes(dpy, id, wsa_mask, &wsa);
       
   727         }
       
   728 
       
   729         if (mwmhints.functions != 0) {
       
   730             mwmhints.flags |= MWM_HINTS_FUNCTIONS;
       
   731             mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
       
   732         } else {
       
   733             mwmhints.functions = MWM_FUNC_ALL;
       
   734         }
       
   735 
       
   736         if (!(flags & Qt::FramelessWindowHint)
       
   737             && flags & Qt::CustomizeWindowHint
       
   738             && flags & Qt::WindowTitleHint
       
   739             && !(flags &
       
   740                  (Qt::WindowMinimizeButtonHint
       
   741                   | Qt::WindowMaximizeButtonHint
       
   742                   | Qt::WindowCloseButtonHint))) {
       
   743             // a special case - only the titlebar without any button
       
   744             mwmhints.flags = MWM_HINTS_FUNCTIONS;
       
   745             mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
       
   746             mwmhints.decorations = 0;
       
   747         }
       
   748     }
       
   749 
       
   750     if (!initializeWindow) {
       
   751         // do no initialization
       
   752     } else if (popup) {                        // popup widget
       
   753         // set EWMH window types
       
   754         setNetWmWindowTypes();
       
   755 
       
   756         wsa.override_redirect = True;
       
   757         wsa.save_under = True;
       
   758         Q_ASSERT(id);
       
   759         XChangeWindowAttributes(dpy, id, CWOverrideRedirect | CWSaveUnder,
       
   760                                 &wsa);
       
   761     } else if (topLevel && !desktop) {        // top-level widget
       
   762         if (!X11->wm_client_leader)
       
   763             create_wm_client_leader();
       
   764 
       
   765         // note: WM_TRANSIENT_FOR is set in QWidgetPrivate::show_sys()
       
   766 
       
   767         XSizeHints size_hints;
       
   768         size_hints.flags = USSize | PSize | PWinGravity;
       
   769         size_hints.x = data.crect.left();
       
   770         size_hints.y = data.crect.top();
       
   771         size_hints.width = data.crect.width();
       
   772         size_hints.height = data.crect.height();
       
   773         size_hints.win_gravity =
       
   774             QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
       
   775 
       
   776         XWMHints wm_hints;                        // window manager hints
       
   777         memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
       
   778         wm_hints.flags = InputHint | StateHint | WindowGroupHint;
       
   779         wm_hints.input = True;
       
   780         wm_hints.initial_state = NormalState;
       
   781         wm_hints.window_group = X11->wm_client_leader;
       
   782 
       
   783         XClassHint class_hint;
       
   784         QByteArray appName = qAppName().toLatin1();
       
   785         class_hint.res_name = appName.data(); // application name
       
   786         class_hint.res_class = const_cast<char *>(QX11Info::appClass());   // application class
       
   787 
       
   788         XSetWMProperties(dpy, id, 0, 0,
       
   789                          qApp->d_func()->argv, qApp->d_func()->argc,
       
   790                          &size_hints, &wm_hints, &class_hint);
       
   791 
       
   792         XResizeWindow(dpy, id,
       
   793                       qBound(1, data.crect.width(), XCOORD_MAX),
       
   794                       qBound(1, data.crect.height(), XCOORD_MAX));
       
   795         XStoreName(dpy, id, appName.data());
       
   796         Atom protocols[5];
       
   797         int n = 0;
       
   798         protocols[n++] = ATOM(WM_DELETE_WINDOW);        // support del window protocol
       
   799         protocols[n++] = ATOM(WM_TAKE_FOCUS);                // support take focus window protocol
       
   800         protocols[n++] = ATOM(_NET_WM_PING);                // support _NET_WM_PING protocol
       
   801 #ifndef QT_NO_XSYNC
       
   802         protocols[n++] = ATOM(_NET_WM_SYNC_REQUEST);        // support _NET_WM_SYNC_REQUEST protocol
       
   803 #endif // QT_NO_XSYNC
       
   804         if (flags & Qt::WindowContextHelpButtonHint)
       
   805             protocols[n++] = ATOM(_NET_WM_CONTEXT_HELP);
       
   806         XSetWMProtocols(dpy, id, protocols, n);
       
   807 
       
   808         // set mwm hints
       
   809         SetMWMHints(dpy, id, mwmhints);
       
   810 
       
   811         // set EWMH window types
       
   812         setNetWmWindowTypes();
       
   813 
       
   814         // set _NET_WM_PID
       
   815         long curr_pid = getpid();
       
   816         XChangeProperty(dpy, id, ATOM(_NET_WM_PID), XA_CARDINAL, 32, PropModeReplace,
       
   817                         (unsigned char *) &curr_pid, 1);
       
   818 
       
   819         // when we create a toplevel widget, the frame strut should be dirty
       
   820         data.fstrut_dirty = 1;
       
   821 
       
   822         // declare the widget's window role
       
   823         if (QTLWExtra *topData = maybeTopData()) {
       
   824             if (!topData->role.isEmpty()) {
       
   825                 QByteArray windowRole = topData->role.toUtf8();
       
   826                 XChangeProperty(dpy, id,
       
   827                                 ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
       
   828                                 (unsigned char *)windowRole.constData(), windowRole.length());
       
   829             }
       
   830         }
       
   831 
       
   832         // set client leader property
       
   833         XChangeProperty(dpy, id, ATOM(WM_CLIENT_LEADER),
       
   834                         XA_WINDOW, 32, PropModeReplace,
       
   835                         (unsigned char *)&X11->wm_client_leader, 1);
       
   836     } else {
       
   837         // non-toplevel widgets don't have a frame, so no need to
       
   838         // update the strut
       
   839         data.fstrut_dirty = 0;
       
   840     }
       
   841 
       
   842     if (initializeWindow && q->internalWinId()) {
       
   843         // don't erase when resizing
       
   844         wsa.bit_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
       
   845         Q_ASSERT(id);
       
   846         XChangeWindowAttributes(dpy, id, CWBitGravity, &wsa);
       
   847     }
       
   848 
       
   849     // set X11 event mask
       
   850     if (desktop) {
       
   851 //         QWidget* main_desktop = find(id);
       
   852 //         if (main_desktop->testWFlags(Qt::WPaintDesktop))
       
   853 //             XSelectInput(dpy, id, stdDesktopEventMask | ExposureMask);
       
   854 //         else
       
   855         XSelectInput(dpy, id, stdDesktopEventMask);
       
   856     } else if (q->internalWinId()) {
       
   857         XSelectInput(dpy, id, stdWidgetEventMask);
       
   858 #if !defined (QT_NO_TABLET)
       
   859         QTabletDeviceDataList *tablet_list = qt_tablet_devices();
       
   860         if (X11->ptrXSelectExtensionEvent) {
       
   861             for (int i = 0; i < tablet_list->size(); ++i) {
       
   862                 QTabletDeviceData tablet = tablet_list->at(i);
       
   863                 X11->ptrXSelectExtensionEvent(dpy, id, reinterpret_cast<XEventClass*>(tablet.eventList),
       
   864                                               tablet.eventCount);
       
   865             }
       
   866         }
       
   867 #endif
       
   868     }
       
   869 
       
   870     if (desktop) {
       
   871         q->setAttribute(Qt::WA_WState_Visible);
       
   872     } else if (topLevel) {                        // set X cursor
       
   873         if (initializeWindow) {
       
   874             qt_x11_enforce_cursor(q);
       
   875 
       
   876             if (QTLWExtra *topData = maybeTopData())
       
   877                 if (!topData->caption.isEmpty())
       
   878                     setWindowTitle_helper(topData->caption);
       
   879 
       
   880             //always enable dnd: it's not worth the effort to maintain the state
       
   881             // NOTE: this always creates topData()
       
   882             X11->dndEnable(q, true);
       
   883 
       
   884             if (maybeTopData() && maybeTopData()->opacity != 255)
       
   885                 q->setWindowOpacity(maybeTopData()->opacity/255.);
       
   886 
       
   887         }
       
   888     } else if (q->testAttribute(Qt::WA_SetCursor) && q->internalWinId()) {
       
   889         qt_x11_enforce_cursor(q);
       
   890     }
       
   891 
       
   892     if (extra && !extra->mask.isEmpty() && q->internalWinId())
       
   893         XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
       
   894                             extra->mask.handle(), ShapeSet);
       
   895 
       
   896     if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled)) {
       
   897         QInputContext *inputContext = q->inputContext();
       
   898         if (inputContext)
       
   899             inputContext->setFocusWidget(q);
       
   900     }
       
   901 
       
   902     if (destroyw)
       
   903         qt_XDestroyWindow(q, dpy, destroyw);
       
   904 
       
   905     // newly created windows are positioned at the window system's
       
   906     // (0,0) position. If the parent uses wrect mapping to expand the
       
   907     // coordinate system, we must also adjust this widget's window
       
   908     // system position
       
   909     if (!topLevel && !parentWidget->data->wrect.topLeft().isNull())
       
   910         setWSGeometry();
       
   911     else if (topLevel && (data.crect.width() == 0 || data.crect.height() == 0))
       
   912         q->setAttribute(Qt::WA_OutsideWSRange, true);
       
   913 
       
   914     if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) {
       
   915         Q_ASSERT(q->internalWinId());
       
   916         XMapWindow(X11->display, q->internalWinId());
       
   917         // Ensure that mapped alien widgets are flushed immediately when re-created as native widgets.
       
   918         if (QWindowSurface *surface = q->windowSurface())
       
   919             surface->flush(q, q->rect(), q->mapTo(surface->window(), QPoint()));
       
   920     }
       
   921 
       
   922 #ifdef ALIEN_DEBUG
       
   923     qDebug() << "QWidgetPrivate::create_sys END:" << q;
       
   924 #endif
       
   925 }
       
   926 
       
   927 static void qt_x11_recreateWidget(QWidget *widget)
       
   928 {
       
   929     if (widget->inherits("QGLWidget")) {
       
   930         // We send QGLWidgets a ParentChange event which causes them to
       
   931         // recreate their GL context, which in turn causes them to choose
       
   932         // their visual again. Now that WA_TranslucentBackground is set,
       
   933         // QGLContext::chooseVisual will select an ARGB visual.
       
   934         QEvent e(QEvent::ParentChange);
       
   935         QApplication::sendEvent(widget, &e);
       
   936     } else {
       
   937         // For regular widgets, reparent them with their parent which
       
   938         // also triggers a recreation of the native window
       
   939         QPoint pos = widget->pos();
       
   940         bool visible = widget->isVisible();
       
   941         if (visible)
       
   942             widget->hide();
       
   943 
       
   944         widget->setParent(widget->parentWidget(), widget->windowFlags());
       
   945         widget->move(pos);
       
   946         if (visible)
       
   947             widget->show();
       
   948     }
       
   949 }
       
   950 
       
   951 static void qt_x11_recreateNativeWidgetsRecursive(QWidget *widget)
       
   952 {
       
   953     if (widget->internalWinId())
       
   954         qt_x11_recreateWidget(widget);
       
   955 
       
   956     const QObjectList &children = widget->children();
       
   957     for (int i = 0; i < children.size(); ++i) {
       
   958         QWidget *child = qobject_cast<QWidget*>(children.at(i));
       
   959         if (child)
       
   960             qt_x11_recreateNativeWidgetsRecursive(child);
       
   961     }
       
   962 }
       
   963 
       
   964 void QWidgetPrivate::x11UpdateIsOpaque()
       
   965 {
       
   966 #ifndef QT_NO_XRENDER
       
   967     Q_Q(QWidget);
       
   968     if (!q->testAttribute(Qt::WA_WState_Created) || !q->testAttribute(Qt::WA_TranslucentBackground))
       
   969         return;
       
   970 
       
   971     bool topLevel = (data.window_flags & Qt::Window);
       
   972     int screen = xinfo.screen();
       
   973     if (topLevel && X11->use_xrender
       
   974         && X11->argbVisuals[screen] && xinfo.depth() != 32)
       
   975     {
       
   976         qt_x11_recreateNativeWidgetsRecursive(q);
       
   977     }
       
   978 #endif
       
   979 }
       
   980 
       
   981 /*
       
   982   Returns true if the background is inherited; otherwise returns
       
   983   false.
       
   984 
       
   985   Mainly used in the paintOnScreen case.
       
   986 */
       
   987 bool QWidgetPrivate::isBackgroundInherited() const
       
   988 {
       
   989     Q_Q(const QWidget);
       
   990 
       
   991     // windows do not inherit their background
       
   992     if (q->isWindow() || q->windowType() == Qt::SubWindow)
       
   993         return false;
       
   994 
       
   995     if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent))
       
   996         return false;
       
   997 
       
   998     const QPalette &pal = q->palette();
       
   999     QPalette::ColorRole bg = q->backgroundRole();
       
  1000     QBrush brush = pal.brush(bg);
       
  1001 
       
  1002     // non opaque brushes leaves us no choice, we must inherit
       
  1003     if (!q->autoFillBackground() || !brush.isOpaque())
       
  1004         return true;
       
  1005 
       
  1006     if (brush.style() == Qt::SolidPattern) {
       
  1007         // the background is just a solid color. If there is no
       
  1008         // propagated contents, then we claim as performance
       
  1009         // optimization that it was not inheritet. This is the normal
       
  1010         // case in standard Windows or Motif style.
       
  1011         const QWidget *w = q->parentWidget();
       
  1012         if (!w->d_func()->isBackgroundInherited())
       
  1013             return false;
       
  1014     }
       
  1015 
       
  1016     return true;
       
  1017 }
       
  1018 
       
  1019 void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
       
  1020 {
       
  1021     Q_D(QWidget);
       
  1022     if (!isWindow() && parentWidget())
       
  1023         parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
       
  1024     d->deactivateWidgetCleanup();
       
  1025     if (testAttribute(Qt::WA_WState_Created)) {
       
  1026         setAttribute(Qt::WA_WState_Created, false);
       
  1027         QObjectList childList = children();
       
  1028         for (int i = 0; i < childList.size(); ++i) { // destroy all widget children
       
  1029             register QObject *obj = childList.at(i);
       
  1030             if (obj->isWidgetType())
       
  1031                 static_cast<QWidget*>(obj)->destroy(destroySubWindows,
       
  1032                                                     destroySubWindows);
       
  1033         }
       
  1034         if (QWidgetPrivate::mouseGrabber == this)
       
  1035             releaseMouse();
       
  1036         if (QWidgetPrivate::keyboardGrabber == this)
       
  1037             releaseKeyboard();
       
  1038         if (isWindow())
       
  1039             X11->deferred_map.removeAll(this);
       
  1040         if (isModal()) {
       
  1041             // just be sure we leave modal
       
  1042             QApplicationPrivate::leaveModal(this);
       
  1043         }
       
  1044         else if ((windowType() == Qt::Popup))
       
  1045             qApp->d_func()->closePopup(this);
       
  1046 
       
  1047 #ifndef QT_NO_XRENDER
       
  1048         if (d->picture) {
       
  1049             if (destroyWindow)
       
  1050                 XRenderFreePicture(X11->display, d->picture);
       
  1051             d->picture = 0;
       
  1052         }
       
  1053 #endif // QT_NO_XRENDER
       
  1054 
       
  1055         // delete the _NET_WM_USER_TIME_WINDOW
       
  1056         qt_net_remove_user_time(this);
       
  1057 
       
  1058         if ((windowType() == Qt::Desktop)) {
       
  1059             if (acceptDrops())
       
  1060                 X11->dndEnable(this, false);
       
  1061         } else {
       
  1062             if (isWindow())
       
  1063                 X11->dndEnable(this, false);
       
  1064             if (destroyWindow)
       
  1065                 qt_XDestroyWindow(this, X11->display, data->winid);
       
  1066         }
       
  1067         QT_TRY {
       
  1068             d->setWinId(0);
       
  1069         } QT_CATCH (const std::bad_alloc &) {
       
  1070             // swallow - destructors must not throw
       
  1071         }
       
  1072 
       
  1073         extern void qPRCleanup(QWidget *widget); // from qapplication_x11.cpp
       
  1074         if (testAttribute(Qt::WA_WState_Reparented))
       
  1075             qPRCleanup(this);
       
  1076 
       
  1077         if(d->ic) {
       
  1078             delete d->ic;
       
  1079         } else {
       
  1080             // release previous focus information participating with
       
  1081             // preedit preservation of qic
       
  1082             QInputContext *qic = inputContext();
       
  1083             if (qic)
       
  1084                 qic->widgetDestroyed(this);
       
  1085         }
       
  1086     }
       
  1087 }
       
  1088 
       
  1089 void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
       
  1090 {
       
  1091     Q_Q(QWidget);
       
  1092 #ifdef ALIEN_DEBUG
       
  1093     qDebug() << "QWidgetPrivate::setParent_sys START" << q << "parent:" << parent;
       
  1094 #endif
       
  1095     QX11Info old_xinfo = xinfo;
       
  1096     if (parent && parent->windowType() == Qt::Desktop) {
       
  1097         // make sure the widget is created on the same screen as the
       
  1098         // programmer specified desktop widget
       
  1099         xinfo = parent->d_func()->xinfo;
       
  1100         parent = 0;
       
  1101     }
       
  1102 
       
  1103     QTLWExtra *topData = maybeTopData();
       
  1104     bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
       
  1105     if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
       
  1106         q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
       
  1107     extern void qPRCreate(const QWidget *, Window);
       
  1108 #ifndef QT_NO_CURSOR
       
  1109     QCursor oldcurs;
       
  1110 #endif
       
  1111 
       
  1112     // dnd unregister (we will register again below)
       
  1113     if (q->testAttribute(Qt::WA_DropSiteRegistered))
       
  1114         q->setAttribute(Qt::WA_DropSiteRegistered, false);
       
  1115 
       
  1116     // if we are a top then remove our dnd prop for now
       
  1117     // it will get rest later
       
  1118     if (q->isWindow() && wasCreated)
       
  1119         X11->dndEnable(q, false);
       
  1120 
       
  1121     if (topData)
       
  1122         qt_net_remove_user_time(q);
       
  1123 
       
  1124 //     QWidget *oldparent = q->parentWidget();
       
  1125     WId old_winid = wasCreated ? data.winid : 0;
       
  1126     if ((q->windowType() == Qt::Desktop))
       
  1127         old_winid = 0;
       
  1128     setWinId(0);
       
  1129 
       
  1130 #ifndef QT_NO_XRENDER
       
  1131     if (picture) {
       
  1132         XRenderFreePicture(X11->display, picture);
       
  1133         picture = 0;
       
  1134     }
       
  1135 #endif
       
  1136 
       
  1137     // hide and reparent our own window away. Otherwise we might get
       
  1138     // destroyed when emitting the child remove event below. See QWorkspace.
       
  1139     if (wasCreated && old_winid) {
       
  1140         XUnmapWindow(X11->display, old_winid);
       
  1141         if (!old_xinfo.screen() != xinfo.screen())
       
  1142             XReparentWindow(X11->display, old_winid, RootWindow(X11->display, xinfo.screen()), 0, 0);
       
  1143     }
       
  1144     if (topData) {
       
  1145         topData->parentWinId = 0;
       
  1146         // zero the frame strut and mark it dirty
       
  1147         topData->frameStrut.setCoords(0, 0, 0, 0);
       
  1148 
       
  1149         // reparenting from top-level, make sure show() works again
       
  1150         topData->waitingForMapNotify = 0;
       
  1151         topData->validWMState = 0;
       
  1152     }
       
  1153     data.fstrut_dirty = (!parent || (f & Qt::Window)); // toplevels get a dirty framestrut
       
  1154 
       
  1155     QObjectPrivate::setParent_helper(parent);
       
  1156     bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
       
  1157 
       
  1158     data.window_flags = f;
       
  1159     q->setAttribute(Qt::WA_WState_Created, false);
       
  1160     q->setAttribute(Qt::WA_WState_Visible, false);
       
  1161     q->setAttribute(Qt::WA_WState_Hidden, false);
       
  1162     adjustFlags(data.window_flags, q);
       
  1163     // keep compatibility with previous versions, we need to preserve the created state
       
  1164     // (but we recreate the winId for the widget being reparented, again for compatibility)
       
  1165     if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created)))
       
  1166         createWinId();
       
  1167     if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
       
  1168         q->setAttribute(Qt::WA_WState_Hidden);
       
  1169     q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
       
  1170 
       
  1171     if (wasCreated) {
       
  1172         QObjectList chlist = q->children();
       
  1173         for (int i = 0; i < chlist.size(); ++i) { // reparent children
       
  1174             QObject *obj = chlist.at(i);
       
  1175             if (obj->isWidgetType()) {
       
  1176                 QWidget *w = (QWidget *)obj;
       
  1177                 if (!w->testAttribute(Qt::WA_WState_Created))
       
  1178                     continue;
       
  1179                 if (xinfo.screen() != w->d_func()->xinfo.screen()) {
       
  1180                     // ### force setParent() to not shortcut out (because
       
  1181                     // ### we're setting the parent to the current parent)
       
  1182                     // ### setParent will add child back to the list
       
  1183                     // ### of children so we need to make sure the
       
  1184                     // ### widget won't be added twice.
       
  1185                     w->d_func()->parent = 0;
       
  1186                     this->children.removeOne(w);
       
  1187                     w->setParent(q);
       
  1188                 } else if (!w->isWindow()) {
       
  1189                     w->d_func()->invalidateBuffer(w->rect());
       
  1190                     if (w->internalWinId()) {
       
  1191                         if (w->testAttribute(Qt::WA_NativeWindow)) {
       
  1192                             QWidget *nativeParentWidget = w->nativeParentWidget();
       
  1193                             // Qt::WA_NativeWindow ensures that we always have a nativeParentWidget
       
  1194                             Q_ASSERT(nativeParentWidget != 0);
       
  1195                             QPoint p = w->mapTo(nativeParentWidget, QPoint());
       
  1196                             XReparentWindow(X11->display,
       
  1197                                             w->internalWinId(),
       
  1198                                             nativeParentWidget->internalWinId(),
       
  1199                                             p.x(), p.y());
       
  1200                         } else {
       
  1201                             w->d_func()->setParent_sys(q, w->data->window_flags);
       
  1202                         }
       
  1203                     }
       
  1204                 } else if (isTransient(w)) {
       
  1205                     /*
       
  1206                       when reparenting toplevel windows with toplevel-transient children,
       
  1207                       we need to make sure that the window manager gets the updated
       
  1208                       WM_TRANSIENT_FOR information... unfortunately, some window managers
       
  1209                       don't handle changing WM_TRANSIENT_FOR before the toplevel window is
       
  1210                       visible, so we unmap and remap all toplevel-transient children *after*
       
  1211                       the toplevel parent has been mapped.  thankfully, this is easy in Qt :)
       
  1212 
       
  1213                       note that the WM_TRANSIENT_FOR hint is actually updated in
       
  1214                       QWidgetPrivate::show_sys()
       
  1215                     */
       
  1216                     if (w->internalWinId())
       
  1217                         XUnmapWindow(X11->display, w->internalWinId());
       
  1218                     QApplication::postEvent(w, new QEvent(QEvent::ShowWindowRequest));
       
  1219                 }
       
  1220             }
       
  1221         }
       
  1222         qPRCreate(q, old_winid);
       
  1223         updateSystemBackground();
       
  1224 
       
  1225         if (old_winid) {
       
  1226             Window *cmwret;
       
  1227             int count;
       
  1228             if (XGetWMColormapWindows(X11->display, old_winid, &cmwret, &count)) {
       
  1229                 Window *cmw;
       
  1230                 int cmw_size = sizeof(Window)*count;
       
  1231                 cmw = new Window[count];
       
  1232                 memcpy((char *)cmw, (char *)cmwret, cmw_size);
       
  1233                 XFree((char *)cmwret);
       
  1234                 int i;
       
  1235                 for (i=0; i<count; i++) {
       
  1236                     if (cmw[i] == old_winid) {
       
  1237                         cmw[i] = q->internalWinId();
       
  1238                         break;
       
  1239                     }
       
  1240                 }
       
  1241                 int top_count;
       
  1242                 if (XGetWMColormapWindows(X11->display, q->window()->internalWinId(),
       
  1243                                           &cmwret, &top_count))
       
  1244                 {
       
  1245                     Window *merged_cmw = new Window[count + top_count];
       
  1246                     memcpy((char *)merged_cmw, (char *)cmw, cmw_size);
       
  1247                     memcpy((char *)merged_cmw + cmw_size, (char *)cmwret, sizeof(Window)*top_count);
       
  1248                     delete [] cmw;
       
  1249                     XFree((char *)cmwret);
       
  1250                     cmw = merged_cmw;
       
  1251                     count += top_count;
       
  1252                 }
       
  1253 
       
  1254                 XSetWMColormapWindows(X11->display, q->window()->internalWinId(), cmw, count);
       
  1255                 delete [] cmw;
       
  1256             }
       
  1257 
       
  1258             qt_XDestroyWindow(q, X11->display, old_winid);
       
  1259         }
       
  1260     }
       
  1261 
       
  1262     // check if we need to register our dropsite
       
  1263     if (q->testAttribute(Qt::WA_AcceptDrops)
       
  1264         || (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))) {
       
  1265         q->setAttribute(Qt::WA_DropSiteRegistered, true);
       
  1266     }
       
  1267 #if !defined(QT_NO_IM)
       
  1268     ic = 0;
       
  1269 #endif
       
  1270     invalidateBuffer(q->rect());
       
  1271 #ifdef ALIEN_DEBUG
       
  1272     qDebug() << "QWidgetPrivate::setParent_sys END" << q;
       
  1273 #endif
       
  1274 }
       
  1275 
       
  1276 
       
  1277 QPoint QWidget::mapToGlobal(const QPoint &pos) const
       
  1278 {
       
  1279     Q_D(const QWidget);
       
  1280     if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
       
  1281         QPoint p = pos + data->crect.topLeft();
       
  1282         //cannot trust that !isWindow() implies parentWidget() before create
       
  1283         return (isWindow() || !parentWidget()) ?  p : parentWidget()->mapToGlobal(p);
       
  1284     }
       
  1285     int           x, y;
       
  1286     Window child;
       
  1287     QPoint p = d->mapToWS(pos);
       
  1288     XTranslateCoordinates(X11->display, internalWinId(),
       
  1289                           QApplication::desktop()->screen(d->xinfo.screen())->internalWinId(),
       
  1290                           p.x(), p.y(), &x, &y, &child);
       
  1291     return QPoint(x, y);
       
  1292 }
       
  1293 
       
  1294 
       
  1295 QPoint QWidget::mapFromGlobal(const QPoint &pos) const
       
  1296 {
       
  1297     Q_D(const QWidget);
       
  1298     if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
       
  1299         //cannot trust that !isWindow() implies parentWidget() before create
       
  1300         QPoint p = (isWindow() || !parentWidget()) ?  pos : parentWidget()->mapFromGlobal(pos);
       
  1301         return p - data->crect.topLeft();
       
  1302     }
       
  1303     int           x, y;
       
  1304     Window child;
       
  1305     XTranslateCoordinates(X11->display,
       
  1306                           QApplication::desktop()->screen(d->xinfo.screen())->internalWinId(),
       
  1307                           internalWinId(), pos.x(), pos.y(), &x, &y, &child);
       
  1308     return d->mapFromWS(QPoint(x, y));
       
  1309 }
       
  1310 
       
  1311 void QWidgetPrivate::updateSystemBackground()
       
  1312 {
       
  1313     Q_Q(QWidget);
       
  1314     if (!q->testAttribute(Qt::WA_WState_Created) || !q->internalWinId())
       
  1315         return;
       
  1316     QBrush brush = q->palette().brush(QPalette::Active, q->backgroundRole());
       
  1317     Qt::WindowType type = q->windowType();
       
  1318     if (brush.style() == Qt::NoBrush
       
  1319         || q->testAttribute(Qt::WA_NoSystemBackground)
       
  1320         || q->testAttribute(Qt::WA_UpdatesDisabled)
       
  1321         || type == Qt::Popup || type == Qt::ToolTip
       
  1322         )
       
  1323         XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
       
  1324     else if (brush.style() == Qt::SolidPattern && brush.isOpaque())
       
  1325         XSetWindowBackground(X11->display, q->internalWinId(),
       
  1326                              QColormap::instance(xinfo.screen()).pixel(brush.color()));
       
  1327     else if (isBackgroundInherited())
       
  1328         XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), ParentRelative);
       
  1329     else if (brush.style() == Qt::TexturePattern) {
       
  1330         extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); // qpixmap_x11.cpp
       
  1331         XSetWindowBackgroundPixmap(X11->display, q->internalWinId(),
       
  1332                                    static_cast<QX11PixmapData*>(qt_toX11Pixmap(brush.texture()).data.data())->x11ConvertToDefaultDepth());
       
  1333     } else
       
  1334         XSetWindowBackground(X11->display, q->internalWinId(),
       
  1335                              QColormap::instance(xinfo.screen()).pixel(brush.color()));
       
  1336 }
       
  1337 
       
  1338 #ifndef QT_NO_CURSOR
       
  1339 void QWidgetPrivate::setCursor_sys(const QCursor &)
       
  1340 {
       
  1341     Q_Q(QWidget);
       
  1342     qt_x11_enforce_cursor(q);
       
  1343     XFlush(X11->display);
       
  1344 }
       
  1345 
       
  1346 void QWidgetPrivate::unsetCursor_sys()
       
  1347 {
       
  1348     Q_Q(QWidget);
       
  1349     qt_x11_enforce_cursor(q);
       
  1350     XFlush(X11->display);
       
  1351 }
       
  1352 #endif
       
  1353 
       
  1354 static XTextProperty*
       
  1355 qstring_to_xtp(const QString& s)
       
  1356 {
       
  1357     static XTextProperty tp = { 0, 0, 0, 0 };
       
  1358     static bool free_prop = true; // we can't free tp.value in case it references
       
  1359     // the data of the static QCString below.
       
  1360     if (tp.value) {
       
  1361         if (free_prop)
       
  1362             XFree(tp.value);
       
  1363         tp.value = 0;
       
  1364         free_prop = true;
       
  1365     }
       
  1366 
       
  1367     static const QTextCodec* mapper = QTextCodec::codecForLocale();
       
  1368     int errCode = 0;
       
  1369     if (mapper) {
       
  1370         QByteArray mapped = mapper->fromUnicode(s);
       
  1371         char* tl[2];
       
  1372         tl[0] = mapped.data();
       
  1373         tl[1] = 0;
       
  1374         errCode = XmbTextListToTextProperty(X11->display, tl, 1, XStdICCTextStyle, &tp);
       
  1375 #if defined(QT_DEBUG)
       
  1376         if (errCode < 0)
       
  1377             qDebug("qstring_to_xtp result code %d", errCode);
       
  1378 #endif
       
  1379     }
       
  1380     if (!mapper || errCode < 0) {
       
  1381         static QByteArray qcs;
       
  1382         qcs = s.toAscii();
       
  1383         tp.value = (uchar*)qcs.data();
       
  1384         tp.encoding = XA_STRING;
       
  1385         tp.format = 8;
       
  1386         tp.nitems = qcs.length();
       
  1387         free_prop = false;
       
  1388     }
       
  1389 
       
  1390     // ### If we knew WM could understand unicode, we could use
       
  1391     // ### a much simpler, cheaper encoding...
       
  1392     /*
       
  1393         tp.value = (XChar2b*)s.unicode();
       
  1394         tp.encoding = XA_UNICODE; // wish
       
  1395         tp.format = 16;
       
  1396         tp.nitems = s.length();
       
  1397     */
       
  1398 
       
  1399     return &tp;
       
  1400 }
       
  1401 
       
  1402 void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
       
  1403 {
       
  1404     Q_Q(QWidget);
       
  1405     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1406     if (!q->internalWinId())
       
  1407         return;
       
  1408     XSetWMName(X11->display, q->internalWinId(), qstring_to_xtp(caption));
       
  1409 
       
  1410     QByteArray net_wm_name = caption.toUtf8();
       
  1411     XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8,
       
  1412                     PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
       
  1413 }
       
  1414 
       
  1415 void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
       
  1416 {
       
  1417     Q_Q(QWidget);
       
  1418     if (!q->testAttribute(Qt::WA_WState_Created))
       
  1419         return;
       
  1420     QTLWExtra *topData = this->topData();
       
  1421     if (topData->iconPixmap && !forceReset)
       
  1422         // already been set
       
  1423         return;
       
  1424 
       
  1425     // preparing images to set the _NET_WM_ICON property
       
  1426     QIcon icon = q->windowIcon();
       
  1427     QVector<long> icon_data;
       
  1428     Qt::HANDLE pixmap_handle = 0;
       
  1429     if (!icon.isNull()) {
       
  1430         QList<QSize> availableSizes = icon.availableSizes();
       
  1431         if(availableSizes.isEmpty()) {
       
  1432             // try to use default sizes since the icon can be a scalable image like svg.
       
  1433             availableSizes.push_back(QSize(16,16));
       
  1434             availableSizes.push_back(QSize(32,32));
       
  1435             availableSizes.push_back(QSize(64,64));
       
  1436             availableSizes.push_back(QSize(128,128));
       
  1437         }
       
  1438         for(int i = 0; i < availableSizes.size(); ++i) {
       
  1439             QSize size = availableSizes.at(i);
       
  1440             QPixmap pixmap = icon.pixmap(size);
       
  1441             if (!pixmap.isNull()) {
       
  1442                 QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
       
  1443                 int pos = icon_data.size();
       
  1444                 icon_data.resize(pos + 2 + image.width()*image.height());
       
  1445                 icon_data[pos++] = image.width();
       
  1446                 icon_data[pos++] = image.height();
       
  1447                 if (sizeof(long) == sizeof(quint32)) {
       
  1448                     memcpy(icon_data.data() + pos, image.scanLine(0), image.numBytes());
       
  1449                 } else {
       
  1450                     for (int y = 0; y < image.height(); ++y) {
       
  1451                         uint *scanLine = reinterpret_cast<uint *>(image.scanLine(y));
       
  1452                         for (int x = 0; x < image.width(); ++x)
       
  1453                             icon_data[pos + y*image.width() + x] = scanLine[x];
       
  1454                     }
       
  1455                 }
       
  1456             }
       
  1457         }
       
  1458         if (!icon_data.isEmpty()) {
       
  1459             extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap);
       
  1460             /*
       
  1461               if the app is running on an unknown desktop, or it is not
       
  1462               using the default visual, convert the icon to 1bpp as stated
       
  1463               in the ICCCM section 4.1.2.4; otherwise, create the icon pixmap
       
  1464               in the default depth (even though this violates the ICCCM)
       
  1465             */
       
  1466             if (X11->desktopEnvironment == DE_UNKNOWN
       
  1467                 || !QX11Info::appDefaultVisual(xinfo.screen())
       
  1468                 || !QX11Info::appDefaultColormap(xinfo.screen())) {
       
  1469                 // unknown DE or non-default visual/colormap, use 1bpp bitmap
       
  1470                 if (!forceReset || !topData->iconPixmap)
       
  1471                     topData->iconPixmap = new QBitmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
       
  1472                 pixmap_handle = topData->iconPixmap->handle();
       
  1473             } else {
       
  1474                 // default depth, use a normal pixmap (even though this
       
  1475                 // violates the ICCCM), since this works on all DEs known to Qt
       
  1476                 if (!forceReset || !topData->iconPixmap)
       
  1477                     topData->iconPixmap = new QPixmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64))));
       
  1478                 pixmap_handle = static_cast<QX11PixmapData*>(topData->iconPixmap->data.data())->x11ConvertToDefaultDepth();
       
  1479             }
       
  1480         }
       
  1481     }
       
  1482 
       
  1483     if (!q->internalWinId())
       
  1484         return;
       
  1485 
       
  1486     if (!icon_data.isEmpty()) {
       
  1487         XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON), XA_CARDINAL, 32,
       
  1488                         PropModeReplace, (unsigned char *) icon_data.data(),
       
  1489                         icon_data.size());
       
  1490     } else {
       
  1491         XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON));
       
  1492     }
       
  1493 
       
  1494     XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
       
  1495     XWMHints wm_hints;
       
  1496     if (!h) {
       
  1497         memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
       
  1498         h = &wm_hints;
       
  1499     }
       
  1500 
       
  1501     if (pixmap_handle) {
       
  1502         h->icon_pixmap = pixmap_handle;
       
  1503         h->flags |= IconPixmapHint;
       
  1504     } else {
       
  1505         h->icon_pixmap = 0;
       
  1506         h->flags &= ~(IconPixmapHint | IconMaskHint);
       
  1507     }
       
  1508 
       
  1509     XSetWMHints(X11->display, q->internalWinId(), h);
       
  1510     if (h != &wm_hints)
       
  1511         XFree((char *)h);
       
  1512 }
       
  1513 
       
  1514 void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
       
  1515 {
       
  1516     Q_Q(QWidget);
       
  1517     if (!q->internalWinId())
       
  1518         return;
       
  1519     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1520     XSetWMIconName(X11->display, q->internalWinId(), qstring_to_xtp(iconText));
       
  1521 
       
  1522     QByteArray icon_name = iconText.toUtf8();
       
  1523     XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON_NAME), ATOM(UTF8_STRING), 8,
       
  1524                     PropModeReplace, (unsigned char *) icon_name.constData(), icon_name.size());
       
  1525 }
       
  1526 
       
  1527 
       
  1528 void QWidget::grabMouse()
       
  1529 {
       
  1530     if (isVisible() && !qt_nograb()) {
       
  1531         if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
       
  1532             QWidgetPrivate::mouseGrabber->releaseMouse();
       
  1533         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
  1534 #ifndef QT_NO_DEBUG
       
  1535         int status =
       
  1536 #endif
       
  1537             XGrabPointer(X11->display, effectiveWinId(), False,
       
  1538                           (uint)(ButtonPressMask | ButtonReleaseMask |
       
  1539                                   PointerMotionMask | EnterWindowMask |
       
  1540                                   LeaveWindowMask),
       
  1541                           GrabModeAsync, GrabModeAsync,
       
  1542                           XNone, XNone, X11->time);
       
  1543 #ifndef QT_NO_DEBUG
       
  1544         if (status) {
       
  1545             const char *s =
       
  1546                 status == GrabNotViewable ? "\"GrabNotViewable\"" :
       
  1547                 status == AlreadyGrabbed  ? "\"AlreadyGrabbed\"" :
       
  1548                 status == GrabFrozen      ? "\"GrabFrozen\"" :
       
  1549                 status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
       
  1550                 "<?>";
       
  1551             qWarning("QWidget::grabMouse: Failed with %s", s);
       
  1552         }
       
  1553 #endif
       
  1554         QWidgetPrivate::mouseGrabber = this;
       
  1555     }
       
  1556 }
       
  1557 
       
  1558 
       
  1559 #ifndef QT_NO_CURSOR
       
  1560 void QWidget::grabMouse(const QCursor &cursor)
       
  1561 {
       
  1562     if (!qt_nograb()) {
       
  1563         if (QWidgetPrivate::mouseGrabber && QWidgetPrivate::mouseGrabber != this)
       
  1564             QWidgetPrivate::mouseGrabber->releaseMouse();
       
  1565         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
  1566 #ifndef QT_NO_DEBUG
       
  1567         int status =
       
  1568 #endif
       
  1569         XGrabPointer(X11->display, effectiveWinId(), False,
       
  1570                       (uint)(ButtonPressMask | ButtonReleaseMask |
       
  1571                              PointerMotionMask | EnterWindowMask | LeaveWindowMask),
       
  1572                       GrabModeAsync, GrabModeAsync,
       
  1573                       XNone, cursor.handle(), X11->time);
       
  1574 #ifndef QT_NO_DEBUG
       
  1575         if (status) {
       
  1576             const char *s =
       
  1577                 status == GrabNotViewable ? "\"GrabNotViewable\"" :
       
  1578                 status == AlreadyGrabbed  ? "\"AlreadyGrabbed\"" :
       
  1579                 status == GrabFrozen      ? "\"GrabFrozen\"" :
       
  1580                 status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
       
  1581                                             "<?>";
       
  1582             qWarning("QWidget::grabMouse: Failed with %s", s);
       
  1583         }
       
  1584 #endif
       
  1585         QWidgetPrivate::mouseGrabber = this;
       
  1586     }
       
  1587 }
       
  1588 #endif
       
  1589 
       
  1590 
       
  1591 void QWidget::releaseMouse()
       
  1592 {
       
  1593     if (!qt_nograb() && QWidgetPrivate::mouseGrabber == this) {
       
  1594         XUngrabPointer(X11->display, X11->time);
       
  1595         XFlush(X11->display);
       
  1596         QWidgetPrivate::mouseGrabber = 0;
       
  1597     }
       
  1598 }
       
  1599 
       
  1600 
       
  1601 void QWidget::grabKeyboard()
       
  1602 {
       
  1603     if (!qt_nograb()) {
       
  1604         if (QWidgetPrivate::keyboardGrabber && QWidgetPrivate::keyboardGrabber != this)
       
  1605             QWidgetPrivate::keyboardGrabber->releaseKeyboard();
       
  1606         XGrabKeyboard(X11->display, effectiveWinId(), False, GrabModeAsync, GrabModeAsync,
       
  1607                       X11->time);
       
  1608         QWidgetPrivate::keyboardGrabber = this;
       
  1609     }
       
  1610 }
       
  1611 
       
  1612 
       
  1613 void QWidget::releaseKeyboard()
       
  1614 {
       
  1615     if (!qt_nograb() && QWidgetPrivate::keyboardGrabber == this) {
       
  1616         XUngrabKeyboard(X11->display, X11->time);
       
  1617         QWidgetPrivate::keyboardGrabber = 0;
       
  1618     }
       
  1619 }
       
  1620 
       
  1621 
       
  1622 QWidget *QWidget::mouseGrabber()
       
  1623 {
       
  1624     return QWidgetPrivate::mouseGrabber;
       
  1625 }
       
  1626 
       
  1627 
       
  1628 QWidget *QWidget::keyboardGrabber()
       
  1629 {
       
  1630     return QWidgetPrivate::keyboardGrabber;
       
  1631 }
       
  1632 
       
  1633 void QWidget::activateWindow()
       
  1634 {
       
  1635     QWidget *tlw = window();
       
  1636     if (tlw->isVisible() && !tlw->d_func()->topData()->embedded && !X11->deferred_map.contains(tlw)) {
       
  1637         if (X11->userTime == 0)
       
  1638             X11->userTime = X11->time;
       
  1639         qt_net_update_user_time(tlw, X11->userTime);
       
  1640         XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time);
       
  1641     }
       
  1642 }
       
  1643 
       
  1644 void QWidget::setWindowState(Qt::WindowStates newstate)
       
  1645 {
       
  1646     Q_D(QWidget);
       
  1647     bool needShow = false;
       
  1648     Qt::WindowStates oldstate = windowState();
       
  1649     if (oldstate == newstate)
       
  1650         return;
       
  1651     if (isWindow()) {
       
  1652         // Ensure the initial size is valid, since we store it as normalGeometry below.
       
  1653         if (!testAttribute(Qt::WA_Resized) && !isVisible())
       
  1654             adjustSize();
       
  1655 
       
  1656         QTLWExtra *top = d->topData();
       
  1657 
       
  1658         if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
       
  1659             if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
       
  1660                 && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))) {
       
  1661                 if ((newstate & Qt::WindowMaximized) && !(oldstate & Qt::WindowFullScreen))
       
  1662                     top->normalGeometry = geometry();
       
  1663                 qt_change_net_wm_state(this, (newstate & Qt::WindowMaximized),
       
  1664                                        ATOM(_NET_WM_STATE_MAXIMIZED_HORZ),
       
  1665                                        ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
       
  1666             } else if (! (newstate & Qt::WindowFullScreen)) {
       
  1667                 if (newstate & Qt::WindowMaximized) {
       
  1668                     // save original geometry
       
  1669                     const QRect normalGeometry = geometry();
       
  1670 
       
  1671                     if (isVisible()) {
       
  1672                         data->fstrut_dirty = true;
       
  1673                         const QRect maxRect = QApplication::desktop()->availableGeometry(this);
       
  1674                         const QRect r = top->normalGeometry;
       
  1675                         const QRect fs = d->frameStrut();
       
  1676                         setGeometry(maxRect.x() + fs.left(),
       
  1677                                     maxRect.y() + fs.top(),
       
  1678                                     maxRect.width() - fs.left() - fs.right(),
       
  1679                                     maxRect.height() - fs.top() - fs.bottom());
       
  1680                         top->normalGeometry = r;
       
  1681                     }
       
  1682 
       
  1683                     if (top->normalGeometry.width() < 0)
       
  1684                         top->normalGeometry = normalGeometry;
       
  1685                 } else {
       
  1686                     // restore original geometry
       
  1687                     setGeometry(top->normalGeometry);
       
  1688                 }
       
  1689             }
       
  1690         }
       
  1691 
       
  1692         if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
       
  1693             if (X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
       
  1694                 if (newstate & Qt::WindowFullScreen) {
       
  1695                     top->normalGeometry = geometry();
       
  1696                     top->fullScreenOffset = d->frameStrut().topLeft();
       
  1697                 }
       
  1698                 qt_change_net_wm_state(this, (newstate & Qt::WindowFullScreen),
       
  1699                                        ATOM(_NET_WM_STATE_FULLSCREEN));
       
  1700             } else {
       
  1701                 needShow = isVisible();
       
  1702 
       
  1703                 if (newstate & Qt::WindowFullScreen) {
       
  1704                     data->fstrut_dirty = true;
       
  1705                     const QRect normalGeometry = geometry();
       
  1706                     const QPoint fullScreenOffset = d->frameStrut().topLeft();
       
  1707 
       
  1708                     top->savedFlags = windowFlags();
       
  1709                     setParent(0, Qt::Window | Qt::FramelessWindowHint);
       
  1710                     const QRect r = top->normalGeometry;
       
  1711                     setGeometry(qApp->desktop()->screenGeometry(this));
       
  1712                     top->normalGeometry = r;
       
  1713 
       
  1714                     if (top->normalGeometry.width() < 0) {
       
  1715                         top->normalGeometry = normalGeometry;
       
  1716                         top->fullScreenOffset = fullScreenOffset;
       
  1717                     }
       
  1718                 } else {
       
  1719                     setParent(0, top->savedFlags);
       
  1720 
       
  1721                     if (newstate & Qt::WindowMaximized) {
       
  1722                         // from fullscreen to maximized
       
  1723                         data->fstrut_dirty = true;
       
  1724                         const QRect maxRect = QApplication::desktop()->availableGeometry(this);
       
  1725                         const QRect r = top->normalGeometry;
       
  1726                         const QRect fs = d->frameStrut();
       
  1727                         setGeometry(maxRect.x() + fs.left(),
       
  1728                                     maxRect.y() + fs.top(),
       
  1729                                     maxRect.width() - fs.left() - fs.right(),
       
  1730                                     maxRect.height() - fs.top() - fs.bottom());
       
  1731                         top->normalGeometry = r;
       
  1732                     } else {
       
  1733                         // restore original geometry
       
  1734                         setGeometry(top->normalGeometry.adjusted(-top->fullScreenOffset.x(),
       
  1735                                                                  -top->fullScreenOffset.y(),
       
  1736                                                                  -top->fullScreenOffset.x(),
       
  1737                                                                  -top->fullScreenOffset.y()));
       
  1738                     }
       
  1739                 }
       
  1740             }
       
  1741         }
       
  1742 
       
  1743         createWinId();
       
  1744         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
  1745         if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
       
  1746             if (isVisible()) {
       
  1747                 if (newstate & Qt::WindowMinimized) {
       
  1748                     XEvent e;
       
  1749                     e.xclient.type = ClientMessage;
       
  1750                     e.xclient.message_type = ATOM(WM_CHANGE_STATE);
       
  1751                     e.xclient.display = X11->display;
       
  1752                     e.xclient.window = data->winid;
       
  1753                     e.xclient.format = 32;
       
  1754                     e.xclient.data.l[0] = IconicState;
       
  1755                     e.xclient.data.l[1] = 0;
       
  1756                     e.xclient.data.l[2] = 0;
       
  1757                     e.xclient.data.l[3] = 0;
       
  1758                     e.xclient.data.l[4] = 0;
       
  1759                     XSendEvent(X11->display,
       
  1760                                RootWindow(X11->display,d->xinfo.screen()),
       
  1761                                False, (SubstructureNotifyMask|SubstructureRedirectMask), &e);
       
  1762                 } else {
       
  1763                     setAttribute(Qt::WA_Mapped);
       
  1764                     XMapWindow(X11->display, effectiveWinId());
       
  1765                 }
       
  1766             }
       
  1767 
       
  1768             needShow = false;
       
  1769         }
       
  1770     }
       
  1771 
       
  1772     data->window_state = newstate;
       
  1773 
       
  1774     if (needShow)
       
  1775         show();
       
  1776 
       
  1777     if (newstate & Qt::WindowActive)
       
  1778         activateWindow();
       
  1779 
       
  1780     QWindowStateChangeEvent e(oldstate);
       
  1781     QApplication::sendEvent(this, &e);
       
  1782 }
       
  1783 
       
  1784 /*!
       
  1785   \internal
       
  1786   Platform-specific part of QWidget::show().
       
  1787 */
       
  1788 
       
  1789 void QWidgetPrivate::show_sys()
       
  1790 {
       
  1791     Q_Q(QWidget);
       
  1792     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1793 
       
  1794     if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
       
  1795         invalidateBuffer(q->rect());
       
  1796         q->setAttribute(Qt::WA_Mapped);
       
  1797         if (QTLWExtra *tlwExtra = maybeTopData())
       
  1798             tlwExtra->waitingForMapNotify = 0;
       
  1799         return;
       
  1800     }
       
  1801 
       
  1802     if (q->isWindow()) {
       
  1803         XWMHints *h = XGetWMHints(X11->display, q->internalWinId());
       
  1804         XWMHints  wm_hints;
       
  1805         bool got_hints = h != 0;
       
  1806         if (!got_hints) {
       
  1807             memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
       
  1808             h = &wm_hints;
       
  1809         }
       
  1810         h->initial_state = q->isMinimized() ? IconicState : NormalState;
       
  1811         h->flags |= StateHint;
       
  1812         XSetWMHints(X11->display, q->internalWinId(), h);
       
  1813         if (got_hints)
       
  1814             XFree((char *)h);
       
  1815 
       
  1816         // update WM_NORMAL_HINTS
       
  1817         do_size_hints(q, extra);
       
  1818 
       
  1819         // udpate WM_TRANSIENT_FOR
       
  1820         if (isTransient(q)) {
       
  1821             QWidget *p = q->parentWidget();
       
  1822 
       
  1823 #ifndef QT_NO_MENU
       
  1824             // hackish ... try to find the main window related to this QMenu
       
  1825             if (qobject_cast<QMenu *>(q)) {
       
  1826                 p = static_cast<QMenuPrivate*>(this)->causedPopup.widget;
       
  1827                 if (!p)
       
  1828                     p = q->parentWidget();
       
  1829                 if (!p)
       
  1830                     p = QApplication::widgetAt(q->pos());
       
  1831                 if (!p)
       
  1832                     p = qApp->activeWindow();
       
  1833             }
       
  1834 #endif
       
  1835             if (p)
       
  1836                 p = p->window();
       
  1837             if (p) {
       
  1838                 // transient for window
       
  1839                 XSetTransientForHint(X11->display, q->internalWinId(), p->internalWinId());
       
  1840             } else {
       
  1841                 // transient for group
       
  1842                 XSetTransientForHint(X11->display, q->internalWinId(), X11->wm_client_leader);
       
  1843             }
       
  1844         }
       
  1845 
       
  1846         // update _MOTIF_WM_HINTS
       
  1847         QtMWMHints mwmhints = GetMWMHints(X11->display, q->internalWinId());
       
  1848 
       
  1849         if (data.window_modality != Qt::NonModal) {
       
  1850             switch (data.window_modality) {
       
  1851             case Qt::WindowModal:
       
  1852                 mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL;
       
  1853                 break;
       
  1854             case Qt::ApplicationModal:
       
  1855             default:
       
  1856                 mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL;
       
  1857                 break;
       
  1858             }
       
  1859             mwmhints.flags |= MWM_HINTS_INPUT_MODE;
       
  1860         } else {
       
  1861             mwmhints.input_mode = MWM_INPUT_MODELESS;
       
  1862             mwmhints.flags &= ~MWM_HINTS_INPUT_MODE;
       
  1863         }
       
  1864 
       
  1865         if (q->minimumSize() == q->maximumSize()) {
       
  1866             // fixed size, remove the resize handle (since mwm/dtwm
       
  1867             // isn't smart enough to do it itself)
       
  1868             mwmhints.flags |= MWM_HINTS_FUNCTIONS;
       
  1869             if (mwmhints.functions == MWM_FUNC_ALL) {
       
  1870                 mwmhints.functions = MWM_FUNC_MOVE;
       
  1871             } else {
       
  1872                 mwmhints.functions &= ~MWM_FUNC_RESIZE;
       
  1873             }
       
  1874 
       
  1875             if (mwmhints.decorations == MWM_DECOR_ALL) {
       
  1876                 mwmhints.flags |= MWM_HINTS_DECORATIONS;
       
  1877                 mwmhints.decorations = (MWM_DECOR_BORDER
       
  1878                                         | MWM_DECOR_TITLE
       
  1879                                         | MWM_DECOR_MENU);
       
  1880             } else {
       
  1881                 mwmhints.decorations &= ~MWM_DECOR_RESIZEH;
       
  1882             }
       
  1883 
       
  1884             if (q->windowFlags() & Qt::WindowMinimizeButtonHint) {
       
  1885                 mwmhints.flags |= MWM_HINTS_DECORATIONS;
       
  1886                 mwmhints.decorations |= MWM_DECOR_MINIMIZE;
       
  1887                 mwmhints.functions |= MWM_FUNC_MINIMIZE;
       
  1888             }
       
  1889             if (q->windowFlags() & Qt::WindowMaximizeButtonHint) {
       
  1890                 mwmhints.flags |= MWM_HINTS_DECORATIONS;
       
  1891                 mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
       
  1892                 mwmhints.functions |= MWM_FUNC_MAXIMIZE;
       
  1893             }
       
  1894             if (q->windowFlags() & Qt::WindowCloseButtonHint)
       
  1895                 mwmhints.functions |= MWM_FUNC_CLOSE;
       
  1896         }
       
  1897 
       
  1898         SetMWMHints(X11->display, q->internalWinId(), mwmhints);
       
  1899 
       
  1900         // update _NET_WM_STATE
       
  1901         QVector<Atom> netWmState = getNetWmState(q);
       
  1902 
       
  1903         Qt::WindowFlags flags = q->windowFlags();
       
  1904         if (flags & Qt::WindowStaysOnTopHint) {
       
  1905             if (flags & Qt::WindowStaysOnBottomHint)
       
  1906                 qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
       
  1907             netWmState.append(ATOM(_NET_WM_STATE_ABOVE));
       
  1908             netWmState.append(ATOM(_NET_WM_STATE_STAYS_ON_TOP));
       
  1909         } else if (flags & Qt::WindowStaysOnBottomHint) {
       
  1910             netWmState.append(ATOM(_NET_WM_STATE_BELOW));
       
  1911         }
       
  1912         if (q->isFullScreen()) {
       
  1913             netWmState.append(ATOM(_NET_WM_STATE_FULLSCREEN));
       
  1914         }
       
  1915         if (q->isMaximized()) {
       
  1916             netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ));
       
  1917             netWmState.append(ATOM(_NET_WM_STATE_MAXIMIZED_VERT));
       
  1918         }
       
  1919         if (data.window_modality != Qt::NonModal) {
       
  1920             netWmState.append(ATOM(_NET_WM_STATE_MODAL));
       
  1921         }
       
  1922 
       
  1923         if (!netWmState.isEmpty()) {
       
  1924             XChangeProperty(X11->display, q->internalWinId(),
       
  1925                             ATOM(_NET_WM_STATE), XA_ATOM, 32, PropModeReplace,
       
  1926                             (unsigned char *) netWmState.data(), netWmState.size());
       
  1927         } else {
       
  1928             XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_STATE));
       
  1929         }
       
  1930 
       
  1931         // set _NET_WM_USER_TIME
       
  1932         Time userTime = X11->userTime;
       
  1933         bool setUserTime = false;
       
  1934         if (q->testAttribute(Qt::WA_ShowWithoutActivating)) {
       
  1935             userTime = 0;
       
  1936             setUserTime = true;
       
  1937         } else if (userTime != CurrentTime) {
       
  1938             setUserTime = true;
       
  1939         }
       
  1940         if (setUserTime)
       
  1941             qt_net_update_user_time(q, userTime);
       
  1942 
       
  1943 #ifndef QT_NO_XSYNC
       
  1944         if (!topData()->syncUpdateCounter) {
       
  1945             XSyncValue value;
       
  1946             XSyncIntToValue(&value, 0);
       
  1947             topData()->syncUpdateCounter = XSyncCreateCounter(X11->display, value);
       
  1948 
       
  1949             XChangeProperty(X11->display, q->internalWinId(),
       
  1950                             ATOM(_NET_WM_SYNC_REQUEST_COUNTER),
       
  1951                             XA_CARDINAL,
       
  1952                             32, PropModeReplace,
       
  1953                             (uchar *) &topData()->syncUpdateCounter, 1);
       
  1954 
       
  1955             topData()->newCounterValueHi = 0;
       
  1956             topData()->newCounterValueLo = 0;
       
  1957         }
       
  1958 #endif
       
  1959 
       
  1960         if (!topData()->embedded
       
  1961             && (topData()->validWMState || topData()->waitingForMapNotify)
       
  1962             && !q->isMinimized()) {
       
  1963             X11->deferred_map.append(q);
       
  1964             return;
       
  1965         }
       
  1966 
       
  1967         if (q->isMaximized() && !q->isFullScreen()
       
  1968             && !(X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ))
       
  1969                  && X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)))) {
       
  1970             XMapWindow(X11->display, q->internalWinId());
       
  1971             data.fstrut_dirty = true;
       
  1972             qt_x11_wait_for_window_manager(q);
       
  1973 
       
  1974             // if the wm was not smart enough to adjust our size, do that manually
       
  1975             QRect maxRect = QApplication::desktop()->availableGeometry(q);
       
  1976 
       
  1977             QTLWExtra *top = topData();
       
  1978             QRect normalRect = top->normalGeometry;
       
  1979             const QRect fs = frameStrut();
       
  1980 
       
  1981             q->setGeometry(maxRect.x() + fs.left(),
       
  1982                            maxRect.y() + fs.top(),
       
  1983                            maxRect.width() - fs.left() - fs.right(),
       
  1984                            maxRect.height() - fs.top() - fs.bottom());
       
  1985 
       
  1986             // restore the original normalGeometry
       
  1987             top->normalGeometry = normalRect;
       
  1988             // internalSetGeometry() clears the maximized flag... make sure we set it back
       
  1989             data.window_state = data.window_state | Qt::WindowMaximized;
       
  1990             q->setAttribute(Qt::WA_Mapped);
       
  1991             return;
       
  1992         }
       
  1993 
       
  1994         if (q->isFullScreen() && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN))) {
       
  1995             XMapWindow(X11->display, q->internalWinId());
       
  1996             qt_x11_wait_for_window_manager(q);
       
  1997             q->setAttribute(Qt::WA_Mapped);
       
  1998             return;
       
  1999         }
       
  2000     }
       
  2001 
       
  2002     invalidateBuffer(q->rect());
       
  2003 
       
  2004     if (q->testAttribute(Qt::WA_OutsideWSRange))
       
  2005         return;
       
  2006     q->setAttribute(Qt::WA_Mapped);
       
  2007     if (q->isWindow())
       
  2008         topData()->waitingForMapNotify = 1;
       
  2009 
       
  2010     if (!q->isWindow()
       
  2011         && (!q->autoFillBackground()
       
  2012             || q->palette().brush(q->backgroundRole()).style() == Qt::LinearGradientPattern)) {
       
  2013         if (q->internalWinId()) {
       
  2014             XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
       
  2015             XMapWindow(X11->display, q->internalWinId());
       
  2016             updateSystemBackground();
       
  2017         }
       
  2018         return;
       
  2019     }
       
  2020 
       
  2021     if (q->internalWinId())
       
  2022         XMapWindow(X11->display, q->internalWinId());
       
  2023 
       
  2024     // Freedesktop.org Startup Notification
       
  2025     if (X11->startupId && q->isWindow()) {
       
  2026         QByteArray message("remove: ID=");
       
  2027         message.append(X11->startupId);
       
  2028         sendStartupMessage(message.constData());
       
  2029         X11->startupId = 0;
       
  2030     }
       
  2031 }
       
  2032 
       
  2033 /*!
       
  2034   \internal
       
  2035   Platform-specific part of QWidget::show().
       
  2036 */
       
  2037 
       
  2038 void QWidgetPrivate::sendStartupMessage(const char *message) const
       
  2039 {
       
  2040     Q_Q(const QWidget);
       
  2041 
       
  2042     if (!message)
       
  2043         return;
       
  2044 
       
  2045     XEvent xevent;
       
  2046     xevent.xclient.type = ClientMessage;
       
  2047     xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO_BEGIN);
       
  2048     xevent.xclient.display = X11->display;
       
  2049     xevent.xclient.window = q->internalWinId();
       
  2050     xevent.xclient.format = 8;
       
  2051 
       
  2052     Window rootWindow = RootWindow(X11->display, DefaultScreen(X11->display));
       
  2053     uint sent = 0;
       
  2054     uint length = strlen(message) + 1;
       
  2055     do {
       
  2056         if (sent == 20)
       
  2057             xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO);
       
  2058 
       
  2059         for (uint i = 0; i < 20 && i + sent <= length; i++)
       
  2060             xevent.xclient.data.b[i] = message[i + sent++];
       
  2061 
       
  2062         XSendEvent(X11->display, rootWindow, false, PropertyChangeMask, &xevent);
       
  2063     } while (sent <= length);
       
  2064 }
       
  2065 
       
  2066 void QWidgetPrivate::setNetWmWindowTypes()
       
  2067 {
       
  2068     Q_Q(QWidget);
       
  2069     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  2070 
       
  2071     if (!q->isWindow()) {
       
  2072         if (q->internalWinId())
       
  2073             XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_WINDOW_TYPE));
       
  2074         return;
       
  2075     }
       
  2076 
       
  2077     QVector<long> windowTypes;
       
  2078 
       
  2079     // manual selection 1 (these are never set by Qt and take precedence)
       
  2080     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDesktop))
       
  2081         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DESKTOP));
       
  2082     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDock))
       
  2083         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DOCK));
       
  2084     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeNotification))
       
  2085         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NOTIFICATION));
       
  2086 
       
  2087     // manual selection 2 (Qt uses these during auto selection);
       
  2088     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeUtility))
       
  2089         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
       
  2090     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeSplash))
       
  2091         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
       
  2092     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDialog))
       
  2093         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
       
  2094     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip))
       
  2095         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));
       
  2096 
       
  2097     // manual selection 3 (these can be set by Qt, but don't have a
       
  2098     // corresponding Qt::WindowType). note that order of the *MENU
       
  2099     // atoms is important
       
  2100     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeMenu))
       
  2101         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_MENU));
       
  2102     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu))
       
  2103         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU));
       
  2104     if (q->testAttribute(Qt::WA_X11NetWmWindowTypePopupMenu))
       
  2105         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_POPUP_MENU));
       
  2106     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolBar))
       
  2107         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLBAR));
       
  2108     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeCombo))
       
  2109         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_COMBO));
       
  2110     if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDND))
       
  2111         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DND));
       
  2112 
       
  2113     // automatic selection
       
  2114     switch (q->windowType()) {
       
  2115     case Qt::Dialog:
       
  2116     case Qt::Sheet:
       
  2117         // dialog netwm type
       
  2118         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_DIALOG));
       
  2119         break;
       
  2120 
       
  2121     case Qt::Tool:
       
  2122     case Qt::Drawer:
       
  2123         // utility netwm type
       
  2124         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_UTILITY));
       
  2125         break;
       
  2126 
       
  2127     case Qt::ToolTip:
       
  2128         // tooltip netwm type
       
  2129         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_TOOLTIP));
       
  2130         break;
       
  2131 
       
  2132     case Qt::SplashScreen:
       
  2133         // splash netwm type
       
  2134         windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_SPLASH));
       
  2135         break;
       
  2136 
       
  2137     default:
       
  2138         break;
       
  2139     }
       
  2140 
       
  2141     if (q->windowFlags() & Qt::FramelessWindowHint) {
       
  2142         // override netwm type - quick and easy for KDE noborder
       
  2143         windowTypes.append(ATOM(_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
       
  2144     }
       
  2145 
       
  2146     // normal netwm type - default
       
  2147     windowTypes.append(ATOM(_NET_WM_WINDOW_TYPE_NORMAL));
       
  2148 
       
  2149     if (!windowTypes.isEmpty()) {
       
  2150         XChangeProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE), XA_ATOM, 32,
       
  2151                         PropModeReplace, (unsigned char *) windowTypes.constData(),
       
  2152                         windowTypes.count());
       
  2153     } else {
       
  2154         XDeleteProperty(X11->display, q->winId(), ATOM(_NET_WM_WINDOW_TYPE));
       
  2155     }
       
  2156 }
       
  2157 
       
  2158 /*!
       
  2159   \internal
       
  2160   Platform-specific part of QWidget::hide().
       
  2161 */
       
  2162 
       
  2163 void QWidgetPrivate::hide_sys()
       
  2164 {
       
  2165     Q_Q(QWidget);
       
  2166     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  2167     deactivateWidgetCleanup();
       
  2168     if (q->isWindow()) {
       
  2169         X11->deferred_map.removeAll(q);
       
  2170         if (q->internalWinId()) // in nsplugin, may be 0
       
  2171             XWithdrawWindow(X11->display, q->internalWinId(), xinfo.screen());
       
  2172         XFlush(X11->display);
       
  2173     } else {
       
  2174         invalidateBuffer(q->rect());
       
  2175         if (q->internalWinId()) // in nsplugin, may be 0
       
  2176             XUnmapWindow(X11->display, q->internalWinId());
       
  2177     }
       
  2178     q->setAttribute(Qt::WA_Mapped, false);
       
  2179 }
       
  2180 
       
  2181 void QWidgetPrivate::setFocus_sys()
       
  2182 {
       
  2183 
       
  2184 }
       
  2185 
       
  2186 
       
  2187 void QWidgetPrivate::raise_sys()
       
  2188 {
       
  2189     Q_Q(QWidget);
       
  2190     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  2191     if (q->internalWinId())
       
  2192         XRaiseWindow(X11->display, q->internalWinId());
       
  2193 }
       
  2194 
       
  2195 void QWidgetPrivate::lower_sys()
       
  2196 {
       
  2197     Q_Q(QWidget);
       
  2198     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  2199     if (q->internalWinId())
       
  2200         XLowerWindow(X11->display, q->internalWinId());
       
  2201     if(!q->isWindow())
       
  2202         invalidateBuffer(q->rect());
       
  2203 }
       
  2204 
       
  2205 void QWidgetPrivate::stackUnder_sys(QWidget* w)
       
  2206 {
       
  2207     Q_Q(QWidget);
       
  2208     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  2209     if (q->internalWinId() && w->internalWinId()) {
       
  2210         Window stack[2];
       
  2211         stack[0] = w->internalWinId();;
       
  2212         stack[1] = q->internalWinId();
       
  2213         XRestackWindows(X11->display, stack, 2);
       
  2214     }
       
  2215     if(!q->isWindow() || !w->internalWinId())
       
  2216         invalidateBuffer(q->rect());
       
  2217 }
       
  2218 
       
  2219 
       
  2220 static void do_size_hints(QWidget* widget, QWExtra *x)
       
  2221 {
       
  2222     Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
       
  2223     XSizeHints s;
       
  2224     s.flags = 0;
       
  2225     if (x) {
       
  2226         QRect g = widget->geometry();
       
  2227         s.x = g.x();
       
  2228         s.y = g.y();
       
  2229         s.width = g.width();
       
  2230         s.height = g.height();
       
  2231         if (x->minw > 0 || x->minh > 0) {
       
  2232             // add minimum size hints
       
  2233             s.flags |= PMinSize;
       
  2234             s.min_width  = qMin(XCOORD_MAX, x->minw);
       
  2235             s.min_height = qMin(XCOORD_MAX, x->minh);
       
  2236         }
       
  2237         if (x->maxw < QWIDGETSIZE_MAX || x->maxh < QWIDGETSIZE_MAX) {
       
  2238             // add maximum size hints
       
  2239             s.flags |= PMaxSize;
       
  2240             s.max_width  = qMin(XCOORD_MAX, x->maxw);
       
  2241             s.max_height = qMin(XCOORD_MAX, x->maxh);
       
  2242         }
       
  2243         if (x->topextra &&
       
  2244             (x->topextra->incw > 0 || x->topextra->inch > 0)) {
       
  2245             // add resize increment hints
       
  2246             s.flags |= PResizeInc | PBaseSize;
       
  2247             s.width_inc = x->topextra->incw;
       
  2248             s.height_inc = x->topextra->inch;
       
  2249             s.base_width = x->topextra->basew;
       
  2250             s.base_height = x->topextra->baseh;
       
  2251         }
       
  2252     }
       
  2253     if (widget->testAttribute(Qt::WA_Moved)) {
       
  2254         // user (i.e. command-line) specified position
       
  2255         s.flags |= USPosition;
       
  2256         s.flags |= PPosition;
       
  2257     }
       
  2258     if (widget->testAttribute(Qt::WA_Resized)) {
       
  2259         // user (i.e. command-line) specified size
       
  2260         s.flags |= USSize;
       
  2261         s.flags |= PSize;
       
  2262     }
       
  2263     s.flags |= PWinGravity;
       
  2264     if (widget->testAttribute(Qt::WA_Moved) && x && x->topextra && !x->topextra->posFromMove) {
       
  2265         // position came from setGeometry(), tell the WM that we don't
       
  2266         // want our window gravity-shifted
       
  2267         s.win_gravity = StaticGravity;
       
  2268     } else {
       
  2269         // position came from move()
       
  2270         s.x = widget->x();
       
  2271         s.y = widget->y();
       
  2272         s.win_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
       
  2273     }
       
  2274     if (widget->internalWinId())
       
  2275         XSetWMNormalHints(X11->display, widget->internalWinId(), &s);
       
  2276 }
       
  2277 
       
  2278 
       
  2279 /*
       
  2280   Helper function for non-toplevel widgets. Helps to map Qt's 32bit
       
  2281   coordinate system to X11's 16bit coordinate system.
       
  2282 
       
  2283   Sets the geometry of the widget to data.crect, but clipped to sizes
       
  2284   that X can handle. Unmaps widgets that are completely outside the
       
  2285   valid range.
       
  2286 
       
  2287   Maintains data.wrect, which is the geometry of the X widget,
       
  2288   measured in this widget's coordinate system.
       
  2289 
       
  2290   if the parent is not clipped, parentWRect is empty, otherwise
       
  2291   parentWRect is the geometry of the parent's X rect, measured in
       
  2292   parent's coord sys
       
  2293  */
       
  2294 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &)
       
  2295 {
       
  2296     Q_Q(QWidget);
       
  2297     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  2298 
       
  2299     /*
       
  2300       There are up to four different coordinate systems here:
       
  2301       Qt coordinate system for this widget.
       
  2302       X coordinate system for this widget (relative to wrect).
       
  2303       Qt coordinate system for parent
       
  2304       X coordinate system for parent (relative to parent's wrect).
       
  2305      */
       
  2306     Display *dpy = xinfo.display();
       
  2307     QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX);
       
  2308     QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX);
       
  2309     QRect wrect;
       
  2310     //xrect is the X geometry of my X widget. (starts out in  parent's Qt coord sys, and ends up in parent's X coord sys)
       
  2311     QRect xrect = data.crect;
       
  2312 
       
  2313     const QWidget *const parent = q->parentWidget();
       
  2314     QRect parentWRect = parent->data->wrect;
       
  2315 
       
  2316     if (parentWRect.isValid()) {
       
  2317         // parent is clipped, and we have to clip to the same limit as parent
       
  2318         if (!parentWRect.contains(xrect)) {
       
  2319             xrect &= parentWRect;
       
  2320             wrect = xrect;
       
  2321             //translate from parent's to my Qt coord sys
       
  2322             wrect.translate(-data.crect.topLeft());
       
  2323         }
       
  2324         //translate from parent's Qt coords to parent's X coords
       
  2325         xrect.translate(-parentWRect.topLeft());
       
  2326 
       
  2327     } else {
       
  2328         // parent is not clipped, we may or may not have to clip
       
  2329 
       
  2330         if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) {
       
  2331             // This is where the main optimization is: we are already
       
  2332             // clipped, and if our clip is still valid, we can just
       
  2333             // move our window, and do not need to move or clip
       
  2334             // children
       
  2335 
       
  2336             QRect vrect = xrect & parent->rect();
       
  2337             vrect.translate(-data.crect.topLeft()); //the part of me that's visible through parent, in my Qt coords
       
  2338             if (data.wrect.contains(vrect)) {
       
  2339                 xrect = data.wrect;
       
  2340                 xrect.translate(data.crect.topLeft());
       
  2341                 if (data.winid)
       
  2342                     XMoveWindow(dpy, data.winid, xrect.x(), xrect.y());
       
  2343                 return;
       
  2344             }
       
  2345         }
       
  2346 
       
  2347         if (!validRange.contains(xrect)) {
       
  2348             // we are too big, and must clip
       
  2349             xrect &=wrectRange;
       
  2350             wrect = xrect;
       
  2351             wrect.translate(-data.crect.topLeft());
       
  2352             //parent's X coord system is equal to parent's Qt coord
       
  2353             //sys, so we don't need to map xrect.
       
  2354         }
       
  2355 
       
  2356     }
       
  2357 
       
  2358     // unmap if we are outside the valid window system coord system
       
  2359     bool outsideRange = !xrect.isValid();
       
  2360     bool mapWindow = false;
       
  2361     if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) {
       
  2362         q->setAttribute(Qt::WA_OutsideWSRange, outsideRange);
       
  2363         if (outsideRange) {
       
  2364             if (data.winid)
       
  2365                 XUnmapWindow(dpy, data.winid);
       
  2366             q->setAttribute(Qt::WA_Mapped, false);
       
  2367         } else if (!q->isHidden()) {
       
  2368             mapWindow = true;
       
  2369         }
       
  2370     }
       
  2371 
       
  2372     if (outsideRange)
       
  2373         return;
       
  2374 
       
  2375     bool jump = (data.wrect != wrect);
       
  2376     data.wrect = wrect;
       
  2377 
       
  2378 
       
  2379     // and now recursively for all children...
       
  2380     // ### can be optimized
       
  2381     for (int i = 0; i < children.size(); ++i) {
       
  2382         QObject *object = children.at(i);
       
  2383         if (object->isWidgetType()) {
       
  2384             QWidget *w = static_cast<QWidget *>(object);
       
  2385             if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created))
       
  2386                 w->d_func()->setWSGeometry(jump);
       
  2387         }
       
  2388     }
       
  2389 
       
  2390     if (data.winid) {
       
  2391         // move ourselves to the new position and map (if necessary) after
       
  2392         // the movement. Rationale: moving unmapped windows is much faster
       
  2393         // than moving mapped windows
       
  2394         if (jump) //avoid flicker when jumping
       
  2395             XSetWindowBackgroundPixmap(dpy, data.winid, XNone);
       
  2396         if (!parent->internalWinId())
       
  2397             xrect.translate(parent->mapTo(q->nativeParentWidget(), QPoint(0, 0)));
       
  2398         XMoveResizeWindow(dpy, data.winid, xrect.x(), xrect.y(), xrect.width(), xrect.height());
       
  2399     }
       
  2400 
       
  2401     //to avoid flicker, we have to show children after the helper widget has moved
       
  2402     if (jump) {
       
  2403         for (int i = 0; i < children.size(); ++i) {
       
  2404             QObject *object = children.at(i);
       
  2405             if (object->isWidgetType()) {
       
  2406                 QWidget *w = static_cast<QWidget *>(object);
       
  2407                 if (!w->testAttribute(Qt::WA_OutsideWSRange) && !w->testAttribute(Qt::WA_Mapped) && !w->isHidden()) {
       
  2408                     w->setAttribute(Qt::WA_Mapped);
       
  2409                     if (w->internalWinId())
       
  2410                         XMapWindow(dpy, w->data->winid);
       
  2411                 }
       
  2412             }
       
  2413         }
       
  2414     }
       
  2415 
       
  2416 
       
  2417     if  (jump && data.winid)
       
  2418         XClearArea(dpy, data.winid, 0, 0, wrect.width(), wrect.height(), True);
       
  2419 
       
  2420     if (mapWindow && !dontShow) {
       
  2421         q->setAttribute(Qt::WA_Mapped);
       
  2422         if (data.winid)
       
  2423             XMapWindow(dpy, data.winid);
       
  2424     }
       
  2425 }
       
  2426 
       
  2427 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
       
  2428 {
       
  2429     Q_Q(QWidget);
       
  2430     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  2431     Display *dpy = X11->display;
       
  2432 
       
  2433     if ((q->windowType() == Qt::Desktop))
       
  2434         return;
       
  2435     if (q->isWindow()) {
       
  2436         if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_VERT))
       
  2437             && !X11->isSupportedByWM(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)))
       
  2438             data.window_state &= ~Qt::WindowMaximized;
       
  2439         if (!X11->isSupportedByWM(ATOM(_NET_WM_STATE_FULLSCREEN)))
       
  2440             data.window_state &= ~Qt::WindowFullScreen;
       
  2441         if (QTLWExtra *topData = maybeTopData())
       
  2442             topData->normalGeometry = QRect(0,0,-1,-1);
       
  2443     } else {
       
  2444         uint s = data.window_state;
       
  2445         s &= ~(Qt::WindowMaximized | Qt::WindowFullScreen);
       
  2446         data.window_state = s;
       
  2447     }
       
  2448     if (extra) {                                // any size restrictions?
       
  2449         w = qMin(w,extra->maxw);
       
  2450         h = qMin(h,extra->maxh);
       
  2451         w = qMax(w,extra->minw);
       
  2452         h = qMax(h,extra->minh);
       
  2453     }
       
  2454     QPoint oldPos(q->pos());
       
  2455     QSize oldSize(q->size());
       
  2456     QRect oldGeom(data.crect);
       
  2457     QRect  r(x, y, w, h);
       
  2458 
       
  2459     // We only care about stuff that changes the geometry, or may
       
  2460     // cause the window manager to change its state
       
  2461     if (!q->isWindow() && oldGeom == r)
       
  2462         return;
       
  2463 
       
  2464     data.crect = r;
       
  2465     bool isResize = q->size() != oldSize;
       
  2466 
       
  2467     if (q->isWindow()) {
       
  2468         if (w == 0 || h == 0) {
       
  2469             q->setAttribute(Qt::WA_OutsideWSRange, true);
       
  2470             if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
       
  2471                 hide_sys();
       
  2472         } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
       
  2473             q->setAttribute(Qt::WA_OutsideWSRange, false);
       
  2474 
       
  2475             // put the window in its place and show it
       
  2476             if (data.winid)
       
  2477                 XMoveResizeWindow(dpy, data.winid, x, y, w, h);
       
  2478             topData()->posFromMove = false; // force StaticGravity
       
  2479             do_size_hints(q, extra);
       
  2480             show_sys();
       
  2481         } else {
       
  2482             q->setAttribute(Qt::WA_OutsideWSRange, false);
       
  2483             if (!q->isVisible())
       
  2484                 do_size_hints(q, extra);
       
  2485             if (isMove) {
       
  2486                 if ((data.window_flags & Qt::X11BypassWindowManagerHint) == Qt::X11BypassWindowManagerHint
       
  2487                     // work around 4Dwm's incompliance with ICCCM 4.1.5
       
  2488                     || X11->desktopEnvironment == DE_4DWM) {
       
  2489                     if (data.winid)
       
  2490                         XMoveResizeWindow(dpy, data.winid, x, y, w, h);
       
  2491                 } else if (q->isVisible()
       
  2492                            && topData()->validWMState
       
  2493                            && X11->isSupportedByWM(ATOM(_NET_MOVERESIZE_WINDOW))) {
       
  2494                     XEvent e;
       
  2495                     e.xclient.type = ClientMessage;
       
  2496                     e.xclient.message_type = ATOM(_NET_MOVERESIZE_WINDOW);
       
  2497                     e.xclient.display = X11->display;
       
  2498                     e.xclient.window = q->internalWinId();
       
  2499                     e.xclient.format = 32;
       
  2500                     e.xclient.data.l[0] = StaticGravity | 1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12;
       
  2501                     e.xclient.data.l[1] = x;
       
  2502                     e.xclient.data.l[2] = y;
       
  2503                     e.xclient.data.l[3] = w;
       
  2504                     e.xclient.data.l[4] = h;
       
  2505                     XSendEvent(X11->display, RootWindow(X11->display, q->x11Info().screen()),
       
  2506                                false, (SubstructureNotifyMask | SubstructureRedirectMask), &e);
       
  2507                 } else if (data.winid) {
       
  2508                     // pos() is right according to ICCCM 4.1.5
       
  2509                     XMoveResizeWindow(dpy, data.winid, q->pos().x(), q->pos().y(), w, h);
       
  2510                 }
       
  2511             } else if (isResize && data.winid) {
       
  2512                 if (!q->isVisible()
       
  2513                     && topData()->validWMState
       
  2514                     && !q->testAttribute(Qt::WA_PendingMoveEvent)) {
       
  2515                     /*
       
  2516                        even though we've not visible, we could be in a
       
  2517                        race w/ the window manager, and it may ignore
       
  2518                        our ConfigureRequest. setting posFromMove to
       
  2519                        false makes sure that doDeferredMap() in
       
  2520                        qapplication_x11.cpp keeps the window in the
       
  2521                        right place
       
  2522                     */
       
  2523                     topData()->posFromMove = false;
       
  2524                 }
       
  2525                 XResizeWindow(dpy, data.winid, w, h);
       
  2526             }
       
  2527         }
       
  2528         if (isResize && !q->testAttribute(Qt::WA_DontShowOnScreen)) // set config pending only on resize, see qapplication_x11.cpp, translateConfigEvent()
       
  2529             q->setAttribute(Qt::WA_WState_ConfigPending);
       
  2530 
       
  2531     } else {
       
  2532         QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
       
  2533         const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false;
       
  2534         const bool disableInTopLevelResize = inTopLevelResize && q->internalWinId();
       
  2535         if (disableInTopLevelResize) {
       
  2536             // Top-level resize optimization does not work for native child widgets;
       
  2537             // disable it for this particular widget.
       
  2538             tlwExtra->inTopLevelResize = false;
       
  2539         }
       
  2540 
       
  2541         if (!isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible()) {
       
  2542             moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y());
       
  2543         }
       
  2544         if (q->testAttribute(Qt::WA_WState_Created))
       
  2545             setWSGeometry();
       
  2546 
       
  2547         if (isResize && (!inTopLevelResize || disableInTopLevelResize) && q->isVisible())
       
  2548             invalidateBuffer_resizeHelper(oldPos, oldSize);
       
  2549 
       
  2550         if (disableInTopLevelResize)
       
  2551             tlwExtra->inTopLevelResize = true;
       
  2552     }
       
  2553 
       
  2554     if (q->isVisible()) {
       
  2555         if (isMove && q->pos() != oldPos) {
       
  2556             if (X11->desktopEnvironment != DE_4DWM) {
       
  2557                 // pos() is right according to ICCCM 4.1.5
       
  2558                 QMoveEvent e(q->pos(), oldPos);
       
  2559                 QApplication::sendEvent(q, &e);
       
  2560             } else {
       
  2561                 // work around 4Dwm's incompliance with ICCCM 4.1.5
       
  2562                 QMoveEvent e(data.crect.topLeft(), oldGeom.topLeft());
       
  2563                 QApplication::sendEvent(q, &e);
       
  2564             }
       
  2565         }
       
  2566         if (isResize) {
       
  2567             static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
       
  2568             // If we have a backing store with static contents, we have to disable the top-level
       
  2569             // resize optimization in order to get invalidated regions for resized widgets.
       
  2570             // The optimization discards all invalidateBuffer() calls since we're going to
       
  2571             // repaint everything anyways, but that's not the case with static contents.
       
  2572             const bool setTopLevelResize = !slowResize && q->isWindow() && extra && extra->topextra
       
  2573                                            && !extra->topextra->inTopLevelResize
       
  2574                                            && (!extra->topextra->backingStore
       
  2575                                                || !extra->topextra->backingStore->hasStaticContents());
       
  2576             if (setTopLevelResize)
       
  2577                 extra->topextra->inTopLevelResize = true;
       
  2578             QResizeEvent e(q->size(), oldSize);
       
  2579             QApplication::sendEvent(q, &e);
       
  2580             if (setTopLevelResize)
       
  2581                 extra->topextra->inTopLevelResize = false;
       
  2582         }
       
  2583     } else {
       
  2584         if (isMove && q->pos() != oldPos)
       
  2585             q->setAttribute(Qt::WA_PendingMoveEvent, true);
       
  2586         if (isResize)
       
  2587             q->setAttribute(Qt::WA_PendingResizeEvent, true);
       
  2588     }
       
  2589 }
       
  2590 
       
  2591 void QWidgetPrivate::setConstraints_sys()
       
  2592 {
       
  2593     Q_Q(QWidget);
       
  2594 #ifdef ALIEN_DEBUG
       
  2595     qDebug() << "QWidgetPrivate::setConstraints_sys START" << q;
       
  2596 #endif
       
  2597     if (q->testAttribute(Qt::WA_WState_Created))
       
  2598         do_size_hints(q, extra);
       
  2599 #ifdef ALIEN_DEBUG
       
  2600     qDebug() << "QWidgetPrivate::setConstraints_sys END" << q;
       
  2601 #endif
       
  2602 }
       
  2603 
       
  2604 void QWidgetPrivate::scroll_sys(int dx, int dy)
       
  2605 {
       
  2606     Q_Q(QWidget);
       
  2607 
       
  2608     scrollChildren(dx, dy);
       
  2609     if (!paintOnScreen()) {
       
  2610         scrollRect(q->rect(), dx, dy);
       
  2611     } else {
       
  2612         scroll_sys(dx, dy, QRect());
       
  2613     }
       
  2614 }
       
  2615 
       
  2616 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
       
  2617 {
       
  2618     Q_Q(QWidget);
       
  2619 
       
  2620     if (!paintOnScreen()) {
       
  2621         scrollRect(r, dx, dy);
       
  2622         return;
       
  2623     }
       
  2624     bool valid_rect = r.isValid();
       
  2625     bool just_update = qAbs(dx) > q->width() || qAbs(dy) > q->height();
       
  2626     QRect sr = valid_rect ? r : clipRect();
       
  2627     if (just_update)
       
  2628         q->update();
       
  2629     else if (!valid_rect)
       
  2630         dirty.translate(dx, dy);
       
  2631 
       
  2632     int x1, y1, x2, y2, w = sr.width(), h = sr.height();
       
  2633     if (dx > 0) {
       
  2634         x1 = sr.x();
       
  2635         x2 = x1+dx;
       
  2636         w -= dx;
       
  2637     } else {
       
  2638         x2 = sr.x();
       
  2639         x1 = x2-dx;
       
  2640         w += dx;
       
  2641     }
       
  2642     if (dy > 0) {
       
  2643         y1 = sr.y();
       
  2644         y2 = y1+dy;
       
  2645         h -= dy;
       
  2646     } else {
       
  2647         y2 = sr.y();
       
  2648         y1 = y2-dy;
       
  2649         h += dy;
       
  2650     }
       
  2651 
       
  2652     if (dx == 0 && dy == 0)
       
  2653         return;
       
  2654 
       
  2655     Display *dpy = X11->display;
       
  2656     // Want expose events
       
  2657     if (w > 0 && h > 0 && !just_update && q->internalWinId()) {
       
  2658         GC gc = XCreateGC(dpy, q->internalWinId(), 0, 0);
       
  2659         XSetGraphicsExposures(dpy, gc, True);
       
  2660         XCopyArea(dpy, q->internalWinId(), q->internalWinId(), gc, x1, y1, w, h, x2, y2);
       
  2661         XFreeGC(dpy, gc);
       
  2662     }
       
  2663 
       
  2664     if (!valid_rect && !children.isEmpty()) {        // scroll children
       
  2665         QPoint pd(dx, dy);
       
  2666         for (int i = 0; i < children.size(); ++i) { // move all children
       
  2667             register QObject *object = children.at(i);
       
  2668             if (object->isWidgetType()) {
       
  2669                 QWidget *w = static_cast<QWidget *>(object);
       
  2670                 if (!w->isWindow())
       
  2671                     w->move(w->pos() + pd);
       
  2672             }
       
  2673         }
       
  2674     }
       
  2675 
       
  2676     if (just_update)
       
  2677         return;
       
  2678 
       
  2679     // Don't let the server be bogged-down with repaint events
       
  2680     bool repaint_immediately = (qt_sip_count(q) < 3 && !q->testAttribute(Qt::WA_WState_InPaintEvent));
       
  2681 
       
  2682     if (dx) {
       
  2683         int x = x2 == sr.x() ? sr.x()+w : sr.x();
       
  2684         if (repaint_immediately)
       
  2685             q->repaint(x, sr.y(), qAbs(dx), sr.height());
       
  2686         else if (q->internalWinId())
       
  2687             XClearArea(dpy, data.winid, x, sr.y(), qAbs(dx), sr.height(), True);
       
  2688     }
       
  2689     if (dy) {
       
  2690         int y = y2 == sr.y() ? sr.y()+h : sr.y();
       
  2691         if (repaint_immediately)
       
  2692             q->repaint(sr.x(), y, sr.width(), qAbs(dy));
       
  2693         else if (q->internalWinId())
       
  2694             XClearArea(dpy, data.winid, sr.x(), y, sr.width(), qAbs(dy), True);
       
  2695     }
       
  2696 
       
  2697     qt_insert_sip(q, dx, dy); // #### ignores r
       
  2698 }
       
  2699 
       
  2700 int QWidget::metric(PaintDeviceMetric m) const
       
  2701 {
       
  2702     Q_D(const QWidget);
       
  2703     int val;
       
  2704     if (m == PdmWidth) {
       
  2705         val = data->crect.width();
       
  2706     } else if (m == PdmHeight) {
       
  2707         val = data->crect.height();
       
  2708     } else {
       
  2709         Display *dpy = X11->display;
       
  2710         int scr = d->xinfo.screen();
       
  2711         switch (m) {
       
  2712             case PdmDpiX:
       
  2713             case PdmPhysicalDpiX:
       
  2714                 if (d->extra && d->extra->customDpiX)
       
  2715                     val = d->extra->customDpiX;
       
  2716                 else if (d->parent)
       
  2717                     val = static_cast<QWidget *>(d->parent)->metric(m);
       
  2718                 else
       
  2719                     val = QX11Info::appDpiX(scr);
       
  2720                 break;
       
  2721             case PdmDpiY:
       
  2722             case PdmPhysicalDpiY:
       
  2723                 if (d->extra && d->extra->customDpiY)
       
  2724                     val = d->extra->customDpiY;
       
  2725                 else if (d->parent)
       
  2726                     val = static_cast<QWidget *>(d->parent)->metric(m);
       
  2727                 else
       
  2728                     val = QX11Info::appDpiY(scr);
       
  2729                 break;
       
  2730             case PdmWidthMM:
       
  2731                 val = (DisplayWidthMM(dpy,scr)*data->crect.width())/
       
  2732                       DisplayWidth(dpy,scr);
       
  2733                 break;
       
  2734             case PdmHeightMM:
       
  2735                 val = (DisplayHeightMM(dpy,scr)*data->crect.height())/
       
  2736                       DisplayHeight(dpy,scr);
       
  2737                 break;
       
  2738             case PdmNumColors:
       
  2739                 val = d->xinfo.cells();
       
  2740                 break;
       
  2741             case PdmDepth:
       
  2742                 val = d->xinfo.depth();
       
  2743                 break;
       
  2744             default:
       
  2745                 val = 0;
       
  2746                 qWarning("QWidget::metric: Invalid metric command");
       
  2747         }
       
  2748     }
       
  2749     return val;
       
  2750 }
       
  2751 
       
  2752 void QWidgetPrivate::createSysExtra()
       
  2753 {
       
  2754     extra->compress_events = true;
       
  2755     extra->xDndProxy = 0;
       
  2756 }
       
  2757 
       
  2758 void QWidgetPrivate::deleteSysExtra()
       
  2759 {
       
  2760 }
       
  2761 
       
  2762 void QWidgetPrivate::createTLSysExtra()
       
  2763 {
       
  2764     extra->topextra->spont_unmapped = 0;
       
  2765     extra->topextra->dnd = 0;
       
  2766     extra->topextra->validWMState = 0;
       
  2767     extra->topextra->waitingForMapNotify = 0;
       
  2768     extra->topextra->parentWinId = 0;
       
  2769     extra->topextra->userTimeWindow = 0;
       
  2770 #ifndef QT_NO_XSYNC
       
  2771     extra->topextra->syncUpdateCounter = 0;
       
  2772     extra->topextra->syncRequestTimestamp = 0;
       
  2773     extra->topextra->newCounterValueHi = 0;
       
  2774     extra->topextra->newCounterValueLo = 0;
       
  2775 #endif
       
  2776 }
       
  2777 
       
  2778 void QWidgetPrivate::deleteTLSysExtra()
       
  2779 {
       
  2780     // don't destroy input context here. it will be destroyed in
       
  2781     // QWidget::destroy() destroyInputContext();
       
  2782 }
       
  2783 
       
  2784 void QWidgetPrivate::registerDropSite(bool on)
       
  2785 {
       
  2786     Q_UNUSED(on);
       
  2787 }
       
  2788 
       
  2789 void QWidgetPrivate::setMask_sys(const QRegion &region)
       
  2790 {
       
  2791     Q_Q(QWidget);
       
  2792     if (!q->internalWinId())
       
  2793         return;
       
  2794 
       
  2795     if (region.isEmpty()) {
       
  2796         XShapeCombineMask(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
       
  2797                           XNone, ShapeSet);
       
  2798     } else {
       
  2799         XShapeCombineRegion(X11->display, q->internalWinId(), ShapeBounding, 0, 0,
       
  2800                             region.handle(), ShapeSet);
       
  2801     }
       
  2802 }
       
  2803 
       
  2804 /*!
       
  2805   \internal
       
  2806 
       
  2807   Computes the frame rectangle when needed.  This is an internal function, you
       
  2808   should never call this.
       
  2809 */
       
  2810 
       
  2811 void QWidgetPrivate::updateFrameStrut()
       
  2812 {
       
  2813     Q_Q(QWidget);
       
  2814 
       
  2815     QTLWExtra *top = topData();
       
  2816     if (!top->validWMState) {
       
  2817         return;
       
  2818     }
       
  2819     if (!q->isWindow() && !q->internalWinId()) {
       
  2820         data.fstrut_dirty = false;
       
  2821         return;
       
  2822     }
       
  2823 
       
  2824     Atom type_ret;
       
  2825     Window l = q->effectiveWinId(), w = l, p, r; // target window, its parent, root
       
  2826     Window *c;
       
  2827     int i_unused;
       
  2828     unsigned int nc;
       
  2829     unsigned char *data_ret;
       
  2830     unsigned long l_unused;
       
  2831 
       
  2832     while (XQueryTree(X11->display, w, &r, &p, &c, &nc)) {
       
  2833         if (c && nc > 0)
       
  2834             XFree(c);
       
  2835 
       
  2836         if (! p) {
       
  2837             qWarning("QWidget::updateFrameStrut: No parent");
       
  2838             return;
       
  2839         }
       
  2840 
       
  2841         // if the parent window is the root window, an Enlightenment virtual root or
       
  2842         // a NET WM virtual root window, stop here
       
  2843         data_ret = 0;
       
  2844         if (p == r ||
       
  2845             (XGetWindowProperty(X11->display, p,
       
  2846                                 ATOM(ENLIGHTENMENT_DESKTOP), 0, 1, False, XA_CARDINAL,
       
  2847                                 &type_ret, &i_unused, &l_unused, &l_unused,
       
  2848                                 &data_ret) == Success &&
       
  2849              type_ret == XA_CARDINAL)) {
       
  2850             if (data_ret)
       
  2851                 XFree(data_ret);
       
  2852 
       
  2853             break;
       
  2854         } else if (X11->isSupportedByWM(ATOM(_NET_VIRTUAL_ROOTS)) && X11->net_virtual_root_list) {
       
  2855             int i = 0;
       
  2856             while (X11->net_virtual_root_list[i] != 0) {
       
  2857                 if (X11->net_virtual_root_list[i++] == p)
       
  2858                     break;
       
  2859             }
       
  2860         }
       
  2861 
       
  2862         l = w;
       
  2863         w = p;
       
  2864     }
       
  2865 
       
  2866     // we have our window
       
  2867     int transx, transy;
       
  2868     XWindowAttributes wattr;
       
  2869     if (XTranslateCoordinates(X11->display, l, w,
       
  2870                               0, 0, &transx, &transy, &p) &&
       
  2871         XGetWindowAttributes(X11->display, w, &wattr)) {
       
  2872         top->frameStrut.setCoords(transx,
       
  2873                                   transy,
       
  2874                                   wattr.width - data.crect.width() - transx,
       
  2875                                   wattr.height - data.crect.height() - transy);
       
  2876 
       
  2877         // add the border_width for the window managers frame... some window managers
       
  2878         // do not use a border_width of zero for their frames, and if we the left and
       
  2879         // top strut, we ensure that pos() is absolutely correct.  frameGeometry()
       
  2880         // will still be incorrect though... perhaps i should have foffset as well, to
       
  2881         // indicate the frame offset (equal to the border_width on X).
       
  2882         // - Brad
       
  2883         top->frameStrut.adjust(wattr.border_width,
       
  2884                                wattr.border_width,
       
  2885                                wattr.border_width,
       
  2886                                wattr.border_width);
       
  2887     }
       
  2888 
       
  2889    data.fstrut_dirty = false;
       
  2890 }
       
  2891 
       
  2892 void QWidgetPrivate::setWindowOpacity_sys(qreal opacity)
       
  2893 {
       
  2894     Q_Q(QWidget);
       
  2895     ulong value = ulong(opacity * 0xffffffff);
       
  2896     XChangeProperty(QX11Info::display(), q->internalWinId(), ATOM(_NET_WM_WINDOW_OPACITY), XA_CARDINAL,
       
  2897                     32, PropModeReplace, (uchar*)&value, 1);
       
  2898 }
       
  2899 
       
  2900 const QX11Info &QWidget::x11Info() const
       
  2901 {
       
  2902     Q_D(const QWidget);
       
  2903     return d->xinfo;
       
  2904 }
       
  2905 
       
  2906 void QWidgetPrivate::setWindowRole()
       
  2907 {
       
  2908     Q_Q(QWidget);
       
  2909     if (!q->internalWinId())
       
  2910         return;
       
  2911     QByteArray windowRole = topData()->role.toUtf8();
       
  2912     XChangeProperty(X11->display, q->internalWinId(),
       
  2913                     ATOM(WM_WINDOW_ROLE), XA_STRING, 8, PropModeReplace,
       
  2914                     (unsigned char *)windowRole.constData(), windowRole.length());
       
  2915 }
       
  2916 
       
  2917 Q_GLOBAL_STATIC(QX11PaintEngine, qt_widget_paintengine)
       
  2918 QPaintEngine *QWidget::paintEngine() const
       
  2919 {
       
  2920     Q_D(const QWidget);
       
  2921     if (qt_widget_paintengine()->isActive()) {
       
  2922         if (d->extraPaintEngine)
       
  2923             return d->extraPaintEngine;
       
  2924         QWidget *self = const_cast<QWidget *>(this);
       
  2925         self->d_func()->extraPaintEngine = new QX11PaintEngine();
       
  2926         return d->extraPaintEngine;
       
  2927     }
       
  2928     return qt_widget_paintengine();
       
  2929 }
       
  2930 
       
  2931 QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
       
  2932 {
       
  2933     return new QX11WindowSurface(q_func());
       
  2934 }
       
  2935 
       
  2936 Qt::HANDLE QWidget::x11PictureHandle() const
       
  2937 {
       
  2938 #ifndef QT_NO_XRENDER
       
  2939     Q_D(const QWidget);
       
  2940     if (!internalWinId() && testAttribute(Qt::WA_WState_Created))
       
  2941         (void)winId(); // enforce native window
       
  2942     return d->picture;
       
  2943 #else
       
  2944     return 0;
       
  2945 #endif // QT_NO_XRENDER
       
  2946 }
       
  2947 
       
  2948 #ifndef QT_NO_XRENDER
       
  2949 XRenderColor QX11Data::preMultiply(const QColor &c)
       
  2950 {
       
  2951     XRenderColor color;
       
  2952     const uint A = c.alpha(),
       
  2953                R = c.red(),
       
  2954                G = c.green(),
       
  2955                B = c.blue();
       
  2956     color.alpha = (A | A << 8);
       
  2957     color.red   = (R | R << 8) * color.alpha / 0x10000;
       
  2958     color.green = (G | G << 8) * color.alpha / 0x10000;
       
  2959     color.blue  = (B | B << 8) * color.alpha / 0x10000;
       
  2960     return color;
       
  2961 }
       
  2962 Picture QX11Data::getSolidFill(int screen, const QColor &c)
       
  2963 {
       
  2964     if (!X11->use_xrender)
       
  2965         return XNone;
       
  2966 
       
  2967     XRenderColor color = preMultiply(c);
       
  2968     for (int i = 0; i < X11->solid_fill_count; ++i) {
       
  2969         if (X11->solid_fills[i].screen == screen
       
  2970             && X11->solid_fills[i].color.alpha == color.alpha
       
  2971             && X11->solid_fills[i].color.red == color.red
       
  2972             && X11->solid_fills[i].color.green == color.green
       
  2973             && X11->solid_fills[i].color.blue == color.blue)
       
  2974             return X11->solid_fills[i].picture;
       
  2975     }
       
  2976     // none found, replace one
       
  2977     int i = rand() % 16;
       
  2978 
       
  2979     if (X11->solid_fills[i].screen != screen && X11->solid_fills[i].picture) {
       
  2980         XRenderFreePicture (X11->display, X11->solid_fills[i].picture);
       
  2981         X11->solid_fills[i].picture = 0;
       
  2982     }
       
  2983 
       
  2984     if (!X11->solid_fills[i].picture) {
       
  2985         Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 1, 1, 32);
       
  2986         XRenderPictureAttributes attrs;
       
  2987         attrs.repeat = True;
       
  2988         X11->solid_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
       
  2989                                                             XRenderFindStandardFormat(X11->display, PictStandardARGB32),
       
  2990                                                             CPRepeat, &attrs);
       
  2991         XFreePixmap (X11->display, pixmap);
       
  2992     }
       
  2993 
       
  2994     X11->solid_fills[i].color = color;
       
  2995     X11->solid_fills[i].screen = screen;
       
  2996     XRenderFillRectangle (X11->display, PictOpSrc, X11->solid_fills[i].picture, &color, 0, 0, 1, 1);
       
  2997     return X11->solid_fills[i].picture;
       
  2998 }
       
  2999 #endif
       
  3000 
       
  3001 void QWidgetPrivate::setModal_sys()
       
  3002 {
       
  3003 }
       
  3004 
       
  3005 void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &att)
       
  3006 {
       
  3007     QX11InfoData* xd = xinfo->getX11Data(true);
       
  3008     const XWindowAttributes &a = *(att.att);
       
  3009     // find which screen the window is on...
       
  3010     xd->screen = QX11Info::appScreen(); // by default, use the default :)
       
  3011     int i;
       
  3012     for (i = 0; i < ScreenCount(X11->display); i++) {
       
  3013         if (RootWindow(X11->display, i) == a.root) {
       
  3014             xd->screen = i;
       
  3015             break;
       
  3016         }
       
  3017     }
       
  3018 
       
  3019     xd->depth = a.depth;
       
  3020     xd->cells = DisplayCells(X11->display, xd->screen);
       
  3021     xd->visual = a.visual;
       
  3022     xd->defaultVisual = (XVisualIDFromVisual((Visual *) a.visual) ==
       
  3023                          XVisualIDFromVisual((Visual *) QX11Info::appVisual(xinfo->screen())));
       
  3024     xd->colormap = a.colormap;
       
  3025     xd->defaultColormap = (a.colormap == QX11Info::appColormap(xinfo->screen()));
       
  3026     xinfo->setX11Data(xd);
       
  3027 }
       
  3028 
       
  3029 QT_END_NAMESPACE