src/gui/kernel/qwidget_win.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qapplication.h"
       
    43 #include "qapplication_p.h"
       
    44 #include "qbitmap.h"
       
    45 #include "qcursor.h"
       
    46 #include "qdesktopwidget.h"
       
    47 #include "qevent.h"
       
    48 #include "qimage.h"
       
    49 #include "qlayout.h"
       
    50 #include "qlibrary.h"
       
    51 #include "qpainter.h"
       
    52 #include "qstack.h"
       
    53 #include "qt_windows.h"
       
    54 #include "qwidget.h"
       
    55 #include "qwidget_p.h"
       
    56 #include "private/qbackingstore_p.h"
       
    57 #include "private/qwindowsurface_raster_p.h"
       
    58 
       
    59 #include "qscrollbar.h"
       
    60 #include "qabstractscrollarea.h"
       
    61 #include <private/qabstractscrollarea_p.h>
       
    62 
       
    63 #include <qdebug.h>
       
    64 
       
    65 #include <private/qapplication_p.h>
       
    66 #include <private/qwininputcontext_p.h>
       
    67 #include <private/qpaintengine_raster_p.h>
       
    68 
       
    69 #if defined(Q_WS_WINCE)
       
    70 #include "qguifunctions_wince.h"
       
    71 QT_USE_NAMESPACE
       
    72 extern void qt_wince_maximize(QWidget *widget);                          //defined in qguifunctions_wince.cpp
       
    73 extern void qt_wince_minimize(HWND hwnd);                                //defined in qguifunctions_wince.cpp
       
    74 extern void qt_wince_full_screen(HWND hwnd, bool fullScreen, UINT swpf); //defined in qguifunctions_wince.cpp
       
    75 extern bool qt_wince_is_mobile();                                        //defined in qguifunctions_wince.cpp
       
    76 #endif
       
    77 
       
    78 typedef BOOL    (WINAPI *PtrSetLayeredWindowAttributes)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
       
    79 static PtrSetLayeredWindowAttributes ptrSetLayeredWindowAttributes = 0;
       
    80 
       
    81 #ifndef QT_NO_DIRECTDRAW
       
    82 #include <ddraw.h>
       
    83 #include <private/qimage_p.h>
       
    84 static IDirectDraw *qt_ddraw_object;
       
    85 static IDirectDrawSurface *qt_ddraw_primary;
       
    86 #endif
       
    87 
       
    88 
       
    89 
       
    90 #if defined(QT_NON_COMMERCIAL)
       
    91 #include "qnc_win.h"
       
    92 #endif
       
    93 
       
    94 #if !defined(WS_EX_TOOLWINDOW)
       
    95 #define WS_EX_TOOLWINDOW 0x00000080
       
    96 #endif
       
    97 
       
    98 #if !defined(GWLP_WNDPROC)
       
    99 #define GWLP_WNDPROC GWL_WNDPROC
       
   100 #endif
       
   101 
       
   102 //#define TABLET_DEBUG
       
   103 #define PACKETDATA  (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE \
       
   104                      | PK_ORIENTATION | PK_CURSOR | PK_Z)
       
   105 #define PACKETMODE  0
       
   106 #include <wintab.h>
       
   107 #include <pktdef.h>
       
   108 
       
   109 QT_BEGIN_NAMESPACE
       
   110 
       
   111 typedef HCTX        (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL);
       
   112 typedef BOOL        (API *PtrWTClose)(HCTX);
       
   113 typedef UINT        (API *PtrWTInfo)(UINT, UINT, LPVOID);
       
   114 typedef BOOL        (API *PtrWTEnable)(HCTX, BOOL);
       
   115 typedef BOOL        (API *PtrWTOverlap)(HCTX, BOOL);
       
   116 typedef int        (API *PtrWTPacketsGet)(HCTX, int, LPVOID);
       
   117 typedef BOOL        (API *PtrWTGet)(HCTX, LPLOGCONTEXT);
       
   118 typedef int     (API *PtrWTQueueSizeGet)(HCTX);
       
   119 typedef BOOL    (API *PtrWTQueueSizeSet)(HCTX, int);
       
   120 
       
   121 static PtrWTOpen ptrWTOpen = 0;
       
   122 static PtrWTClose ptrWTClose = 0;
       
   123 static PtrWTInfo ptrWTInfo = 0;
       
   124 static PtrWTQueueSizeGet ptrWTQueueSizeGet = 0;
       
   125 static PtrWTQueueSizeSet ptrWTQueueSizeSet = 0;
       
   126 static void init_wintab_functions();
       
   127 static void qt_tablet_init();
       
   128 static void qt_tablet_cleanup();
       
   129 extern HCTX qt_tablet_context;
       
   130 extern bool qt_tablet_tilt_support;
       
   131 
       
   132 static QWidget *qt_tablet_widget = 0;
       
   133 QWidget* qt_get_tablet_widget()
       
   134 {
       
   135     return qt_tablet_widget;
       
   136 }
       
   137 
       
   138 extern bool qt_is_gui_used;
       
   139 static void init_wintab_functions()
       
   140 {
       
   141 #if defined(Q_OS_WINCE)
       
   142     return;
       
   143 #else
       
   144     if (!qt_is_gui_used)
       
   145         return;
       
   146     QLibrary library(QLatin1String("wintab32"));
       
   147     ptrWTOpen = (PtrWTOpen)library.resolve("WTOpenW");
       
   148     ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW");
       
   149     ptrWTClose = (PtrWTClose)library.resolve("WTClose");
       
   150     ptrWTQueueSizeGet = (PtrWTQueueSizeGet)library.resolve("WTQueueSizeGet");
       
   151     ptrWTQueueSizeSet = (PtrWTQueueSizeSet)library.resolve("WTQueueSizeSet");
       
   152 #endif // Q_OS_WINCE
       
   153 }
       
   154 
       
   155 static void qt_tablet_init()
       
   156 {
       
   157     static bool firstTime = true;
       
   158     if (!firstTime)
       
   159         return;
       
   160     firstTime = false;
       
   161     qt_tablet_widget = new QWidget(0);
       
   162     qt_tablet_widget->createWinId();
       
   163     qt_tablet_widget->setObjectName(QLatin1String("Qt internal tablet widget"));
       
   164     LOGCONTEXT lcMine;
       
   165     qAddPostRoutine(qt_tablet_cleanup);
       
   166     struct tagAXIS tpOri[3];
       
   167     init_wintab_functions();
       
   168     if (ptrWTInfo && ptrWTOpen && ptrWTQueueSizeGet && ptrWTQueueSizeSet) {
       
   169         // make sure we have WinTab
       
   170         if (!ptrWTInfo(0, 0, NULL)) {
       
   171 #ifdef TABLET_DEBUG
       
   172             qWarning("QWidget: Wintab services not available");
       
   173 #endif
       
   174             return;
       
   175         }
       
   176 
       
   177         // some tablets don't support tilt, check if it is possible,
       
   178         qt_tablet_tilt_support = ptrWTInfo(WTI_DEVICES, DVC_ORIENTATION, &tpOri);
       
   179         if (qt_tablet_tilt_support) {
       
   180             // check for azimuth and altitude
       
   181             qt_tablet_tilt_support = tpOri[0].axResolution && tpOri[1].axResolution;
       
   182         }
       
   183         // build our context from the default context
       
   184         ptrWTInfo(WTI_DEFSYSCTX, 0, &lcMine);
       
   185         // Go for the raw coordinates, the tablet event will return good stuff
       
   186         lcMine.lcOptions |= CXO_MESSAGES | CXO_CSRMESSAGES;
       
   187         lcMine.lcPktData = PACKETDATA;
       
   188         lcMine.lcPktMode = PACKETMODE;
       
   189         lcMine.lcMoveMask = PACKETDATA;
       
   190         lcMine.lcOutOrgX = 0;
       
   191         lcMine.lcOutExtX = lcMine.lcInExtX;
       
   192         lcMine.lcOutOrgY = 0;
       
   193         lcMine.lcOutExtY = -lcMine.lcInExtY;
       
   194         qt_tablet_context = ptrWTOpen(qt_tablet_widget->winId(), &lcMine, true);
       
   195 #ifdef TABLET_DEBUG
       
   196         qDebug("Tablet is %p", qt_tablet_context);
       
   197 #endif
       
   198         if (!qt_tablet_context) {
       
   199 #ifdef TABLET_DEBUG
       
   200             qWarning("QWidget: Failed to open the tablet");
       
   201 #endif
       
   202             return;
       
   203         }
       
   204         // Set the size of the Packet Queue to the correct size...
       
   205         int currSize = ptrWTQueueSizeGet(qt_tablet_context);
       
   206         if (!ptrWTQueueSizeSet(qt_tablet_context, QT_TABLET_NPACKETQSIZE)) {
       
   207             // Ideally one might want to use a smaller
       
   208             // multiple, but for now, since we managed to destroy
       
   209             // the existing Q with the previous call, set it back
       
   210             // to the other size, which should work.  If not,
       
   211             // there will be trouble.
       
   212             if (!ptrWTQueueSizeSet(qt_tablet_context, currSize)) {
       
   213                 Q_ASSERT_X(0, "Qt::Internal", "There is no packet queue for"
       
   214                          " the tablet. The tablet will not work");
       
   215             }
       
   216         }
       
   217     }
       
   218 }
       
   219 
       
   220 static void qt_tablet_cleanup()
       
   221 {
       
   222     if (ptrWTClose)
       
   223         ptrWTClose(qt_tablet_context);
       
   224     delete qt_tablet_widget;
       
   225     qt_tablet_widget = 0;
       
   226 }
       
   227 
       
   228 const QString qt_reg_winclass(QWidget *w);                // defined in qapplication_win.cpp
       
   229 
       
   230 #ifndef QT_NO_DRAGANDDROP
       
   231 void            qt_olednd_unregister(QWidget* widget, QOleDropTarget *dst); // dnd_win
       
   232 QOleDropTarget* qt_olednd_register(QWidget* widget);
       
   233 #endif
       
   234 
       
   235 extern bool qt_nograb();
       
   236 extern HRGN qt_win_bitmapToRegion(const QBitmap& bitmap);
       
   237 
       
   238 static QWidget *mouseGrb    = 0;
       
   239 static QCursor *mouseGrbCur = 0;
       
   240 static QWidget *keyboardGrb = 0;
       
   241 static HHOOK   journalRec  = 0;
       
   242 
       
   243 extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
       
   244 
       
   245 #define XCOORD_MAX 16383
       
   246 #define WRECT_MAX 16383
       
   247 
       
   248 /*****************************************************************************
       
   249   QWidget member functions
       
   250  *****************************************************************************/
       
   251 
       
   252 #ifndef Q_WS_WINCE
       
   253 void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
       
   254 {
       
   255     Q_Q(QWidget);
       
   256     static int sw = -1, sh = -1;
       
   257 
       
   258     Qt::WindowType type = q->windowType();
       
   259     Qt::WindowFlags flags = data.window_flags;
       
   260 
       
   261     bool topLevel = (flags & Qt::Window);
       
   262     bool popup = (type == Qt::Popup);
       
   263     bool dialog = (type == Qt::Dialog
       
   264                    || type == Qt::Sheet
       
   265                    || (flags & Qt::MSWindowsFixedSizeDialogHint));
       
   266     bool desktop = (type == Qt::Desktop);
       
   267     bool tool = (type == Qt::Tool || type == Qt::Drawer);
       
   268 
       
   269     HINSTANCE appinst  = qWinAppInst();
       
   270     HWND parentw, destroyw = 0;
       
   271     WId id = 0;
       
   272 
       
   273     QString windowClassName = qt_reg_winclass(q);
       
   274 
       
   275     if (!window)                                // always initialize
       
   276         initializeWindow = true;
       
   277 
       
   278     if (popup)
       
   279         flags |= Qt::WindowStaysOnTopHint; // a popup stays on top
       
   280 
       
   281     if (sw < 0) {                                // get the (primary) screen size
       
   282         sw = GetSystemMetrics(SM_CXSCREEN);
       
   283         sh = GetSystemMetrics(SM_CYSCREEN);
       
   284     }
       
   285 
       
   286     if (desktop && !q->testAttribute(Qt::WA_DontShowOnScreen)) {                                // desktop widget
       
   287         popup = false;                                // force this flags off
       
   288         data.crect.setRect(GetSystemMetrics(76 /* SM_XVIRTUALSCREEN  */), GetSystemMetrics(77 /* SM_YVIRTUALSCREEN  */),
       
   289                            GetSystemMetrics(78 /* SM_CXVIRTUALSCREEN */), GetSystemMetrics(79 /* SM_CYVIRTUALSCREEN */));
       
   290     }
       
   291 
       
   292     parentw = q->parentWidget() ? q->parentWidget()->effectiveWinId() : 0;
       
   293 
       
   294     QString title;
       
   295     int style = WS_CHILD;
       
   296     int exsty = 0;
       
   297 
       
   298     if (window) {
       
   299         style = GetWindowLong(window, GWL_STYLE);
       
   300         if (!style)
       
   301             qErrnoWarning("QWidget::create: GetWindowLong failed");
       
   302         topLevel = false; // #### needed for some IE plugins??
       
   303     } else if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
       
   304         style = WS_POPUP;
       
   305     } else if (topLevel && !desktop) {
       
   306         if (flags & Qt::FramelessWindowHint)
       
   307             style = WS_POPUP;                // no border
       
   308         else if (flags & Qt::WindowTitleHint)
       
   309             style = WS_OVERLAPPED;
       
   310         else
       
   311             style = 0;
       
   312     }
       
   313     if (!desktop) {
       
   314         // if (!testAttribute(Qt::WA_PaintUnclipped))
       
   315         // ### Commented out for now as it causes some problems, but
       
   316         // this should be correct anyway, so dig some more into this
       
   317 #ifndef Q_FLATTEN_EXPOSE
       
   318         style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
       
   319 #endif
       
   320         if (topLevel) {
       
   321             if ((type == Qt::Window || dialog || tool)) {
       
   322                 if (!(flags & Qt::FramelessWindowHint)) {
       
   323                     if (!(flags & Qt::MSWindowsFixedSizeDialogHint)) {
       
   324                         style |= WS_THICKFRAME;
       
   325                         if(!(flags &
       
   326                             ( Qt::WindowSystemMenuHint
       
   327                             | Qt::WindowTitleHint
       
   328                             | Qt::WindowMinMaxButtonsHint
       
   329                             | Qt::WindowCloseButtonHint
       
   330                             | Qt::WindowContextHelpButtonHint)))
       
   331                             style |= WS_POPUP;
       
   332                     } else {
       
   333                         style |= WS_POPUP | WS_DLGFRAME;
       
   334                     }
       
   335                 }
       
   336                 if (flags & Qt::WindowTitleHint)
       
   337                     style |= WS_CAPTION;
       
   338                 if (flags & Qt::WindowSystemMenuHint)
       
   339                     style |= WS_SYSMENU;
       
   340                 if (flags & Qt::WindowMinimizeButtonHint)
       
   341                     style |= WS_MINIMIZEBOX;
       
   342                 if (shouldShowMaximizeButton())
       
   343                     style |= WS_MAXIMIZEBOX;
       
   344                 if (tool)
       
   345                     exsty |= WS_EX_TOOLWINDOW;
       
   346                 if (flags & Qt::WindowContextHelpButtonHint)
       
   347                     exsty |= WS_EX_CONTEXTHELP;
       
   348             } else {
       
   349                  exsty |= WS_EX_TOOLWINDOW;
       
   350             }
       
   351         }
       
   352     }
       
   353 
       
   354     if (flags & Qt::WindowTitleHint) {
       
   355         title = q->isWindow() ? qAppName() : q->objectName();
       
   356     }
       
   357 
       
   358     // The Qt::WA_WState_Created flag is checked by translateConfigEvent() in
       
   359     // qapplication_win.cpp. We switch it off temporarily to avoid move
       
   360     // and resize events during creationt
       
   361     q->setAttribute(Qt::WA_WState_Created, false);
       
   362 
       
   363     if (window) {                                // override the old window
       
   364         if (destroyOldWindow)
       
   365             destroyw = data.winid;
       
   366         id = window;
       
   367         setWinId(window);
       
   368         LONG res = SetWindowLong(window, GWL_STYLE, style);
       
   369         if (!res)
       
   370             qErrnoWarning("QWidget::create: Failed to set window style");
       
   371 #ifdef _WIN64
       
   372         res = SetWindowLongPtr( window, GWLP_WNDPROC, (LONG_PTR)QtWndProc );
       
   373 #else
       
   374         res = SetWindowLong( window, GWL_WNDPROC, (LONG)QtWndProc );
       
   375 #endif
       
   376         if (!res)
       
   377             qErrnoWarning("QWidget::create: Failed to set window procedure");
       
   378     } else if (desktop) {                        // desktop widget
       
   379         id = GetDesktopWindow();
       
   380 //         QWidget *otherDesktop = QWidget::find(id);        // is there another desktop?
       
   381 //         if (otherDesktop && otherDesktop->testWFlags(Qt::WPaintDesktop)) {
       
   382 //             otherDesktop->d_func()->setWinId(0);        // remove id from widget mapper
       
   383 //             d->setWinId(id);                     // make sure otherDesktop is
       
   384 //             otherDesktop->d_func()->setWinId(id);       //   found first
       
   385 //         } else {
       
   386             setWinId(id);
       
   387 //         }
       
   388     } else if (topLevel) {                       // create top-level widget
       
   389         if (popup)
       
   390             parentw = 0;
       
   391 
       
   392         const bool wasMoved = q->testAttribute(Qt::WA_Moved);
       
   393         int x = wasMoved ? data.crect.left() : CW_USEDEFAULT;
       
   394         int y = wasMoved ? data.crect.top() : CW_USEDEFAULT;
       
   395         int w = CW_USEDEFAULT;
       
   396         int h = CW_USEDEFAULT;
       
   397 
       
   398         // Adjust for framestrut when needed
       
   399         RECT rect = {0,0,0,0};
       
   400         bool isVisibleOnScreen = !q->testAttribute(Qt::WA_DontShowOnScreen);
       
   401         if (isVisibleOnScreen && AdjustWindowRectEx(&rect, style & ~WS_OVERLAPPED, FALSE, exsty)) {
       
   402             QTLWExtra *td = maybeTopData();
       
   403             if (wasMoved && (td && !td->posFromMove)) {
       
   404                 x = data.crect.x() + rect.left;
       
   405                 y = data.crect.y() + rect.top;
       
   406             }
       
   407 
       
   408             if (q->testAttribute(Qt::WA_Resized)) {
       
   409                 w = data.crect.width() + (rect.right - rect.left);
       
   410                 h = data.crect.height() + (rect.bottom - rect.top);
       
   411             }
       
   412         }
       
   413         //update position & initial size of POPUP window
       
   414         if (isVisibleOnScreen && topLevel && initializeWindow && (style & WS_POPUP)) {
       
   415             if (!q->testAttribute(Qt::WA_Resized)) {
       
   416                 w = sw/2;
       
   417                 h = 4*sh/10;
       
   418             }
       
   419             if (!wasMoved) {
       
   420                 x = sw/2 - w/2;
       
   421                 y = sh/2 - h/2;
       
   422             }
       
   423         }
       
   424 
       
   425         id = CreateWindowEx(exsty, reinterpret_cast<const wchar_t *>(windowClassName.utf16()),
       
   426                             reinterpret_cast<const wchar_t *>(title.utf16()), style,
       
   427                             x, y, w, h,
       
   428                             parentw, NULL, appinst, NULL);
       
   429         if (!id)
       
   430             qErrnoWarning("QWidget::create: Failed to create window");
       
   431         setWinId(id);
       
   432         if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) {
       
   433             SetWindowPos(id, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
       
   434             if (flags & Qt::WindowStaysOnBottomHint)
       
   435                 qWarning() << "QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time";
       
   436         } else if (flags & Qt::WindowStaysOnBottomHint)
       
   437             SetWindowPos(id, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
       
   438         winUpdateIsOpaque();
       
   439     } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create child widget
       
   440         id = CreateWindowEx(exsty, reinterpret_cast<const wchar_t *>(windowClassName.utf16()),
       
   441                             reinterpret_cast<const wchar_t *>(title.utf16()), style,
       
   442                             data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(),
       
   443                             parentw, NULL, appinst, NULL);
       
   444         if (!id)
       
   445             qErrnoWarning("QWidget::create: Failed to create window");
       
   446         SetWindowPos(id, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
       
   447         setWinId(id);
       
   448     }
       
   449 
       
   450     if (desktop) {
       
   451         q->setAttribute(Qt::WA_WState_Visible);
       
   452     } else if (topLevel && !q->testAttribute(Qt::WA_DontShowOnScreen)) {
       
   453         RECT  cr;
       
   454         GetClientRect(id, &cr);
       
   455         // one cannot trust cr.left and cr.top, use a correction POINT instead
       
   456         POINT pt;
       
   457         pt.x = 0;
       
   458         pt.y = 0;
       
   459         ClientToScreen(id, &pt);
       
   460 
       
   461         if (data.crect.width() == 0 || data.crect.height() == 0) {
       
   462             data.crect = QRect(pt.x, pt.y, data.crect.width(), data.crect.height());
       
   463         } else {
       
   464             data.crect = QRect(QPoint(pt.x, pt.y),
       
   465                                QPoint(pt.x + cr.right - 1, pt.y + cr.bottom - 1));
       
   466         }
       
   467 
       
   468         if (data.fstrut_dirty) {
       
   469             // be nice to activeqt
       
   470             updateFrameStrut();
       
   471         }
       
   472     }
       
   473 
       
   474     if (topLevel) {
       
   475         if (data.window_flags & Qt::CustomizeWindowHint
       
   476             && data.window_flags & Qt::WindowTitleHint) {
       
   477             HMENU systemMenu = GetSystemMenu((HWND)q->internalWinId(), FALSE);
       
   478             if (data.window_flags & Qt::WindowCloseButtonHint)
       
   479                 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
       
   480             else
       
   481                 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
       
   482         }
       
   483     }
       
   484 
       
   485     q->setAttribute(Qt::WA_WState_Created);                // accept move/resize events
       
   486     hd = 0;                                        // no display context
       
   487 
       
   488     if (q->testAttribute(Qt::WA_AcceptTouchEvents))
       
   489         registerTouchWindow();
       
   490 
       
   491     if (window) {                                // got window from outside
       
   492         if (IsWindowVisible(window))
       
   493             q->setAttribute(Qt::WA_WState_Visible);
       
   494         else
       
   495             q->setAttribute(Qt::WA_WState_Visible, false);
       
   496     }
       
   497 
       
   498     if (extra && !extra->mask.isEmpty())
       
   499         setMask_sys(extra->mask);
       
   500 
       
   501 #if defined(QT_NON_COMMERCIAL)
       
   502     QT_NC_WIDGET_CREATE
       
   503 #endif
       
   504 
       
   505     if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled))
       
   506         q->inputContext()->setFocusWidget(q);
       
   507 
       
   508     if (destroyw) {
       
   509         DestroyWindow(destroyw);
       
   510     }
       
   511 
       
   512     if (q != qt_tablet_widget && QWidgetPrivate::mapper)
       
   513         qt_tablet_init();
       
   514 
       
   515     if (q->testAttribute(Qt::WA_DropSiteRegistered))
       
   516         registerDropSite(true);
       
   517 
       
   518     if (maybeTopData() && maybeTopData()->opacity != 255)
       
   519         q->setWindowOpacity(maybeTopData()->opacity/255.);
       
   520 
       
   521     if (topLevel && (data.crect.width() == 0 || data.crect.height() == 0)) {
       
   522         q->setAttribute(Qt::WA_OutsideWSRange, true);
       
   523     }
       
   524 
       
   525     if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) {
       
   526         Q_ASSERT(q->internalWinId());
       
   527         ShowWindow(q->internalWinId(), SW_SHOW);
       
   528     }
       
   529 }
       
   530 
       
   531 #endif //Q_WS_WINCE
       
   532 
       
   533 
       
   534 void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
       
   535 {
       
   536     Q_D(QWidget);
       
   537     if (!isWindow() && parentWidget())
       
   538         parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
       
   539     d->deactivateWidgetCleanup();
       
   540     if (testAttribute(Qt::WA_WState_Created)) {
       
   541         setAttribute(Qt::WA_WState_Created, false);
       
   542         for(int i = 0; i < d->children.size(); ++i) { // destroy all widget children
       
   543             register QObject *obj = d->children.at(i);
       
   544             if (obj->isWidgetType())
       
   545                 ((QWidget*)obj)->destroy(destroySubWindows,
       
   546                                          destroySubWindows);
       
   547         }
       
   548         if (mouseGrb == this)
       
   549             releaseMouse();
       
   550         if (keyboardGrb == this)
       
   551             releaseKeyboard();
       
   552         if (testAttribute(Qt::WA_ShowModal))                // just be sure we leave modal
       
   553             QApplicationPrivate::leaveModal(this);
       
   554         else if ((windowType() == Qt::Popup))
       
   555             qApp->d_func()->closePopup(this);
       
   556         if (destroyWindow && !(windowType() == Qt::Desktop) && internalWinId()) {
       
   557             DestroyWindow(internalWinId());
       
   558         }
       
   559 #ifdef Q_WS_WINCE
       
   560         if (destroyWindow && (windowType() == Qt::Desktop) && !GetDesktopWindow()) {
       
   561             DestroyWindow(internalWinId());
       
   562         }
       
   563 
       
   564 #endif
       
   565         QT_TRY {
       
   566             d->setWinId(0);
       
   567         } QT_CATCH (const std::bad_alloc &) {
       
   568             // swallow - destructors must not throw
       
   569         }
       
   570     }
       
   571 }
       
   572 
       
   573 void QWidgetPrivate::reparentChildren()
       
   574 {
       
   575     Q_Q(QWidget);
       
   576     QObjectList chlist = q->children();
       
   577     for(int i = 0; i < chlist.size(); ++i) { // reparent children
       
   578         QObject *obj = chlist.at(i);
       
   579         if (obj->isWidgetType()) {
       
   580             QWidget *w = (QWidget *)obj;
       
   581             if ((w->windowType() == Qt::Popup)) {
       
   582                 ;
       
   583             } else if (w->isWindow()) {
       
   584                 bool showIt = w->isVisible();
       
   585                 QPoint old_pos = w->pos();
       
   586                 w->setParent(q, w->windowFlags());
       
   587                 w->move(old_pos);
       
   588                 if (showIt)
       
   589                     w->show();
       
   590             } else {
       
   591                 w->d_func()->invalidateBuffer(w->rect());
       
   592                 SetParent(w->effectiveWinId(), q->effectiveWinId());
       
   593                 w->d_func()->reparentChildren();
       
   594             }
       
   595         }
       
   596     }
       
   597 }
       
   598 
       
   599 void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
       
   600 {
       
   601     Q_Q(QWidget);
       
   602     bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
       
   603     if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
       
   604         q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
       
   605 
       
   606     WId old_winid = data.winid;
       
   607     // hide and reparent our own window away. Otherwise we might get
       
   608     // destroyed when emitting the child remove event below. See QWorkspace.
       
   609     if (q->isVisible() && data.winid) {
       
   610         ShowWindow(data.winid, SW_HIDE);
       
   611         SetParent(data.winid, 0);
       
   612     }
       
   613     bool dropSiteWasRegistered = false;
       
   614     if (q->testAttribute(Qt::WA_DropSiteRegistered)) {
       
   615         dropSiteWasRegistered = true;
       
   616         q->setAttribute(Qt::WA_DropSiteRegistered, false); // ole dnd unregister (we will register again below)
       
   617     }
       
   618 
       
   619     if ((q->windowType() == Qt::Desktop))
       
   620         old_winid = 0;
       
   621     setWinId(0);
       
   622 
       
   623     QObjectPrivate::setParent_helper(parent);
       
   624     bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide);
       
   625 
       
   626     data.window_flags = f;
       
   627     data.fstrut_dirty = true;
       
   628     q->setAttribute(Qt::WA_WState_Created, false);
       
   629     q->setAttribute(Qt::WA_WState_Visible, false);
       
   630     q->setAttribute(Qt::WA_WState_Hidden, false);
       
   631     adjustFlags(data.window_flags, q);
       
   632     // keep compatibility with previous versions, we need to preserve the created state
       
   633     // (but we recreate the winId for the widget being reparented, again for compatibility)
       
   634     if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created)))
       
   635         createWinId();
       
   636     if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
       
   637         q->setAttribute(Qt::WA_WState_Hidden);
       
   638     q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
       
   639 
       
   640     if (wasCreated) {
       
   641         reparentChildren();
       
   642     }
       
   643 
       
   644     if (extra && !extra->mask.isEmpty()) {
       
   645         QRegion r = extra->mask;
       
   646         extra->mask = QRegion();
       
   647         q->setMask(r);
       
   648     }
       
   649     if (extra && extra->topextra && !extra->topextra->caption.isEmpty()) {
       
   650         setWindowIcon_sys(true);
       
   651         setWindowTitle_helper(extra->topextra->caption);
       
   652     }
       
   653     if (old_winid)
       
   654         DestroyWindow(old_winid);
       
   655 
       
   656     if (q->testAttribute(Qt::WA_AcceptDrops) || dropSiteWasRegistered
       
   657         || (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered)))
       
   658         q->setAttribute(Qt::WA_DropSiteRegistered, true);
       
   659 
       
   660 #ifdef Q_WS_WINCE
       
   661     // Show borderless toplevel windows in tasklist & NavBar
       
   662     if (!parent) {
       
   663         QString txt = q->windowTitle().isEmpty()?qAppName():q->windowTitle();
       
   664         SetWindowText(q->internalWinId(), (wchar_t*)txt.utf16());
       
   665     }
       
   666 #endif
       
   667     invalidateBuffer(q->rect());
       
   668 }
       
   669 
       
   670 
       
   671 QPoint QWidget::mapToGlobal(const QPoint &pos) const
       
   672 {
       
   673     Q_D(const QWidget);
       
   674     QWidget *parentWindow = window();
       
   675     QWExtra *extra = parentWindow->d_func()->extra;
       
   676     if (!isVisible() || parentWindow->isMinimized() || !testAttribute(Qt::WA_WState_Created) || !internalWinId()
       
   677         || (extra && extra->proxyWidget)) {
       
   678         if (extra && extra->topextra && extra->topextra->embedded) {
       
   679             QPoint pt = mapTo(parentWindow, pos);
       
   680             POINT p = {pt.x(), pt.y()};
       
   681             ClientToScreen(parentWindow->effectiveWinId(), &p);
       
   682             return QPoint(p.x, p.y);
       
   683         } else {
       
   684             QPoint toGlobal = mapTo(parentWindow, pos) + parentWindow->pos();
       
   685             // Adjust for window decorations
       
   686             toGlobal += parentWindow->geometry().topLeft() - parentWindow->frameGeometry().topLeft();
       
   687             return toGlobal;
       
   688         }
       
   689     }
       
   690     POINT p;
       
   691     QPoint tmp = d->mapToWS(pos);
       
   692     p.x = tmp.x();
       
   693     p.y = tmp.y();
       
   694     ClientToScreen(internalWinId(), &p);
       
   695     return QPoint(p.x, p.y);
       
   696 }
       
   697 
       
   698 QPoint QWidget::mapFromGlobal(const QPoint &pos) const
       
   699 {
       
   700     Q_D(const QWidget);
       
   701     QWidget *parentWindow = window();
       
   702     QWExtra *extra = parentWindow->d_func()->extra;
       
   703     if (!isVisible() || parentWindow->isMinimized() || !testAttribute(Qt::WA_WState_Created) || !internalWinId()
       
   704         || (extra && extra->proxyWidget)) {
       
   705         if (extra && extra->topextra && extra->topextra->embedded) {
       
   706             POINT p = {pos.x(), pos.y()};
       
   707             ScreenToClient(parentWindow->effectiveWinId(), &p);
       
   708             return mapFrom(parentWindow, QPoint(p.x, p.y));
       
   709         } else {
       
   710             QPoint fromGlobal = mapFrom(parentWindow, pos - parentWindow->pos());
       
   711             // Adjust for window decorations
       
   712             fromGlobal -= parentWindow->geometry().topLeft() - parentWindow->frameGeometry().topLeft();
       
   713             return fromGlobal;
       
   714         }
       
   715     }
       
   716     POINT p;
       
   717     p.x = pos.x();
       
   718     p.y = pos.y();
       
   719     ScreenToClient(internalWinId(), &p);
       
   720     return d->mapFromWS(QPoint(p.x, p.y));
       
   721 }
       
   722 
       
   723 void QWidgetPrivate::updateSystemBackground() {}
       
   724 
       
   725 #ifndef QT_NO_CURSOR
       
   726 void QWidgetPrivate::setCursor_sys(const QCursor &cursor)
       
   727 {
       
   728     Q_UNUSED(cursor);
       
   729     Q_Q(QWidget);
       
   730     qt_win_set_cursor(q, false);
       
   731 }
       
   732 
       
   733 void QWidgetPrivate::unsetCursor_sys()
       
   734 {
       
   735     Q_Q(QWidget);
       
   736     qt_win_set_cursor(q, false);
       
   737 }
       
   738 #endif
       
   739 
       
   740 void QWidgetPrivate::setWindowTitle_sys(const QString &caption)
       
   741 {
       
   742     Q_Q(QWidget);
       
   743     if (!q->isWindow())
       
   744         return;
       
   745 
       
   746     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   747     SetWindowText(q->internalWinId(), (wchar_t*)caption.utf16());
       
   748 }
       
   749 
       
   750 HICON qt_createIcon(QIcon icon, int xSize, int ySize, QPixmap **cache)
       
   751 {
       
   752     HICON result = 0;
       
   753     if (!icon.isNull()) { // valid icon
       
   754         QSize size = icon.actualSize(QSize(xSize, ySize));
       
   755         QPixmap pm = icon.pixmap(size);
       
   756         if (pm.isNull())
       
   757             return 0;
       
   758 
       
   759         result = pm.toWinHICON();
       
   760 
       
   761         if (cache) {
       
   762             delete *cache;
       
   763             *cache = new QPixmap(pm);;
       
   764         }
       
   765     }
       
   766     return result;
       
   767 }
       
   768 
       
   769 void QWidgetPrivate::setWindowIcon_sys(bool forceReset)
       
   770 {
       
   771     Q_Q(QWidget);
       
   772     if (!q->testAttribute(Qt::WA_WState_Created) || !q->isWindow())
       
   773         return;
       
   774     QTLWExtra* x = topData();
       
   775     if (x->iconPixmap && !forceReset)
       
   776         // already been set
       
   777         return;
       
   778 
       
   779     if (x->winIconBig) {
       
   780         DestroyIcon(x->winIconBig);
       
   781         x->winIconBig = 0;
       
   782     }
       
   783     if (x->winIconSmall) {
       
   784         DestroyIcon(x->winIconSmall);
       
   785         x->winIconSmall = 0;
       
   786     }
       
   787 
       
   788     x->winIconSmall = qt_createIcon(q->windowIcon(),
       
   789                                     GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
       
   790                                     &(x->iconPixmap));
       
   791     x->winIconBig = qt_createIcon(q->windowIcon(),
       
   792                                   GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON),
       
   793                                   &(x->iconPixmap));
       
   794     if (x->winIconBig) {
       
   795         SendMessage(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall);
       
   796         SendMessage(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconBig);
       
   797     } else {
       
   798         SendMessage(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall);
       
   799         SendMessage(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconSmall);
       
   800     }
       
   801 }
       
   802 
       
   803 
       
   804 void QWidgetPrivate::setWindowIconText_sys(const QString &iconText)
       
   805 {
       
   806     Q_UNUSED(iconText);
       
   807 }
       
   808 
       
   809 
       
   810 QCursor *qt_grab_cursor()
       
   811 {
       
   812     return mouseGrbCur;
       
   813 }
       
   814 
       
   815 // The procedure does nothing, but is required for mousegrabbing to work
       
   816 #ifndef Q_WS_WINCE
       
   817 LRESULT CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam)
       
   818 {
       
   819     return CallNextHookEx(journalRec, nCode, wParam, lParam);
       
   820 }
       
   821 #endif //Q_WS_WINCE
       
   822 
       
   823 /* Works only as long as pointer is inside the application's window,
       
   824    which is good enough for QDockWidget.
       
   825 
       
   826    Doesn't call SetWindowsHookEx() - this function causes a system-wide
       
   827    freeze if any other app on the system installs a hook and fails to
       
   828    process events. */
       
   829 void QWidgetPrivate::grabMouseWhileInWindow()
       
   830 {
       
   831     Q_Q(QWidget);
       
   832     if (!qt_nograb()) {
       
   833         if (mouseGrb)
       
   834             mouseGrb->releaseMouse();
       
   835         Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
   836         SetCapture(q->effectiveWinId());
       
   837         mouseGrb = q;
       
   838 #ifndef QT_NO_CURSOR
       
   839         mouseGrbCur = new QCursor(mouseGrb->cursor());
       
   840 #endif
       
   841     }
       
   842 }
       
   843 
       
   844 #ifndef Q_WS_WINCE
       
   845 void QWidget::grabMouse()
       
   846 {
       
   847     if (!qt_nograb()) {
       
   848         if (mouseGrb)
       
   849             mouseGrb->releaseMouse();
       
   850         journalRec = SetWindowsHookEx(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandle(0), 0);
       
   851         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
   852         SetCapture(effectiveWinId());
       
   853         mouseGrb = this;
       
   854         mouseGrbCur = new QCursor(mouseGrb->cursor());
       
   855     }
       
   856 }
       
   857 
       
   858 void QWidget::grabMouse(const QCursor &cursor)
       
   859 {
       
   860     if (!qt_nograb()) {
       
   861         if (mouseGrb)
       
   862             mouseGrb->releaseMouse();
       
   863         journalRec = SetWindowsHookEx(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandle(0), 0);
       
   864         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
   865         SetCapture(effectiveWinId());
       
   866         mouseGrbCur = new QCursor(cursor);
       
   867         SetCursor(mouseGrbCur->handle());
       
   868         mouseGrb = this;
       
   869     }
       
   870 }
       
   871 
       
   872 void QWidget::releaseMouse()
       
   873 {
       
   874     if (!qt_nograb() && mouseGrb == this) {
       
   875         ReleaseCapture();
       
   876         if (journalRec) {
       
   877             UnhookWindowsHookEx(journalRec);
       
   878             journalRec = 0;
       
   879         }
       
   880         if (mouseGrbCur) {
       
   881             delete mouseGrbCur;
       
   882             mouseGrbCur = 0;
       
   883         }
       
   884         mouseGrb = 0;
       
   885     }
       
   886 }
       
   887 #endif
       
   888 
       
   889 void QWidget::grabKeyboard()
       
   890 {
       
   891     if (!qt_nograb()) {
       
   892         if (keyboardGrb)
       
   893             keyboardGrb->releaseKeyboard();
       
   894         keyboardGrb = this;
       
   895     }
       
   896 }
       
   897 
       
   898 void QWidget::releaseKeyboard()
       
   899 {
       
   900     if (!qt_nograb() && keyboardGrb == this)
       
   901         keyboardGrb = 0;
       
   902 }
       
   903 
       
   904 
       
   905 QWidget *QWidget::mouseGrabber()
       
   906 {
       
   907     return mouseGrb;
       
   908 }
       
   909 
       
   910 QWidget *QWidget::keyboardGrabber()
       
   911 {
       
   912     return keyboardGrb;
       
   913 }
       
   914 
       
   915 void QWidget::activateWindow()
       
   916 {
       
   917     window()->createWinId();
       
   918     SetForegroundWindow(window()->internalWinId());
       
   919 }
       
   920 
       
   921 #ifndef Q_WS_WINCE
       
   922 void QWidget::setWindowState(Qt::WindowStates newstate)
       
   923 {
       
   924     Q_D(QWidget);
       
   925     Qt::WindowStates oldstate = windowState();
       
   926     if (oldstate == newstate)
       
   927         return;
       
   928 
       
   929     int max = SW_MAXIMIZE;
       
   930     int min = SW_MINIMIZE;
       
   931 
       
   932     int normal = SW_SHOWNOACTIVATE;
       
   933     if (newstate & Qt::WindowActive) {
       
   934         max = SW_SHOWMAXIMIZED;
       
   935         min = SW_SHOWMINIMIZED;
       
   936         normal = SW_SHOWNORMAL;
       
   937     }
       
   938 
       
   939     if (isWindow()) {
       
   940         createWinId();
       
   941         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
   942 
       
   943         // Ensure the initial size is valid, since we store it as normalGeometry below.
       
   944         if (!testAttribute(Qt::WA_Resized) && !isVisible())
       
   945             adjustSize();
       
   946 
       
   947         if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) {
       
   948             if (newstate & Qt::WindowMaximized && !(oldstate & Qt::WindowFullScreen))
       
   949                 d->topData()->normalGeometry = geometry();
       
   950             if (isVisible() && !(newstate & Qt::WindowMinimized)) {
       
   951                 ShowWindow(internalWinId(), (newstate & Qt::WindowMaximized) ? max : normal);
       
   952                 if (!(newstate & Qt::WindowFullScreen)) {
       
   953                     QRect r = d->topData()->normalGeometry;
       
   954                     if (!(newstate & Qt::WindowMaximized) && r.width() >= 0) {
       
   955                         if (pos() != r.topLeft() || size() !=r.size()) {
       
   956                             d->topData()->normalGeometry = QRect(0,0,-1,-1);
       
   957                             setGeometry(r);
       
   958                         }
       
   959                     }
       
   960                 } else {
       
   961                     d->updateFrameStrut();
       
   962                 }
       
   963             }
       
   964         }
       
   965 
       
   966         if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) {
       
   967             if (newstate & Qt::WindowFullScreen) {
       
   968                 if (d->topData()->normalGeometry.width() < 0 && !(oldstate & Qt::WindowMaximized))
       
   969                     d->topData()->normalGeometry = geometry();
       
   970                 d->topData()->savedFlags = Qt::WindowFlags(GetWindowLong(internalWinId(), GWL_STYLE));
       
   971 #ifndef Q_FLATTEN_EXPOSE
       
   972                 UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP;
       
   973 #else
       
   974                 UINT style = WS_POPUP;
       
   975 #endif
       
   976 		if (ulong(d->topData()->savedFlags) & WS_SYSMENU)
       
   977 		    style |= WS_SYSMENU;
       
   978                 if (isVisible())
       
   979                     style |= WS_VISIBLE;
       
   980                 SetWindowLong(internalWinId(), GWL_STYLE, style);
       
   981                 QRect r = QApplication::desktop()->screenGeometry(this);
       
   982                 UINT swpf = SWP_FRAMECHANGED;
       
   983                 if (newstate & Qt::WindowActive)
       
   984                     swpf |= SWP_NOACTIVATE;
       
   985 
       
   986                 SetWindowPos(internalWinId(), HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf);
       
   987                 d->updateFrameStrut();
       
   988             } else {
       
   989                 UINT style = d->topData()->savedFlags;
       
   990                 if (isVisible())
       
   991                     style |= WS_VISIBLE;
       
   992                 SetWindowLong(internalWinId(), GWL_STYLE, style);
       
   993 
       
   994                 UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE;
       
   995                 if (newstate & Qt::WindowActive)
       
   996                     swpf |= SWP_NOACTIVATE;
       
   997                 SetWindowPos(internalWinId(), 0, 0, 0, 0, 0, swpf);
       
   998                 d->updateFrameStrut();
       
   999 
       
  1000                 // preserve maximized state
       
  1001                 if (isVisible())
       
  1002                     ShowWindow(internalWinId(), (newstate & Qt::WindowMaximized) ? max : normal);
       
  1003 
       
  1004                 if (!(newstate & Qt::WindowMaximized)) {
       
  1005                     QRect r = d->topData()->normalGeometry;
       
  1006                     d->topData()->normalGeometry = QRect(0,0,-1,-1);
       
  1007                     if (r.isValid())
       
  1008                         setGeometry(r);
       
  1009                 }
       
  1010             }
       
  1011         }
       
  1012 
       
  1013         if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) {
       
  1014             if (isVisible())
       
  1015                 ShowWindow(internalWinId(), (newstate & Qt::WindowMinimized) ? min :
       
  1016                                     (newstate & Qt::WindowMaximized) ? max : normal);
       
  1017         }
       
  1018     }
       
  1019     data->window_state = newstate;
       
  1020     QWindowStateChangeEvent e(oldstate);
       
  1021     QApplication::sendEvent(this, &e);
       
  1022 }
       
  1023 #endif //Q_WS_WINCE
       
  1024 
       
  1025 
       
  1026 /*
       
  1027   \internal
       
  1028   Platform-specific part of QWidget::hide().
       
  1029 */
       
  1030 
       
  1031 void QWidgetPrivate::hide_sys()
       
  1032 {
       
  1033     Q_Q(QWidget);
       
  1034     deactivateWidgetCleanup();
       
  1035     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1036 #ifdef Q_WS_WINCE
       
  1037     if (!qt_wince_is_mobile() && q->isFullScreen()) {
       
  1038         HWND handle = FindWindow(L"HHTaskBar", L"");
       
  1039         if (handle) {
       
  1040             ShowWindow(handle, 1);
       
  1041             EnableWindow(handle, true);
       
  1042         }
       
  1043     }
       
  1044 #endif
       
  1045     if (q->windowFlags() != Qt::Desktop) {
       
  1046         if ((q->windowFlags() & Qt::Popup) && q->internalWinId())
       
  1047             ShowWindow(q->internalWinId(), SW_HIDE);
       
  1048         else if (q->internalWinId())
       
  1049             SetWindowPos(q->internalWinId(),0, 0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
       
  1050     }
       
  1051     if (q->isWindow()) {
       
  1052         if (QWidgetBackingStore *bs = maybeBackingStore())
       
  1053             bs->releaseBuffer();
       
  1054     } else {
       
  1055         invalidateBuffer(q->rect());
       
  1056     }
       
  1057     q->setAttribute(Qt::WA_Mapped, false);
       
  1058 }
       
  1059 
       
  1060 
       
  1061 /*
       
  1062   \internal
       
  1063   Platform-specific part of QWidget::show().
       
  1064 */
       
  1065 #ifndef Q_WS_WINCE
       
  1066 void QWidgetPrivate::show_sys()
       
  1067 {
       
  1068     Q_Q(QWidget);
       
  1069 #if defined(QT_NON_COMMERCIAL)
       
  1070     QT_NC_SHOW_WINDOW
       
  1071 #endif
       
  1072     if (q->testAttribute(Qt::WA_OutsideWSRange))
       
  1073         return;
       
  1074     q->setAttribute(Qt::WA_Mapped);
       
  1075     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1076 
       
  1077     if (q->testAttribute(Qt::WA_DontShowOnScreen)) {
       
  1078         invalidateBuffer(q->rect());
       
  1079         return;
       
  1080     }
       
  1081 
       
  1082     int sm = SW_SHOWNORMAL;
       
  1083     bool fakedMaximize = false;
       
  1084     if (q->isWindow()) {
       
  1085         if (q->isMinimized()) {
       
  1086             sm = SW_SHOWMINIMIZED;
       
  1087             if (!IsWindowVisible(q->internalWinId()))
       
  1088                 sm = SW_SHOWMINNOACTIVE;
       
  1089         } else if (q->isMaximized()) {
       
  1090             sm = SW_SHOWMAXIMIZED;
       
  1091             // Windows will not behave correctly when we try to maximize a window which does not
       
  1092             // have minimize nor maximize buttons in the window frame. Windows would then ignore
       
  1093             // non-available geometry, and rather maximize the widget to the full screen, minus the
       
  1094             // window frame (caption). So, we do a trick here, by adding a maximize button before
       
  1095             // maximizing the widget, and then remove the maximize button afterwards.
       
  1096             Qt::WindowFlags &flags = data.window_flags;
       
  1097             if (flags & Qt::WindowTitleHint &&
       
  1098                 !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) {
       
  1099                 fakedMaximize = TRUE;
       
  1100                 int style = GetWindowLong(q->internalWinId(), GWL_STYLE);
       
  1101                 SetWindowLong(q->internalWinId(), GWL_STYLE, style | WS_MAXIMIZEBOX);
       
  1102             }
       
  1103         }
       
  1104     }
       
  1105     if (q->testAttribute(Qt::WA_ShowWithoutActivating)
       
  1106         || (q->windowType() == Qt::Popup)
       
  1107         || (q->windowType() == Qt::ToolTip)
       
  1108         || (q->windowType() == Qt::Tool)) {
       
  1109         sm = SW_SHOWNOACTIVATE;
       
  1110     }
       
  1111 
       
  1112 
       
  1113     if (q->internalWinId())
       
  1114         ShowWindow(q->internalWinId(), sm);
       
  1115 
       
  1116     if (fakedMaximize) {
       
  1117         int style = GetWindowLong(q->internalWinId(), GWL_STYLE);
       
  1118         SetWindowLong(q->internalWinId(), GWL_STYLE, style & ~WS_MAXIMIZEBOX);
       
  1119         SetWindowPos(q->internalWinId(), 0, 0, 0, 0, 0,
       
  1120                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER
       
  1121                      | SWP_FRAMECHANGED);
       
  1122     }
       
  1123 
       
  1124     if (q->internalWinId()) {
       
  1125         if (IsIconic(q->internalWinId()))
       
  1126             data.window_state |= Qt::WindowMinimized;
       
  1127         if (IsZoomed(q->internalWinId()))
       
  1128             data.window_state |= Qt::WindowMaximized;
       
  1129     }
       
  1130 
       
  1131     winSetupGestures();
       
  1132 
       
  1133     invalidateBuffer(q->rect());
       
  1134 }
       
  1135 #endif //Q_WS_WINCE
       
  1136 
       
  1137 void QWidgetPrivate::setFocus_sys()
       
  1138 {
       
  1139     Q_Q(QWidget);
       
  1140     if (q->testAttribute(Qt::WA_WState_Created) && q->window()->windowType() != Qt::Popup)
       
  1141         SetFocus(q->effectiveWinId());
       
  1142 }
       
  1143 
       
  1144 void QWidgetPrivate::raise_sys()
       
  1145 {
       
  1146     Q_Q(QWidget);
       
  1147     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1148     if (q->internalWinId())
       
  1149         SetWindowPos(q->internalWinId(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
       
  1150 }
       
  1151 
       
  1152 void QWidgetPrivate::lower_sys()
       
  1153 {
       
  1154     Q_Q(QWidget);
       
  1155     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1156     if (q->internalWinId())
       
  1157         SetWindowPos(q->internalWinId(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
       
  1158     invalidateBuffer(q->rect());
       
  1159 }
       
  1160 
       
  1161 void QWidgetPrivate::stackUnder_sys(QWidget* w)
       
  1162 {
       
  1163     Q_Q(QWidget);
       
  1164     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1165     if (q->internalWinId() && w->internalWinId())
       
  1166         SetWindowPos(q->internalWinId(), w->internalWinId() , 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
       
  1167     invalidateBuffer(q->rect());
       
  1168 }
       
  1169 
       
  1170 
       
  1171 /*
       
  1172   Helper function for non-toplevel widgets. Helps to map Qt's 32bit
       
  1173   coordinate system to Windpws's 16bit coordinate system.
       
  1174 
       
  1175   This code is duplicated from the X11 code, so any changes there
       
  1176   should also (most likely) be reflected here.
       
  1177 
       
  1178   (In all comments below: s/X/Windows/g)
       
  1179  */
       
  1180 
       
  1181 void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &)
       
  1182 {
       
  1183     Q_Q(QWidget);
       
  1184     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1185 
       
  1186     /*
       
  1187       There are up to four different coordinate systems here:
       
  1188       Qt coordinate system for this widget.
       
  1189       X coordinate system for this widget (relative to wrect).
       
  1190       Qt coordinate system for parent
       
  1191       X coordinate system for parent (relative to parent's wrect).
       
  1192      */
       
  1193     QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX);
       
  1194     QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX);
       
  1195     QRect wrect;
       
  1196     //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)
       
  1197     QRect xrect = data.crect;
       
  1198 
       
  1199     const QWidget *const parent = q->parentWidget();
       
  1200     QRect parentWRect = parent->data->wrect;
       
  1201 
       
  1202     if (parentWRect.isValid()) {
       
  1203         // parent is clipped, and we have to clip to the same limit as parent
       
  1204         if (!parentWRect.contains(xrect)) {
       
  1205             xrect &= parentWRect;
       
  1206             wrect = xrect;
       
  1207             //translate from parent's to my Qt coord sys
       
  1208             wrect.translate(-data.crect.topLeft());
       
  1209         }
       
  1210         //translate from parent's Qt coords to parent's X coords
       
  1211         xrect.translate(-parentWRect.topLeft());
       
  1212 
       
  1213     } else {
       
  1214         // parent is not clipped, we may or may not have to clip
       
  1215 
       
  1216         if (data.wrect.isValid() && QRect(QPoint(),data.crect.size()).contains(data.wrect)) {
       
  1217             // This is where the main optimization is: we are already
       
  1218             // clipped, and if our clip is still valid, we can just
       
  1219             // move our window, and do not need to move or clip
       
  1220             // children
       
  1221 
       
  1222             QRect vrect = xrect & parent->rect();
       
  1223             vrect.translate(-data.crect.topLeft()); //the part of me that's visible through parent, in my Qt coords
       
  1224             if (data.wrect.contains(vrect)) {
       
  1225                 xrect = data.wrect;
       
  1226                 xrect.translate(data.crect.topLeft());
       
  1227                 if (q->internalWinId())
       
  1228                     MoveWindow(q->internalWinId(), xrect.x(), xrect.y(), xrect.width(), xrect.height(), true);
       
  1229                 return;
       
  1230             }
       
  1231         }
       
  1232 
       
  1233         if (!validRange.contains(xrect)) {
       
  1234             // we are too big, and must clip
       
  1235             xrect &=wrectRange;
       
  1236             wrect = xrect;
       
  1237             wrect.translate(-data.crect.topLeft());
       
  1238             //parent's X coord system is equal to parent's Qt coord
       
  1239             //sys, so we don't need to map xrect.
       
  1240         }
       
  1241 
       
  1242     }
       
  1243 
       
  1244 
       
  1245     // unmap if we are outside the valid window system coord system
       
  1246     bool outsideRange = !xrect.isValid();
       
  1247     bool mapWindow = false;
       
  1248     if (q->testAttribute(Qt::WA_OutsideWSRange) != outsideRange) {
       
  1249         q->setAttribute(Qt::WA_OutsideWSRange, outsideRange);
       
  1250         if (outsideRange) {
       
  1251             if (q->internalWinId())
       
  1252                 ShowWindow(q->internalWinId(), SW_HIDE);
       
  1253             q->setAttribute(Qt::WA_Mapped, false);
       
  1254         } else if (!q->isHidden()) {
       
  1255             mapWindow = true;
       
  1256         }
       
  1257     }
       
  1258 
       
  1259     if (outsideRange)
       
  1260         return;
       
  1261 
       
  1262     bool jump = (data.wrect != wrect);
       
  1263     data.wrect = wrect;
       
  1264 
       
  1265     // and now recursively for all children...
       
  1266     for (int i = 0; i < children.size(); ++i) {
       
  1267         QObject *object = children.at(i);
       
  1268         if (object->isWidgetType()) {
       
  1269             QWidget *w = static_cast<QWidget *>(object);
       
  1270             if (!w->isWindow() && w->testAttribute(Qt::WA_WState_Created))
       
  1271                 w->d_func()->setWSGeometry();
       
  1272         }
       
  1273     }
       
  1274 
       
  1275     // move ourselves to the new position and map (if necessary) after
       
  1276     // the movement. Rationale: moving unmapped windows is much faster
       
  1277     // than moving mapped windows
       
  1278     if (q->internalWinId()) {
       
  1279         if (!parent->internalWinId())
       
  1280             xrect.translate(parent->mapTo(q->nativeParentWidget(), QPoint(0, 0)));
       
  1281         MoveWindow(q->internalWinId(), xrect.x(), xrect.y(), xrect.width(), xrect.height(), !jump);
       
  1282     }
       
  1283     if (mapWindow && !dontShow) {
       
  1284         q->setAttribute(Qt::WA_Mapped);
       
  1285         if (q->internalWinId())
       
  1286             ShowWindow(q->internalWinId(), SW_SHOWNOACTIVATE);
       
  1287     }
       
  1288 
       
  1289     if (jump && q->internalWinId())
       
  1290         InvalidateRect(q->internalWinId(), 0, false);
       
  1291 
       
  1292 }
       
  1293 
       
  1294 //
       
  1295 // The internal qWinRequestConfig, defined in qapplication_win.cpp, stores move,
       
  1296 // resize and setGeometry requests for a widget that is already
       
  1297 // processing a config event. The purpose is to avoid recursion.
       
  1298 //
       
  1299 void qWinRequestConfig(WId, int, int, int, int, int);
       
  1300 
       
  1301 void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
       
  1302 {
       
  1303     Q_Q(QWidget);
       
  1304     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1305     if (extra) {                                // any size restrictions?
       
  1306         w = qMin(w,extra->maxw);
       
  1307         h = qMin(h,extra->maxh);
       
  1308         w = qMax(w,extra->minw);
       
  1309         h = qMax(h,extra->minh);
       
  1310     }
       
  1311     if (q->isWindow())
       
  1312         topData()->normalGeometry = QRect(0, 0, -1, -1);
       
  1313 
       
  1314     QSize  oldSize(q->size());
       
  1315     QPoint oldPos(q->pos());
       
  1316 
       
  1317     if (!q->isWindow())
       
  1318         isMove = (data.crect.topLeft() != QPoint(x, y));
       
  1319     bool isResize = w != oldSize.width() || h != oldSize.height();
       
  1320 
       
  1321     if (!isMove && !isResize)
       
  1322         return;
       
  1323 
       
  1324     if (isResize && !q->testAttribute(Qt::WA_StaticContents) && q->internalWinId())
       
  1325         ValidateRgn(q->internalWinId(), 0);
       
  1326 
       
  1327     if (isResize)
       
  1328         data.window_state &= ~Qt::WindowMaximized;
       
  1329 
       
  1330     if (data.window_state & Qt::WindowFullScreen) {
       
  1331         QTLWExtra *top = topData();
       
  1332 
       
  1333         if (q->isWindow()) {
       
  1334             // We need to update these flags when we remove the full screen state
       
  1335             // or the frame will not be updated
       
  1336             UINT style = top->savedFlags;
       
  1337             if (q->isVisible())
       
  1338                 style |= WS_VISIBLE;
       
  1339             SetWindowLong(q->internalWinId(), GWL_STYLE, style);
       
  1340 
       
  1341             UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE;
       
  1342             if (data.window_state & Qt::WindowActive)
       
  1343                 swpf |= SWP_NOACTIVATE;
       
  1344             SetWindowPos(q->internalWinId(), 0, 0, 0, 0, 0, swpf);
       
  1345             updateFrameStrut();
       
  1346         }
       
  1347         data.window_state &= ~Qt::WindowFullScreen;
       
  1348         topData()->savedFlags = 0;
       
  1349     }
       
  1350 
       
  1351     QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
       
  1352     const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false;
       
  1353     const bool isTranslucentWindow = !isOpaque && ptrUpdateLayeredWindowIndirect && (data.window_flags & Qt::FramelessWindowHint)
       
  1354                                      && GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED;
       
  1355 
       
  1356     if (q->testAttribute(Qt::WA_WState_ConfigPending)) {        // processing config event
       
  1357         if (q->internalWinId())
       
  1358             qWinRequestConfig(q->internalWinId(), isMove ? 2 : 1, x, y, w, h);
       
  1359     } else {
       
  1360         if (!q->testAttribute(Qt::WA_DontShowOnScreen))
       
  1361             q->setAttribute(Qt::WA_WState_ConfigPending);
       
  1362         if (q->windowType() == Qt::Desktop) {
       
  1363             data.crect.setRect(x, y, w, h);
       
  1364         } else if (q->isWindow()) {
       
  1365             QRect fs(frameStrut());
       
  1366             if (extra) {
       
  1367                 fs.setLeft(x - fs.left());
       
  1368                 fs.setTop(y - fs.top());
       
  1369                 fs.setRight((x + w - 1) + fs.right());
       
  1370                 fs.setBottom((y + h - 1) + fs.bottom());
       
  1371             }
       
  1372             if (w == 0 || h == 0) {
       
  1373                 q->setAttribute(Qt::WA_OutsideWSRange, true);
       
  1374                 if (q->isVisible() && q->testAttribute(Qt::WA_Mapped))
       
  1375                     hide_sys();
       
  1376                 data.crect = QRect(x, y, w, h);
       
  1377             } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) {
       
  1378                 q->setAttribute(Qt::WA_OutsideWSRange, false);
       
  1379 
       
  1380                 // put the window in its place and show it
       
  1381                 MoveWindow(q->internalWinId(), fs.x(), fs.y(), fs.width(), fs.height(), true);
       
  1382                 RECT rect;
       
  1383                 if (!q->testAttribute(Qt::WA_DontShowOnScreen)) {
       
  1384                     GetClientRect(q->internalWinId(), &rect);
       
  1385                     data.crect.setRect(x, y, rect.right - rect.left, rect.bottom - rect.top);
       
  1386                 } else {
       
  1387                     data.crect.setRect(x, y, w, h);
       
  1388                 }
       
  1389 
       
  1390                 show_sys();
       
  1391             } else if (!q->testAttribute(Qt::WA_DontShowOnScreen)) {
       
  1392                 q->setAttribute(Qt::WA_OutsideWSRange, false);
       
  1393 #ifndef Q_WS_WINCE
       
  1394                 // If the window is hidden and in maximized state or minimized, instead of moving the
       
  1395                 // window, set the normal position of the window.
       
  1396                 WINDOWPLACEMENT wndpl;
       
  1397                 GetWindowPlacement(q->internalWinId(), &wndpl);
       
  1398                 if ((wndpl.showCmd == SW_MAXIMIZE && !IsWindowVisible(q->internalWinId())) || wndpl.showCmd == SW_SHOWMINIMIZED) {
       
  1399                     RECT normal = {fs.x(), fs.y(), fs.x()+fs.width(), fs.y()+fs.height()};
       
  1400                     wndpl.rcNormalPosition = normal;
       
  1401                     wndpl.showCmd = wndpl.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE;
       
  1402                     SetWindowPlacement(q->internalWinId(), &wndpl);
       
  1403                 } else {
       
  1404 #else
       
  1405                 if (data.window_state & Qt::WindowMaximized) {
       
  1406                     qt_wince_maximize(q);
       
  1407                 } else {
       
  1408 #endif
       
  1409                     MoveWindow(q->internalWinId(), fs.x(), fs.y(), fs.width(), fs.height(), true);
       
  1410                 }
       
  1411                 if (!q->isVisible())
       
  1412                     InvalidateRect(q->internalWinId(), 0, FALSE);
       
  1413                 RECT rect;
       
  1414                 // If the layout has heightForWidth, the MoveWindow() above can
       
  1415                 // change the size/position, so refresh them.
       
  1416 
       
  1417                 if (isTranslucentWindow) {
       
  1418                     data.crect.setRect(x, y, w, h);
       
  1419                 } else {
       
  1420                     GetClientRect(q->internalWinId(), &rect);
       
  1421                     RECT rcNormalPosition ={0};
       
  1422                     // Use (0,0) as window position for embedded ActiveQt controls.
       
  1423                     if (!tlwExtra || !tlwExtra->embedded)
       
  1424                         GetWindowRect(q->internalWinId(), &rcNormalPosition);
       
  1425                     QRect fStrut(frameStrut());
       
  1426                     data.crect.setRect(rcNormalPosition.left + fStrut.left(),
       
  1427                                        rcNormalPosition.top + fStrut.top(),
       
  1428                                        rect.right - rect.left,
       
  1429                                        rect.bottom - rect.top);
       
  1430                     isResize = data.crect.size() != oldSize;
       
  1431                 }
       
  1432             } else {
       
  1433                 q->setAttribute(Qt::WA_OutsideWSRange, false);
       
  1434                 data.crect.setRect(x, y, w, h);
       
  1435             }
       
  1436         } else {
       
  1437             QRect oldGeom(data.crect);
       
  1438             data.crect.setRect(x, y, w, h);
       
  1439             if (q->isVisible() && (!inTopLevelResize || q->internalWinId())) {
       
  1440                 // Top-level resize optimization does not work for native child widgets;
       
  1441                 // disable it for this particular widget.
       
  1442                 if (inTopLevelResize)
       
  1443                     tlwExtra->inTopLevelResize = false;
       
  1444 
       
  1445                 if (!isResize)
       
  1446                     moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y());
       
  1447                 else
       
  1448                     invalidateBuffer_resizeHelper(oldPos, oldSize);
       
  1449 
       
  1450                 if (inTopLevelResize)
       
  1451                     tlwExtra->inTopLevelResize = true;
       
  1452             }
       
  1453             if (q->testAttribute(Qt::WA_WState_Created))
       
  1454                 setWSGeometry();
       
  1455         }
       
  1456         q->setAttribute(Qt::WA_WState_ConfigPending, false);
       
  1457     }
       
  1458 
       
  1459     if (q->isWindow() && q->isVisible() && isResize && !inTopLevelResize) {
       
  1460         invalidateBuffer(q->rect()); //after the resize
       
  1461     }
       
  1462 
       
  1463     // Process events immediately rather than in translateConfigEvent to
       
  1464     // avoid windows message process delay.
       
  1465     if (q->isVisible()) {
       
  1466         if (isMove && q->pos() != oldPos) {
       
  1467             QMoveEvent e(q->pos(), oldPos);
       
  1468             QApplication::sendEvent(q, &e);
       
  1469         }
       
  1470         if (isResize) {
       
  1471             static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
       
  1472             // If we have a backing store with static contents, we have to disable the top-level
       
  1473             // resize optimization in order to get invalidated regions for resized widgets.
       
  1474             // The optimization discards all invalidateBuffer() calls since we're going to
       
  1475             // repaint everything anyways, but that's not the case with static contents.
       
  1476             const bool setTopLevelResize = !slowResize && q->isWindow() && extra && extra->topextra
       
  1477                                            && !extra->topextra->inTopLevelResize
       
  1478                                            && (!extra->topextra->backingStore
       
  1479                                                || !extra->topextra->backingStore->hasStaticContents());
       
  1480             if (setTopLevelResize)
       
  1481                 extra->topextra->inTopLevelResize = true;
       
  1482             QResizeEvent e(q->size(), oldSize);
       
  1483             QApplication::sendEvent(q, &e);
       
  1484             if (setTopLevelResize)
       
  1485                 extra->topextra->inTopLevelResize = false;
       
  1486         }
       
  1487     } else {
       
  1488         if (isMove && q->pos() != oldPos)
       
  1489             q->setAttribute(Qt::WA_PendingMoveEvent, true);
       
  1490         if (isResize)
       
  1491             q->setAttribute(Qt::WA_PendingResizeEvent, true);
       
  1492     }
       
  1493 }
       
  1494 
       
  1495 bool QWidgetPrivate::shouldShowMaximizeButton()
       
  1496 {
       
  1497     if (data.window_flags & Qt::MSWindowsFixedSizeDialogHint)
       
  1498         return false;
       
  1499     // if the user explicitely asked for the maximize button, we try to add
       
  1500     // it even if the window has fixed size.
       
  1501     if (data.window_flags & Qt::CustomizeWindowHint &&
       
  1502         data.window_flags & Qt::WindowMaximizeButtonHint)
       
  1503         return true;
       
  1504     if (extra) {
       
  1505         if ((extra->maxw && extra->maxw != QWIDGETSIZE_MAX && extra->maxw != QLAYOUTSIZE_MAX)
       
  1506             || (extra->maxh && extra->maxh != QWIDGETSIZE_MAX && extra->maxh != QLAYOUTSIZE_MAX))
       
  1507             return false;
       
  1508     }
       
  1509     return data.window_flags & Qt::WindowMaximizeButtonHint;
       
  1510 }
       
  1511 
       
  1512 void QWidgetPrivate::winUpdateIsOpaque()
       
  1513 {
       
  1514 #ifndef Q_WS_WINCE
       
  1515     Q_Q(QWidget);
       
  1516 
       
  1517     if (!q->isWindow() || !q->testAttribute(Qt::WA_TranslucentBackground))
       
  1518         return;
       
  1519 
       
  1520     if ((data.window_flags & Qt::FramelessWindowHint) == 0)
       
  1521         return;
       
  1522 
       
  1523     if (!isOpaque && ptrUpdateLayeredWindowIndirect) {
       
  1524         SetWindowLong(q->internalWinId(), GWL_EXSTYLE,
       
  1525             GetWindowLong(q->internalWinId(), GWL_EXSTYLE) | Q_WS_EX_LAYERED);
       
  1526     } else {
       
  1527         SetWindowLong(q->internalWinId(), GWL_EXSTYLE,
       
  1528             GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & ~Q_WS_EX_LAYERED);
       
  1529     }
       
  1530 #endif
       
  1531 }
       
  1532 
       
  1533 void QWidgetPrivate::setConstraints_sys()
       
  1534 {
       
  1535 #ifndef Q_WS_WINCE_WM
       
  1536     Q_Q(QWidget);
       
  1537     if (q->isWindow() && q->testAttribute(Qt::WA_WState_Created)) {
       
  1538         int style = GetWindowLong(q->internalWinId(), GWL_STYLE);
       
  1539         if (shouldShowMaximizeButton())
       
  1540             style |= WS_MAXIMIZEBOX;
       
  1541         else
       
  1542             style &= ~WS_MAXIMIZEBOX;
       
  1543         SetWindowLong(q->internalWinId(), GWL_STYLE, style);
       
  1544     }
       
  1545 #endif
       
  1546 }
       
  1547 
       
  1548 void QWidgetPrivate::scroll_sys(int dx, int dy)
       
  1549 {
       
  1550     Q_Q(QWidget);
       
  1551     scrollChildren(dx, dy);
       
  1552 
       
  1553     if (!paintOnScreen()) {
       
  1554         scrollRect(q->rect(), dx, dy);
       
  1555     } else {
       
  1556         UINT flags = SW_INVALIDATE;
       
  1557         if (!q->testAttribute(Qt::WA_OpaquePaintEvent))
       
  1558             flags |= SW_ERASE;
       
  1559         Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1560         ScrollWindowEx(q->internalWinId(), dx, dy, 0, 0, 0, 0, flags);
       
  1561         UpdateWindow(q->internalWinId());
       
  1562     }
       
  1563 }
       
  1564 
       
  1565 void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r)
       
  1566 {
       
  1567     Q_Q(QWidget);
       
  1568 
       
  1569     if (!paintOnScreen()) {
       
  1570         scrollRect(r, dx, dy);
       
  1571     } else {
       
  1572         RECT wr;
       
  1573         wr.top = r.top();
       
  1574         wr.left = r.left();
       
  1575         wr.bottom = r.bottom()+1;
       
  1576         wr.right = r.right()+1;
       
  1577 
       
  1578         UINT flags = SW_INVALIDATE;
       
  1579         if (!q->testAttribute(Qt::WA_OpaquePaintEvent))
       
  1580             flags |= SW_ERASE;
       
  1581         Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1582         ScrollWindowEx(q->internalWinId(), dx, dy, &wr, &wr, 0, 0, flags);
       
  1583         UpdateWindow(q->internalWinId());
       
  1584     }
       
  1585 }
       
  1586 
       
  1587 extern Q_GUI_EXPORT HDC qt_win_display_dc();
       
  1588 
       
  1589 int QWidget::metric(PaintDeviceMetric m) const
       
  1590 {
       
  1591     Q_D(const QWidget);
       
  1592     int val;
       
  1593     if (m == PdmWidth) {
       
  1594         val = data->crect.width();
       
  1595     } else if (m == PdmHeight) {
       
  1596         val = data->crect.height();
       
  1597     } else {
       
  1598         HDC gdc = qt_win_display_dc();
       
  1599         switch (m) {
       
  1600         case PdmDpiX:
       
  1601         case PdmPhysicalDpiX:
       
  1602                 if (d->extra && d->extra->customDpiX)
       
  1603                     val = d->extra->customDpiX;
       
  1604                 else if (d->parent)
       
  1605                     val = static_cast<QWidget *>(d->parent)->metric(m);
       
  1606                 else
       
  1607                     val = GetDeviceCaps(gdc, LOGPIXELSX);
       
  1608             break;
       
  1609         case PdmDpiY:
       
  1610         case PdmPhysicalDpiY:
       
  1611                 if (d->extra && d->extra->customDpiY)
       
  1612                     val = d->extra->customDpiY;
       
  1613                 else if (d->parent)
       
  1614                     val = static_cast<QWidget *>(d->parent)->metric(m);
       
  1615                 else
       
  1616                     val = GetDeviceCaps(gdc, LOGPIXELSY);
       
  1617             break;
       
  1618         case PdmWidthMM:
       
  1619             val = data->crect.width()
       
  1620                     * GetDeviceCaps(gdc, HORZSIZE)
       
  1621                     / GetDeviceCaps(gdc, HORZRES);
       
  1622             break;
       
  1623         case PdmHeightMM:
       
  1624             val = data->crect.height()
       
  1625                     * GetDeviceCaps(gdc, VERTSIZE)
       
  1626                     / GetDeviceCaps(gdc, VERTRES);
       
  1627             break;
       
  1628         case PdmNumColors:
       
  1629             if (GetDeviceCaps(gdc, RASTERCAPS) & RC_PALETTE)
       
  1630                 val = GetDeviceCaps(gdc, SIZEPALETTE);
       
  1631             else {
       
  1632                 HDC hd = d->hd ? HDC(d->hd) : gdc;
       
  1633                 int bpp = GetDeviceCaps(hd, BITSPIXEL);
       
  1634                 if (bpp == 32)
       
  1635                     val = INT_MAX; // ### this is bogus, it should be 2^24 colors for 32 bit as well
       
  1636                 else if(bpp<=8)
       
  1637                     val = GetDeviceCaps(hd, NUMCOLORS);
       
  1638                 else
       
  1639                     val = 1 << (bpp * GetDeviceCaps(hd, PLANES));
       
  1640             }
       
  1641             break;
       
  1642         case PdmDepth:
       
  1643             val = GetDeviceCaps(gdc, BITSPIXEL);
       
  1644             break;
       
  1645         default:
       
  1646             val = 0;
       
  1647             qWarning("QWidget::metric: Invalid metric command");
       
  1648         }
       
  1649     }
       
  1650     return val;
       
  1651 }
       
  1652 
       
  1653 void QWidgetPrivate::createSysExtra()
       
  1654 {
       
  1655 #ifndef QT_NO_DRAGANDDROP
       
  1656     extra->dropTarget = 0;
       
  1657 #endif
       
  1658 }
       
  1659 
       
  1660 #ifndef Q_WS_WINCE
       
  1661 void QWidgetPrivate::deleteSysExtra()
       
  1662 {
       
  1663 }
       
  1664 #endif //Q_WS_WINCE
       
  1665 
       
  1666 void QWidgetPrivate::createTLSysExtra()
       
  1667 {
       
  1668     extra->topextra->savedFlags = 0;
       
  1669     extra->topextra->winIconBig = 0;
       
  1670     extra->topextra->winIconSmall = 0;
       
  1671 }
       
  1672 
       
  1673 void QWidgetPrivate::deleteTLSysExtra()
       
  1674 {
       
  1675     if (extra->topextra->winIconSmall)
       
  1676         DestroyIcon(extra->topextra->winIconSmall);
       
  1677     if (extra->topextra->winIconBig)
       
  1678         DestroyIcon(extra->topextra->winIconBig);
       
  1679 }
       
  1680 
       
  1681 void QWidgetPrivate::registerDropSite(bool on)
       
  1682 {
       
  1683     Q_Q(QWidget);
       
  1684     if (!q->testAttribute(Qt::WA_WState_Created))
       
  1685         return;
       
  1686     // Enablement is defined by d->extra->dropTarget != 0.
       
  1687     if (on) {
       
  1688         // Turn on.
       
  1689         createExtra();
       
  1690 #ifndef QT_NO_DRAGANDDROP
       
  1691         if (!q->internalWinId())
       
  1692             q->nativeParentWidget()->d_func()->createExtra();
       
  1693         QWExtra *extra = extraData();
       
  1694         if (!extra->dropTarget)
       
  1695             extra->dropTarget = registerOleDnd(q);
       
  1696 #endif
       
  1697     } else {
       
  1698         // Turn off.
       
  1699         QWExtra *extra = extraData();
       
  1700 #ifndef QT_NO_DRAGANDDROP
       
  1701         if (extra && extra->dropTarget) {
       
  1702             unregisterOleDnd(q, extra->dropTarget);
       
  1703             extra->dropTarget = 0;
       
  1704         }
       
  1705 #endif
       
  1706     }
       
  1707 }
       
  1708 
       
  1709 #ifndef QT_NO_DRAGANDDROP
       
  1710 QOleDropTarget* QWidgetPrivate::registerOleDnd(QWidget *widget)
       
  1711 {
       
  1712     QOleDropTarget *dropTarget = new QOleDropTarget(widget);
       
  1713     Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
       
  1714     if (!widget->internalWinId()) {
       
  1715         QWidget *nativeParent = widget->nativeParentWidget();
       
  1716         Q_ASSERT(nativeParent);
       
  1717         QWExtra *nativeExtra = nativeParent->d_func()->extra;
       
  1718         Q_ASSERT(nativeExtra);
       
  1719         if (!nativeParent->acceptDrops())
       
  1720             nativeParent->setAcceptDrops(true);
       
  1721         if (!nativeExtra->oleDropWidgets.contains(widget))
       
  1722             nativeExtra->oleDropWidgets.append(widget);
       
  1723         if (!nativeExtra->dropTarget) {
       
  1724             nativeExtra->dropTarget = registerOleDnd(nativeParent);
       
  1725             Q_ASSERT(nativeExtra->dropTarget);
       
  1726 #ifndef Q_OS_WINCE
       
  1727             CoLockObjectExternal(nativeExtra->dropTarget, false, true);
       
  1728 #endif
       
  1729             RegisterDragDrop(nativeParent->internalWinId(), nativeExtra->dropTarget);
       
  1730         }
       
  1731     } else {
       
  1732         RegisterDragDrop(widget->internalWinId(), dropTarget);
       
  1733 #ifndef Q_OS_WINCE
       
  1734         CoLockObjectExternal(dropTarget, true, true);
       
  1735 #endif
       
  1736     }
       
  1737     return dropTarget;
       
  1738 }
       
  1739 
       
  1740 void QWidgetPrivate::unregisterOleDnd(QWidget *widget, QOleDropTarget *dropTarget)
       
  1741 {
       
  1742     dropTarget->releaseQt();
       
  1743     dropTarget->Release();
       
  1744     Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
       
  1745     if (!widget->internalWinId()) {
       
  1746         QWidget *nativeParent = widget->nativeParentWidget();
       
  1747         Q_ASSERT(nativeParent);
       
  1748         QWExtra *nativeExtra = nativeParent->d_func()->extra;
       
  1749         Q_ASSERT(nativeExtra);
       
  1750         nativeExtra->oleDropWidgets.removeAll(widget);
       
  1751         nativeExtra->oleDropWidgets.removeAll(static_cast<QWidget *>(0));
       
  1752         if (nativeExtra->oleDropWidgets.isEmpty() && nativeExtra->dropTarget
       
  1753                 && !nativeParent->testAttribute(Qt::WA_DropSiteRegistered)) {
       
  1754 #ifndef Q_OS_WINCE
       
  1755             CoLockObjectExternal(nativeExtra->dropTarget, false, true);
       
  1756 #endif
       
  1757             RevokeDragDrop(nativeParent->internalWinId());
       
  1758             nativeExtra->dropTarget = 0;
       
  1759         }
       
  1760     } else {
       
  1761 #ifndef Q_OS_WINCE
       
  1762         CoLockObjectExternal(dropTarget, false, true);
       
  1763 #endif
       
  1764         RevokeDragDrop(widget->internalWinId());
       
  1765     }
       
  1766 }
       
  1767 
       
  1768 #endif //QT_NO_DRAGANDDROP
       
  1769 
       
  1770 // from qregion_win.cpp
       
  1771 extern HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom);
       
  1772 void QWidgetPrivate::setMask_sys(const QRegion &region)
       
  1773 {
       
  1774     Q_Q(QWidget);
       
  1775     if (!q->internalWinId())
       
  1776         return;
       
  1777 
       
  1778     if (region.isEmpty()) {
       
  1779         SetWindowRgn(q->internalWinId(), 0, true);
       
  1780         return;
       
  1781     }
       
  1782 
       
  1783     // Since SetWindowRegion takes ownership, and we need to translate,
       
  1784     // we take a copy.
       
  1785     HRGN wr = qt_tryCreateRegion(QRegion::Rectangle, 0,0,0,0);
       
  1786     CombineRgn(wr, region.handle(), 0, RGN_COPY);
       
  1787 
       
  1788     QPoint offset = (q->isWindow()
       
  1789                      ? frameStrut().topLeft()
       
  1790                      : QPoint(0, 0));
       
  1791     OffsetRgn(wr, offset.x(), offset.y());
       
  1792 
       
  1793     Q_ASSERT(q->testAttribute(Qt::WA_WState_Created));
       
  1794     if (!SetWindowRgn(data.winid, wr, true))
       
  1795         DeleteObject(wr);
       
  1796 }
       
  1797 
       
  1798 void QWidgetPrivate::updateFrameStrut()
       
  1799 {
       
  1800     Q_Q(QWidget);
       
  1801 
       
  1802     if (!q->testAttribute(Qt::WA_WState_Created))
       
  1803         return;
       
  1804 
       
  1805     if (!q->internalWinId()) {
       
  1806         data.fstrut_dirty = false;
       
  1807         return;
       
  1808     }
       
  1809 
       
  1810     RECT rect = {0,0,0,0};
       
  1811 
       
  1812     QTLWExtra *top = topData();
       
  1813     uint exstyle = GetWindowLong(q->internalWinId(), GWL_EXSTYLE);
       
  1814     uint style = GetWindowLong(q->internalWinId(), GWL_STYLE);
       
  1815 #ifndef Q_WS_WINCE
       
  1816     if (AdjustWindowRectEx(&rect, style & ~(WS_OVERLAPPED), FALSE, exstyle)) {
       
  1817 #else
       
  1818     if (AdjustWindowRectEx(&rect, style, FALSE, exstyle)) {
       
  1819 #endif
       
  1820         top->frameStrut.setCoords(-rect.left, -rect.top, rect.right, rect.bottom);
       
  1821         data.fstrut_dirty = false;
       
  1822     }
       
  1823 }
       
  1824 
       
  1825 #ifndef Q_WS_WINCE
       
  1826 void QWidgetPrivate::setWindowOpacity_sys(qreal level)
       
  1827 {
       
  1828     Q_Q(QWidget);
       
  1829 
       
  1830     if (!isOpaque && ptrUpdateLayeredWindow && (data.window_flags & Qt::FramelessWindowHint)) {
       
  1831         if (GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED) {
       
  1832             BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * level), AC_SRC_ALPHA};
       
  1833             ptrUpdateLayeredWindow(q->internalWinId(), NULL, NULL, NULL, NULL, NULL, 0, &blend, Q_ULW_ALPHA);
       
  1834         }
       
  1835         return;
       
  1836     }
       
  1837 
       
  1838     static bool function_resolved = false;
       
  1839     if (!function_resolved) {
       
  1840         ptrSetLayeredWindowAttributes =
       
  1841             (PtrSetLayeredWindowAttributes) QLibrary::resolve(QLatin1String("user32"),
       
  1842                                                               "SetLayeredWindowAttributes");
       
  1843         function_resolved = true;
       
  1844     }
       
  1845 
       
  1846     if (!ptrSetLayeredWindowAttributes)
       
  1847         return;
       
  1848 
       
  1849     int wl = GetWindowLong(q->internalWinId(), GWL_EXSTYLE);
       
  1850 
       
  1851     if (level != 1.0) {
       
  1852         if ((wl&Q_WS_EX_LAYERED) == 0)
       
  1853             SetWindowLong(q->internalWinId(), GWL_EXSTYLE, wl | Q_WS_EX_LAYERED);
       
  1854     } else if (wl&Q_WS_EX_LAYERED) {
       
  1855         SetWindowLong(q->internalWinId(), GWL_EXSTYLE, wl & ~Q_WS_EX_LAYERED);
       
  1856     }
       
  1857     ptrSetLayeredWindowAttributes(q->internalWinId(), 0, (int)(level * 255), Q_LWA_ALPHA);
       
  1858 }
       
  1859 #endif //Q_WS_WINCE
       
  1860 
       
  1861 // class QGlobalRasterPaintEngine: public QRasterPaintEngine
       
  1862 // {
       
  1863 // public:
       
  1864 //     inline QGlobalRasterPaintEngine() : QRasterPaintEngine() { setFlushOnEnd(false); }
       
  1865 // };
       
  1866 // Q_GLOBAL_STATIC(QGlobalRasterPaintEngine, globalRasterPaintEngine)
       
  1867 
       
  1868 
       
  1869 #ifndef QT_NO_DIRECTDRAW
       
  1870 static uchar *qt_primary_surface_bits;
       
  1871 static int qt_primary_surface_stride;
       
  1872 static QImage::Format qt_primary_surface_format;
       
  1873 
       
  1874 void qt_win_initialize_directdraw()
       
  1875 {
       
  1876     HRESULT res;
       
  1877 
       
  1878     // Some initialization...
       
  1879     if (!qt_ddraw_object) {
       
  1880         res = DirectDrawCreate(0, &qt_ddraw_object, 0);
       
  1881 
       
  1882         if (res != DD_OK)
       
  1883             qWarning("DirectDrawCreate failed: %d", res);
       
  1884 
       
  1885         qt_ddraw_object->SetCooperativeLevel(0, DDSCL_NORMAL);
       
  1886 
       
  1887         DDSURFACEDESC surfaceDesc;
       
  1888         memset(&surfaceDesc, 0, sizeof(DDSURFACEDESC));
       
  1889 
       
  1890         surfaceDesc.dwSize = sizeof(DDSURFACEDESC);
       
  1891         surfaceDesc.dwFlags = DDSD_CAPS;
       
  1892         surfaceDesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
       
  1893 
       
  1894         res = qt_ddraw_object->CreateSurface(&surfaceDesc, &qt_ddraw_primary, 0);
       
  1895         if (res != DD_OK)
       
  1896             qWarning("CreateSurface failed: %d", res);
       
  1897 
       
  1898         memset(&surfaceDesc, 0, sizeof(DDSURFACEDESC));
       
  1899         surfaceDesc.dwSize = sizeof(DDSURFACEDESC);
       
  1900         res = qt_ddraw_primary->Lock(0, &surfaceDesc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, 0);
       
  1901         if (res != DD_OK)
       
  1902             qWarning("Locking surface failed: %d", res);
       
  1903 
       
  1904         if (surfaceDesc.ddpfPixelFormat.dwFlags == DDPF_RGB) {
       
  1905             qt_primary_surface_bits = (uchar *) surfaceDesc.lpSurface;
       
  1906             qt_primary_surface_stride = surfaceDesc.lPitch;
       
  1907             qt_primary_surface_format = QImage::Format_RGB32;
       
  1908         } else {
       
  1909             qWarning("QWidget painting: unsupported device depth for onscreen painting...\n");
       
  1910         }
       
  1911 
       
  1912         qt_ddraw_primary->Unlock(0);
       
  1913     }
       
  1914 }
       
  1915 
       
  1916 class QOnScreenRasterPaintEngine : public QRasterPaintEngine
       
  1917 {
       
  1918 public:
       
  1919     // The image allocated here leaks... Fix if this code is ifdef'ed
       
  1920     // in
       
  1921     QOnScreenRasterPaintEngine()
       
  1922         : QRasterPaintEngine(new QImage(qt_primary_surface_bits,
       
  1923                                         QApplication::desktop()->width(),
       
  1924                                         QApplication::desktop()->height(),
       
  1925                                         qt_primary_surface_stride,
       
  1926                                         qt_primary_surface_format))
       
  1927     {
       
  1928         device = static_cast<QImage *>(d_func()->device);
       
  1929     }
       
  1930 
       
  1931     bool begin(QPaintDevice *)
       
  1932     {
       
  1933         QRegion clip = systemClip();
       
  1934         originalSystemClip = clip;
       
  1935         clip.translate(widget->mapToGlobal(QPoint(0, 0)));
       
  1936         setSystemClip(clip);
       
  1937 
       
  1938         QRect bounds = clip.boundingRect();
       
  1939         DDSURFACEDESC surface;
       
  1940         surface.dwSize = sizeof(DDSURFACEDESC);
       
  1941         HRESULT res = qt_ddraw_primary->Lock((RECT *) &bounds, &surface, DDLOCK_WAIT, 0);
       
  1942         if (res != DD_OK) {
       
  1943             qWarning("QWidget painting: locking onscreen bits failed: %d\n", res);
       
  1944             return false;
       
  1945         }
       
  1946 
       
  1947         if (surface.lpSurface == qt_primary_surface_bits) {
       
  1948             qt_primary_surface_bits = (uchar *) surface.lpSurface;
       
  1949             device->data_ptr()->data = qt_primary_surface_bits;
       
  1950         }
       
  1951 
       
  1952         return QRasterPaintEngine::begin(device);
       
  1953     }
       
  1954 
       
  1955     bool end()
       
  1956     {
       
  1957         HRESULT res = qt_ddraw_primary->Unlock(0);
       
  1958         if (res != DD_OK)
       
  1959             qWarning("QWidget::paint, failed to unlock DirectDraw surface: %d", res);
       
  1960         bool ok = QRasterPaintEngine::end();
       
  1961         setSystemClip(originalSystemClip);
       
  1962         return ok;
       
  1963     }
       
  1964 
       
  1965     QPoint coordinateOffset() const {
       
  1966         return -widget->mapToGlobal(QPoint(0, 0));
       
  1967     }
       
  1968 
       
  1969     const QWidget *widget;
       
  1970     QImage *device;
       
  1971     QRegion originalSystemClip;
       
  1972 };
       
  1973 Q_GLOBAL_STATIC(QOnScreenRasterPaintEngine, onScreenPaintEngine)
       
  1974 #else
       
  1975 void qt_win_initialize_directdraw() { }
       
  1976 #endif
       
  1977 
       
  1978 QPaintEngine *QWidget::paintEngine() const
       
  1979 {
       
  1980 #ifndef QT_NO_DIRECTDRAW
       
  1981     QOnScreenRasterPaintEngine *pe = onScreenPaintEngine();
       
  1982     pe->widget = this;
       
  1983     return pe;
       
  1984 #endif
       
  1985 
       
  1986     // We set this bit which is checked in setAttribute for
       
  1987     // Qt::WA_PaintOnScreen. We do this to allow these two scenarios:
       
  1988     //
       
  1989     // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to
       
  1990     // windows which would mean suddenly their widgets stop working.
       
  1991     //
       
  1992     // 2. Users set paint on screen and subclass paintEngine() to
       
  1993     // return 0, in which case we have a "hole" in the backingstore
       
  1994     // allowing use of GDI or DirectX directly.
       
  1995     //
       
  1996     // 1 is WRONG, but to minimize silent failures, we have set this
       
  1997     // bit to ignore the setAttribute call. 2. needs to be
       
  1998     // supported because its our only means of embeddeding native
       
  1999     // graphics stuff.
       
  2000     const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1;
       
  2001 
       
  2002     return 0;
       
  2003 }
       
  2004 
       
  2005 QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
       
  2006 {
       
  2007     Q_Q(QWidget);
       
  2008     return new QRasterWindowSurface(q);
       
  2009 }
       
  2010 
       
  2011 void QWidgetPrivate::setModal_sys()
       
  2012 {
       
  2013 }
       
  2014 
       
  2015 void QWidgetPrivate::registerTouchWindow()
       
  2016 {
       
  2017     Q_Q(QWidget);
       
  2018 
       
  2019     // enable WM_TOUCH* messages on our window
       
  2020     if (q->testAttribute(Qt::WA_WState_Created)
       
  2021         && QApplicationPrivate::RegisterTouchWindow
       
  2022         && q->windowType() != Qt::Desktop)
       
  2023         QApplicationPrivate::RegisterTouchWindow(q->effectiveWinId(), 0);
       
  2024 }
       
  2025 
       
  2026 void QWidgetPrivate::winSetupGestures()
       
  2027 {
       
  2028     Q_Q(QWidget);
       
  2029     if (!q || !q->isVisible())
       
  2030         return;
       
  2031     QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
       
  2032     WId winid = q->effectiveWinId();
       
  2033 
       
  2034     bool needh = false;
       
  2035     bool needv = false;
       
  2036     bool singleFingerPanEnabled = false;
       
  2037 
       
  2038     if (QAbstractScrollArea *asa = qobject_cast<QAbstractScrollArea*>(q->parent())) {
       
  2039         QScrollBar *hbar = asa->horizontalScrollBar();
       
  2040         QScrollBar *vbar = asa->verticalScrollBar();
       
  2041         Qt::ScrollBarPolicy hbarpolicy = asa->horizontalScrollBarPolicy();
       
  2042         Qt::ScrollBarPolicy vbarpolicy = asa->verticalScrollBarPolicy();
       
  2043         needh = (hbarpolicy == Qt::ScrollBarAlwaysOn ||
       
  2044                  (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum()));
       
  2045         needv = (vbarpolicy == Qt::ScrollBarAlwaysOn ||
       
  2046                  (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum()));
       
  2047         singleFingerPanEnabled = asa->d_func()->singleFingerPanEnabled;
       
  2048     }
       
  2049     if (winid && qAppPriv->SetGestureConfig) {
       
  2050         GESTURECONFIG gc[1];
       
  2051         memset(gc, 0, sizeof(gc));
       
  2052         gc[0].dwID = GID_PAN;
       
  2053         if (nativeGesturePanEnabled) {
       
  2054             gc[0].dwWant = GC_PAN;
       
  2055             if (needv && singleFingerPanEnabled)
       
  2056                 gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
       
  2057             else
       
  2058                 gc[0].dwBlock |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
       
  2059             if (needh && singleFingerPanEnabled)
       
  2060                 gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
       
  2061             else
       
  2062                 gc[0].dwBlock |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
       
  2063         } else {
       
  2064             gc[0].dwBlock = GC_PAN;
       
  2065         }
       
  2066 
       
  2067 //        gc[1].dwID = GID_ZOOM;
       
  2068 //        if (gestures.pinch)
       
  2069 //            gc[1].dwWant = GC_ZOOM;
       
  2070 //        else
       
  2071 //            gc[1].dwBlock = GC_ZOOM;
       
  2072 //        gc[2].dwID = GID_ROTATE;
       
  2073 //        if (gestures.pinch)
       
  2074 //            gc[2].dwWant = GC_ROTATE;
       
  2075 //        else
       
  2076 //            gc[2].dwBlock = GC_ROTATE;
       
  2077 
       
  2078         qAppPriv->SetGestureConfig(winid, 0, sizeof(gc)/sizeof(gc[0]), gc, sizeof(gc[0]));
       
  2079     }
       
  2080 }
       
  2081 
       
  2082 QT_END_NAMESPACE
       
  2083 
       
  2084 #ifdef Q_WS_WINCE
       
  2085 #       include "qwidget_wince.cpp"
       
  2086 #endif