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