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