src/gui/kernel/qapplication_win.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #ifdef Q_WS_WINCE
       
    43 #include "qguifunctions_wince.h"
       
    44 #include "qmenubar.h"
       
    45 extern bool qt_wince_is_mobile();             //defined in qguifunctions_wince.cpp
       
    46 extern bool qt_wince_is_high_dpi();           //defined in qguifunctions_wince.cpp
       
    47 extern bool qt_wince_is_smartphone();         //defined in qguifunctions_wince.cpp
       
    48 extern bool qt_wince_is_pocket_pc();          //defined in qguifunctions_wince.cpp
       
    49 extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.cpp
       
    50 #endif
       
    51 #ifdef Q_WS_WINCE_WM
       
    52 #include <windowsm.h>
       
    53 #include <tpcshell.h>
       
    54 #ifdef QT_WINCE_GESTURES
       
    55 #include <gesture.h>
       
    56 #endif
       
    57 #endif
       
    58 
       
    59 #include "qapplication.h"
       
    60 #include "qdesktopwidget.h"
       
    61 #include "qevent.h"
       
    62 #include "private/qeventdispatcher_win_p.h"
       
    63 #include "qeventloop.h"
       
    64 #include "qclipboard.h"
       
    65 #include "qcursor.h"
       
    66 #include "qdatetime.h"
       
    67 #include "qpointer.h"
       
    68 #include "qhash.h"
       
    69 #include "qlibrary.h"
       
    70 #include "qmetaobject.h"
       
    71 #include "qmime.h"
       
    72 #include "qpainter.h"
       
    73 #include "qpixmapcache.h"
       
    74 #include "qsessionmanager.h"
       
    75 #include "qstyle.h"
       
    76 #include "qwhatsthis.h" // ######## dependency
       
    77 #include "qwidget.h"
       
    78 #include "qcolormap.h"
       
    79 #include "qlayout.h"
       
    80 #include "qtooltip.h"
       
    81 #include "qt_windows.h"
       
    82 #if defined(QT_NON_COMMERCIAL)
       
    83 #include "qnc_win.h"
       
    84 #endif
       
    85 #include "private/qwininputcontext_p.h"
       
    86 #include "private/qcursor_p.h"
       
    87 #include "private/qmath_p.h"
       
    88 #include "private/qapplication_p.h"
       
    89 #include "private/qbackingstore_p.h"
       
    90 #include "private/qwindowsurface_raster_p.h"
       
    91 #include "qdebug.h"
       
    92 #include <private/qkeymapper_p.h>
       
    93 #include <private/qlocale_p.h>
       
    94 #include "qevent_p.h"
       
    95 
       
    96 //#define ALIEN_DEBUG
       
    97 
       
    98 #ifndef QT_NO_THREAD
       
    99 #include "qmutex.h"
       
   100 #endif
       
   101 
       
   102 #ifndef QT_NO_ACCESSIBILITY
       
   103 #include "qaccessible.h"
       
   104 
       
   105 #include <oleacc.h>
       
   106 #ifndef WM_GETOBJECT
       
   107 #define WM_GETOBJECT                    0x003D
       
   108 #endif
       
   109 #endif // QT_NO_ACCESSIBILITY
       
   110 
       
   111 #if !defined(WINABLEAPI)
       
   112 #  if defined(Q_WS_WINCE)
       
   113 #    include <bldver.h>
       
   114 #  endif
       
   115 #  include <winable.h>
       
   116 #endif
       
   117 
       
   118 #ifndef WM_TOUCH
       
   119 #  define WM_TOUCH 0x0240
       
   120 
       
   121 #  define TOUCHEVENTF_MOVE       0x0001
       
   122 #  define TOUCHEVENTF_DOWN       0x0002
       
   123 #  define TOUCHEVENTF_UP         0x0004
       
   124 #  define TOUCHEVENTF_INRANGE    0x0008
       
   125 #  define TOUCHEVENTF_PRIMARY    0x0010
       
   126 #  define TOUCHEVENTF_NOCOALESCE 0x0020
       
   127 #  define TOUCHEVENTF_PEN        0x0040
       
   128 #  define TOUCHEVENTF_PALM       0x0080
       
   129 
       
   130 #  define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001
       
   131 #  define TOUCHINPUTMASKF_EXTRAINFO      0x0002
       
   132 #  define TOUCHINPUTMASKF_CONTACTAREA    0x0004
       
   133 
       
   134 typedef struct tagTOUCHINPUT
       
   135 {
       
   136     LONG x;
       
   137     LONG y;
       
   138     HANDLE hSource;
       
   139     DWORD dwID;
       
   140     DWORD dwFlags;
       
   141     DWORD dwMask;
       
   142     DWORD dwTime;
       
   143     ULONG_PTR dwExtraInfo;
       
   144     DWORD cxContact;
       
   145     DWORD cyContact;
       
   146 } TOUCHINPUT, *PTOUCHINPUT;
       
   147 
       
   148 #endif
       
   149 
       
   150 #include <windowsx.h>
       
   151 #include <limits.h>
       
   152 #include <string.h>
       
   153 #include <ctype.h>
       
   154 #include <stdio.h>
       
   155 #include <math.h>
       
   156 
       
   157 #define PACKETDATA  (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE \
       
   158                      | PK_ORIENTATION | PK_CURSOR | PK_Z)
       
   159 #define PACKETMODE  0
       
   160 
       
   161 #include <wintab.h>
       
   162 #ifndef CSR_TYPE
       
   163 #define CSR_TYPE 20 // Some old Wacom wintab.h may not provide this constant.
       
   164 #endif
       
   165 #include <pktdef.h>
       
   166 
       
   167 #if defined(__CYGWIN32__)
       
   168 #define __INSIDE_CYGWIN32__
       
   169 #include <mywinsock.h>
       
   170 #endif
       
   171 
       
   172 #ifndef IMR_RECONVERTSTRING
       
   173 #define IMR_RECONVERTSTRING 4
       
   174 #endif
       
   175 
       
   176 #ifndef IMR_CONFIRMRECONVERTSTRING
       
   177 #define IMR_CONFIRMRECONVERTSTRING 0x0005
       
   178 #endif
       
   179 QT_BEGIN_NAMESPACE
       
   180 
       
   181 #ifdef Q_WS_WINCE
       
   182 #ifndef SHRG_RETURNCMD
       
   183 struct SHRGINFO {
       
   184     DWORD cbSize;
       
   185     HWND hwndClient;
       
   186     POINT ptDown;
       
   187     DWORD dwFlags;
       
   188 };
       
   189 #define  GN_CONTEXTMENU       1000
       
   190 #define  SHRG_RETURNCMD       0x00000001
       
   191 #define  SHRG_NOANIMATION     0x00000010
       
   192 #endif
       
   193 
       
   194 #ifndef SPI_SETSIPINFO
       
   195 #define SPI_SETSIPINFO        224
       
   196 #endif
       
   197 
       
   198 typedef DWORD (API *AygRecognizeGesture)(SHRGINFO*);
       
   199 static AygRecognizeGesture ptrRecognizeGesture = 0;
       
   200 static bool aygResolved = false;
       
   201 static void resolveAygLibs()
       
   202 {
       
   203     if (!aygResolved) {
       
   204         aygResolved = true;
       
   205         QLibrary ayglib(QLatin1String("aygshell"));
       
   206         if (!ayglib.load())
       
   207             return;
       
   208         ptrRecognizeGesture = (AygRecognizeGesture) ayglib.resolve("SHRecognizeGesture");
       
   209     }
       
   210 }
       
   211 
       
   212 #endif
       
   213 
       
   214 #ifndef SPI_SETFONTSMOOTHINGTYPE
       
   215 #  define SPI_SETFONTSMOOTHINGTYPE 0x200B
       
   216 #endif
       
   217 #ifndef SPI_GETFONTSMOOTHINGTYPE
       
   218 #  define SPI_GETFONTSMOOTHINGTYPE 0x200A
       
   219 #endif
       
   220 #ifndef FE_FONTSMOOTHINGCLEARTYPE
       
   221 #  define FE_FONTSMOOTHINGCLEARTYPE 0x0002
       
   222 #endif
       
   223 
       
   224 Q_GUI_EXPORT bool qt_cleartype_enabled;
       
   225 Q_GUI_EXPORT bool qt_win_owndc_required; // CS_OWNDC is required if we use the GL graphicssystem as default
       
   226 
       
   227 typedef HCTX (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL);
       
   228 typedef BOOL (API *PtrWTClose)(HCTX);
       
   229 typedef UINT (API *PtrWTInfo)(UINT, UINT, LPVOID);
       
   230 typedef BOOL (API *PtrWTEnable)(HCTX, BOOL);
       
   231 typedef BOOL (API *PtrWTOverlap)(HCTX, BOOL);
       
   232 typedef int  (API *PtrWTPacketsGet)(HCTX, int, LPVOID);
       
   233 typedef BOOL (API *PtrWTGet)(HCTX, LPLOGCONTEXT);
       
   234 typedef int  (API *PtrWTQueueSizeGet)(HCTX);
       
   235 typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int);
       
   236 
       
   237 static PtrWTInfo ptrWTInfo = 0;
       
   238 static PtrWTEnable ptrWTEnable = 0;
       
   239 static PtrWTOverlap ptrWTOverlap = 0;
       
   240 static PtrWTPacketsGet ptrWTPacketsGet = 0;
       
   241 static PtrWTGet ptrWTGet = 0;
       
   242 
       
   243 static PACKET localPacketBuf[QT_TABLET_NPACKETQSIZE];  // our own tablet packet queue.
       
   244 HCTX qt_tablet_context;  // the hardware context for the tablet (like a window handle)
       
   245 bool qt_tablet_tilt_support;
       
   246 static void tabletInit(UINT wActiveCsr, HCTX hTab);
       
   247 static void initWinTabFunctions();        // resolve the WINTAB api functions
       
   248 
       
   249 
       
   250 #ifndef QT_NO_ACCESSIBILITY
       
   251 extern IAccessible *qt_createWindowsAccessible(QAccessibleInterface *object);
       
   252 #endif // QT_NO_ACCESSIBILITY
       
   253 
       
   254 extern bool qt_tabletChokeMouse;
       
   255 extern QWidget* qt_get_tablet_widget();
       
   256 extern bool qt_sendSpontaneousEvent(QObject*, QEvent*);
       
   257 extern QRegion qt_dirtyRegion(QWidget *);
       
   258 
       
   259 typedef QHash<UINT, QTabletDeviceData> QTabletCursorInfo;
       
   260 Q_GLOBAL_STATIC(QTabletCursorInfo, tCursorInfo)
       
   261 QTabletDeviceData currentTabletPointer;
       
   262 
       
   263 // from qregion_win.cpp
       
   264 extern HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom);
       
   265 
       
   266 // support for on-the-fly changes of the XP theme engine
       
   267 #ifndef WM_THEMECHANGED
       
   268 #define WM_THEMECHANGED                 0x031A
       
   269 #endif
       
   270 #ifndef COLOR_MENUHILIGHT
       
   271 #define COLOR_MENUHILIGHT                29
       
   272 #define COLOR_MENUBAR                        30
       
   273 #endif
       
   274 
       
   275 // support for xbuttons
       
   276 #ifndef WM_XBUTTONDOWN
       
   277 #define WM_XBUTTONDOWN                  0x020B
       
   278 #define WM_XBUTTONUP                    0x020C
       
   279 #define WM_XBUTTONDBLCLK                0x020D
       
   280 #endif
       
   281 #ifndef GET_KEYSTATE_WPARAM
       
   282 #define GET_KEYSTATE_WPARAM(wParam)     (LOWORD(wParam))
       
   283 #define GET_XBUTTON_WPARAM(wParam)      (HIWORD(wParam))
       
   284 #define XBUTTON1      0x0001
       
   285 #define XBUTTON2      0x0002
       
   286 #endif
       
   287 #ifndef MK_XBUTTON1
       
   288 #define MK_XBUTTON1         0x0020
       
   289 #define MK_XBUTTON2         0x0040
       
   290 #endif
       
   291 
       
   292 // support for multi-media-keys
       
   293 #ifndef WM_APPCOMMAND
       
   294 #define WM_APPCOMMAND                   0x0319
       
   295 #endif
       
   296 
       
   297 #ifndef FAPPCOMMAND_MOUSE
       
   298 #define FAPPCOMMAND_MOUSE 0x8000
       
   299 #define FAPPCOMMAND_KEY   0
       
   300 #define FAPPCOMMAND_OEM   0x1000
       
   301 #define FAPPCOMMAND_MASK  0xF000
       
   302 #define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
       
   303 #define GET_DEVICE_LPARAM(lParam)     ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK))
       
   304 #define GET_MOUSEORKEY_LPARAM         GET_DEVICE_LPARAM
       
   305 #define GET_FLAGS_LPARAM(lParam)      (LOWORD(lParam))
       
   306 #define GET_KEYSTATE_LPARAM(lParam)   GET_FLAGS_LPARAM(lParam)
       
   307 
       
   308 #define APPCOMMAND_BROWSER_BACKWARD       1
       
   309 #define APPCOMMAND_BROWSER_FORWARD        2
       
   310 #define APPCOMMAND_BROWSER_REFRESH        3
       
   311 #define APPCOMMAND_BROWSER_STOP           4
       
   312 #define APPCOMMAND_BROWSER_SEARCH         5
       
   313 #define APPCOMMAND_BROWSER_FAVORITES      6
       
   314 #define APPCOMMAND_BROWSER_HOME           7
       
   315 #define APPCOMMAND_VOLUME_MUTE            8
       
   316 #define APPCOMMAND_VOLUME_DOWN            9
       
   317 #define APPCOMMAND_VOLUME_UP              10
       
   318 #define APPCOMMAND_MEDIA_NEXTTRACK        11
       
   319 #define APPCOMMAND_MEDIA_PREVIOUSTRACK    12
       
   320 #define APPCOMMAND_MEDIA_STOP             13
       
   321 #define APPCOMMAND_MEDIA_PLAY_PAUSE       14
       
   322 #define APPCOMMAND_LAUNCH_MAIL            15
       
   323 #define APPCOMMAND_LAUNCH_MEDIA_SELECT    16
       
   324 #define APPCOMMAND_LAUNCH_APP1            17
       
   325 #define APPCOMMAND_LAUNCH_APP2            18
       
   326 #define APPCOMMAND_BASS_DOWN              19
       
   327 #define APPCOMMAND_BASS_BOOST             20
       
   328 #define APPCOMMAND_BASS_UP                21
       
   329 #define APPCOMMAND_TREBLE_DOWN            22
       
   330 #define APPCOMMAND_TREBLE_UP              23
       
   331 #endif // FAPPCOMMAND_MOUSE
       
   332 
       
   333 // New commands from Windows XP (some even Sp1)
       
   334 #ifndef APPCOMMAND_MICROPHONE_VOLUME_MUTE
       
   335 #define APPCOMMAND_MICROPHONE_VOLUME_MUTE 24
       
   336 #define APPCOMMAND_MICROPHONE_VOLUME_DOWN 25
       
   337 #define APPCOMMAND_MICROPHONE_VOLUME_UP   26
       
   338 #define APPCOMMAND_HELP                   27
       
   339 #define APPCOMMAND_FIND                   28
       
   340 #define APPCOMMAND_NEW                    29
       
   341 #define APPCOMMAND_OPEN                   30
       
   342 #define APPCOMMAND_CLOSE                  31
       
   343 #define APPCOMMAND_SAVE                   32
       
   344 #define APPCOMMAND_PRINT                  33
       
   345 #define APPCOMMAND_UNDO                   34
       
   346 #define APPCOMMAND_REDO                   35
       
   347 #define APPCOMMAND_COPY                   36
       
   348 #define APPCOMMAND_CUT                    37
       
   349 #define APPCOMMAND_PASTE                  38
       
   350 #define APPCOMMAND_REPLY_TO_MAIL          39
       
   351 #define APPCOMMAND_FORWARD_MAIL           40
       
   352 #define APPCOMMAND_SEND_MAIL              41
       
   353 #define APPCOMMAND_SPELL_CHECK            42
       
   354 #define APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE    43
       
   355 #define APPCOMMAND_MIC_ON_OFF_TOGGLE      44
       
   356 #define APPCOMMAND_CORRECTION_LIST        45
       
   357 #define APPCOMMAND_MEDIA_PLAY             46
       
   358 #define APPCOMMAND_MEDIA_PAUSE            47
       
   359 #define APPCOMMAND_MEDIA_RECORD           48
       
   360 #define APPCOMMAND_MEDIA_FAST_FORWARD     49
       
   361 #define APPCOMMAND_MEDIA_REWIND           50
       
   362 #define APPCOMMAND_MEDIA_CHANNEL_UP       51
       
   363 #define APPCOMMAND_MEDIA_CHANNEL_DOWN     52
       
   364 #endif // APPCOMMAND_MICROPHONE_VOLUME_MUTE
       
   365 
       
   366 #if (_WIN32_WINNT < 0x0400)
       
   367 // This struct is defined in winuser.h if the _WIN32_WINNT >= 0x0400 -- in the
       
   368 // other cases we have to define it on our own.
       
   369 typedef struct tagTRACKMOUSEEVENT {
       
   370     DWORD cbSize;
       
   371     DWORD dwFlags;
       
   372     HWND  hwndTrack;
       
   373     DWORD dwHoverTime;
       
   374 } TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT;
       
   375 #endif
       
   376 #ifndef WM_MOUSELEAVE
       
   377 #define WM_MOUSELEAVE                   0x02A3
       
   378 #endif
       
   379 
       
   380 QT_BEGIN_INCLUDE_NAMESPACE
       
   381 #include "private/qwidget_p.h"
       
   382 QT_END_INCLUDE_NAMESPACE
       
   383 
       
   384 static int translateButtonState(int s, int type, int button);
       
   385 
       
   386 // ##### get rid of this!
       
   387 QRgb qt_colorref2qrgb(COLORREF col)
       
   388 {
       
   389     return qRgb(GetRValue(col),GetGValue(col),GetBValue(col));
       
   390 }
       
   391 
       
   392 
       
   393 /*****************************************************************************
       
   394   Internal variables and functions
       
   395  *****************************************************************************/
       
   396 
       
   397 static HWND         curWin                = 0;                // current window
       
   398 static HDC         displayDC        = 0;                // display device context
       
   399 
       
   400 // Session management
       
   401 static bool        sm_blockUserInput    = false;
       
   402 static bool        sm_smActive             = false;
       
   403 extern QSessionManager* qt_session_manager_self;
       
   404 static bool        sm_cancel;
       
   405 
       
   406 static bool replayPopupMouseEvent = false; // replay handling when popups close
       
   407 
       
   408 // ignore the next release event if return from a modal widget
       
   409 Q_GUI_EXPORT bool qt_win_ignoreNextMouseReleaseEvent = false;
       
   410 
       
   411 
       
   412 #if defined(QT_DEBUG)
       
   413 static bool        appNoGrab        = false;        // mouse/keyboard grabbing
       
   414 #endif
       
   415 
       
   416 static bool        app_do_modal           = false;        // modal mode
       
   417 extern QWidgetList *qt_modal_stack;
       
   418 extern QDesktopWidget *qt_desktopWidget;
       
   419 static QPointer<QWidget> popupButtonFocus;
       
   420 static bool        qt_try_modal(QWidget *, MSG *, int& ret);
       
   421 
       
   422 QWidget               *qt_button_down = 0;                // widget got last button-down
       
   423 QPointer<QWidget> qt_last_mouse_receiver = 0;
       
   424 
       
   425 static HWND        autoCaptureWnd = 0;
       
   426 static HWND        imeParentWnd = 0;
       
   427 static void        setAutoCapture(HWND);                // automatic capture
       
   428 static void        releaseAutoCapture();
       
   429 
       
   430 static void     unregWinClasses();
       
   431 
       
   432 extern QCursor *qt_grab_cursor();
       
   433 
       
   434 #if defined(Q_WS_WIN)
       
   435 #define __export
       
   436 #endif
       
   437 
       
   438 extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
       
   439 
       
   440 class QETWidget : public QWidget                // event translator widget
       
   441 {
       
   442 public:
       
   443     QWExtra    *xtra() { return d_func()->extraData(); }
       
   444     QTLWExtra  *topData() { return d_func()->topData(); }
       
   445     QTLWExtra  *maybeTopData() { return d_func()->maybeTopData(); }
       
   446     void syncBackingStore(const QRegion &rgn) { d_func()->syncBackingStore(rgn); }
       
   447     void syncBackingStore() { d_func()->syncBackingStore(); }
       
   448     QWidgetData *dataPtr() { return data; }
       
   449     QWidgetPrivate *dptr() { return d_func(); }
       
   450     QRect frameStrut() const { return d_func()->frameStrut(); }
       
   451     bool        winEvent(MSG *m, long *r)        { return QWidget::winEvent(m, r); }
       
   452     void        markFrameStrutDirty()        { data->fstrut_dirty = 1; }
       
   453     bool        translateMouseEvent(const MSG &msg);
       
   454     bool        translateWheelEvent(const MSG &msg);
       
   455     bool        translatePaintEvent(const MSG &msg);
       
   456     bool        translateConfigEvent(const MSG &msg);
       
   457     bool        translateCloseEvent(const MSG &msg);
       
   458     bool        translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets);
       
   459     bool        translateGestureEvent(const MSG &msg, const GESTUREINFO &gi);
       
   460     void        repolishStyle(QStyle &style);
       
   461     inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); }
       
   462     inline void hideChildren(bool spontaneous) { d_func()->hideChildren(spontaneous); }
       
   463     inline uint testWindowState(uint teststate){ return dataPtr()->window_state & teststate; }
       
   464     inline void setWindowTitle_helper(const QString &title) { d_func()->setWindowTitle_helper(title); }
       
   465     inline void forceUpdate() {
       
   466         QTLWExtra *tlwExtra = window()->d_func()->maybeTopData();
       
   467         if (tlwExtra && tlwExtra->backingStore)
       
   468             tlwExtra->backingStore->markDirty(rect(), this, true, true);
       
   469     }
       
   470 };
       
   471 
       
   472 // need to get default font?
       
   473 extern bool qt_app_has_font;
       
   474 
       
   475 extern QFont qt_LOGFONTtoQFont(LOGFONT& lf,bool scale);
       
   476 
       
   477 static void qt_set_windows_color_resources()
       
   478 {
       
   479     // Do the color settings
       
   480     QPalette pal;
       
   481     pal.setColor(QPalette::WindowText,
       
   482                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOWTEXT))));
       
   483     pal.setColor(QPalette::Button,
       
   484                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNFACE))));
       
   485     pal.setColor(QPalette::Light,
       
   486                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNHIGHLIGHT))));
       
   487     pal.setColor(QPalette::Dark,
       
   488                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNSHADOW))));
       
   489     pal.setColor(QPalette::Mid, pal.button().color().darker(150));
       
   490     pal.setColor(QPalette::Text,
       
   491                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOWTEXT))));
       
   492     pal.setColor(QPalette::BrightText,
       
   493                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNHIGHLIGHT))));
       
   494     pal.setColor(QPalette::Base,
       
   495                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_WINDOW))));
       
   496     pal.setColor(QPalette::Window,
       
   497                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNFACE))));
       
   498     pal.setColor(QPalette::ButtonText,
       
   499                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_BTNTEXT))));
       
   500     pal.setColor(QPalette::Midlight,
       
   501                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_3DLIGHT))));
       
   502     pal.setColor(QPalette::Shadow,
       
   503                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_3DDKSHADOW))));
       
   504     pal.setColor(QPalette::Highlight,
       
   505                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHT))));
       
   506     pal.setColor(QPalette::HighlightedText,
       
   507                  QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHTTEXT))));
       
   508 
       
   509 #if defined(Q_WS_WINCE)
       
   510     // ### hardcoded until I find out how to get it from the system settings.
       
   511     pal.setColor(QPalette::LinkVisited, pal.highlight().color().dark(150));
       
   512     pal.setColor(QPalette::Link, pal.highlight().color().light(130));
       
   513     // Background == Base on Windows CE
       
   514     if (qt_wince_is_smartphone() || qt_wince_is_pocket_pc())
       
   515       pal.setColor(QPalette::Background, pal.base().color());
       
   516 #else
       
   517     pal.setColor(QPalette::Link, Qt::blue);
       
   518     pal.setColor(QPalette::LinkVisited, Qt::magenta);
       
   519 #endif
       
   520 
       
   521 
       
   522 
       
   523     pal.setColor(QPalette::Inactive, QPalette::Button, pal.button().color());
       
   524     pal.setColor(QPalette::Inactive, QPalette::Window, pal.background().color());
       
   525     pal.setColor(QPalette::Inactive, QPalette::Light, pal.light().color());
       
   526     pal.setColor(QPalette::Inactive, QPalette::Dark, pal.dark().color());
       
   527 
       
   528     if (pal.midlight() == pal.button())
       
   529         pal.setColor(QPalette::Midlight, pal.button().color().lighter(110));
       
   530     if (pal.background() != pal.base()) {
       
   531         pal.setColor(QPalette::Inactive, QPalette::Highlight, pal.color(QPalette::Inactive, QPalette::Window));
       
   532         pal.setColor(QPalette::Inactive, QPalette::HighlightedText, pal.color(QPalette::Inactive, QPalette::Text));
       
   533     }
       
   534 
       
   535     const QColor bg = pal.background().color();
       
   536     const QColor fg = pal.foreground().color(), btn = pal.button().color();
       
   537     QColor disabled((fg.red()+btn.red())/2,(fg.green()+btn.green())/2,
       
   538                      (fg.blue()+btn.blue())/2);
       
   539     pal.setColorGroup(QPalette::Disabled, pal.foreground(), pal.button(), pal.light(),
       
   540         pal.dark(), pal.mid(), pal.text(), pal.brightText(), pal.base(), pal.background() );
       
   541     pal.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
       
   542     pal.setColor(QPalette::Disabled, QPalette::Text, disabled);
       
   543     pal.setColor(QPalette::Disabled, QPalette::ButtonText, disabled);
       
   544     pal.setColor(QPalette::Disabled, QPalette::Highlight,
       
   545                   QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHT))));
       
   546     pal.setColor(QPalette::Disabled, QPalette::HighlightedText,
       
   547                   QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHTTEXT))));
       
   548     pal.setColor(QPalette::Disabled, QPalette::Base, bg);
       
   549 
       
   550     QApplicationPrivate::setSystemPalette(pal);
       
   551 
       
   552     QApplicationPrivate::initializeWidgetPaletteHash();
       
   553 
       
   554     QColor ttip(qt_colorref2qrgb(GetSysColor(COLOR_INFOBK)));
       
   555 
       
   556     QColor ttipText(qt_colorref2qrgb(GetSysColor(COLOR_INFOTEXT)));
       
   557     {
       
   558 #ifndef QT_NO_TOOLTIP
       
   559         QPalette tiplabel(pal);
       
   560         tiplabel.setColor(QPalette::All, QPalette::Button, ttip);
       
   561         tiplabel.setColor(QPalette::All, QPalette::Window, ttip);
       
   562         tiplabel.setColor(QPalette::All, QPalette::Text, ttipText);
       
   563         tiplabel.setColor(QPalette::All, QPalette::WindowText, ttipText);
       
   564         tiplabel.setColor(QPalette::All, QPalette::ButtonText, ttipText);
       
   565         tiplabel.setColor(QPalette::All, QPalette::Button, ttip);
       
   566         tiplabel.setColor(QPalette::All, QPalette::Window, ttip);
       
   567         tiplabel.setColor(QPalette::All, QPalette::Text, ttipText);
       
   568         tiplabel.setColor(QPalette::All, QPalette::WindowText, ttipText);
       
   569         tiplabel.setColor(QPalette::All, QPalette::ButtonText, ttipText);
       
   570         const QColor fg = tiplabel.foreground().color(), btn = tiplabel.button().color();
       
   571         QColor disabled((fg.red()+btn.red())/2,(fg.green()+btn.green())/2,
       
   572                          (fg.blue()+btn.blue())/2);
       
   573         tiplabel.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
       
   574         tiplabel.setColor(QPalette::Disabled, QPalette::Text, disabled);
       
   575         tiplabel.setColor(QPalette::Disabled, QPalette::Base, Qt::white);
       
   576         tiplabel.setColor(QPalette::Disabled, QPalette::BrightText, Qt::white);
       
   577         QToolTip::setPalette(tiplabel);
       
   578 #endif //QT_NO_TOOLTIP
       
   579     }
       
   580 }
       
   581 
       
   582 static void qt_set_windows_font_resources()
       
   583 {
       
   584 #ifndef Q_WS_WINCE
       
   585     NONCLIENTMETRICS ncm;
       
   586     ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
       
   587     SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
       
   588 
       
   589     QFont menuFont = qt_LOGFONTtoQFont(ncm.lfMenuFont, true);
       
   590     QFont messageFont = qt_LOGFONTtoQFont(ncm.lfMessageFont, true);
       
   591     QFont statusFont = qt_LOGFONTtoQFont(ncm.lfStatusFont, true);
       
   592     QFont titleFont = qt_LOGFONTtoQFont(ncm.lfCaptionFont, true);
       
   593 
       
   594     LOGFONT lfIconTitleFont;
       
   595     SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
       
   596     QFont iconTitleFont = qt_LOGFONTtoQFont(lfIconTitleFont, true);
       
   597 
       
   598     QApplication::setFont(menuFont, "QMenu");
       
   599     QApplication::setFont(menuFont, "QMenuBar");
       
   600     QApplication::setFont(messageFont, "QMessageBox");
       
   601     QApplication::setFont(statusFont, "QTipLabel");
       
   602     QApplication::setFont(statusFont, "QStatusBar");
       
   603     QApplication::setFont(titleFont, "Q3TitleBar");
       
   604     QApplication::setFont(titleFont, "QWorkspaceTitleBar");
       
   605     QApplication::setFont(iconTitleFont, "QAbstractItemView");
       
   606     QApplication::setFont(iconTitleFont, "QDockWidgetTitle");
       
   607 
       
   608 #else
       
   609     LOGFONT lf;
       
   610     HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT);
       
   611     GetObject(stockFont, sizeof(lf), &lf);
       
   612     QFont systemFont = qt_LOGFONTtoQFont(lf, true);
       
   613     QApplicationPrivate::setSystemFont(systemFont);
       
   614     QFont smallerFont = systemFont;
       
   615     if (qt_wince_is_mobile()) {
       
   616         smallerFont.setPointSize(systemFont.pointSize()-1);
       
   617         QApplication::setFont(smallerFont, "QTabBar");
       
   618     }
       
   619 #endif// Q_WS_WINCE
       
   620 }
       
   621 
       
   622 static void qt_win_read_cleartype_settings()
       
   623 {
       
   624     UINT result = 0;
       
   625 #ifdef Q_OS_WINCE
       
   626     if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &result, 0))
       
   627         qt_cleartype_enabled = result;
       
   628 #else
       
   629     if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0))
       
   630         qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE);
       
   631 #endif
       
   632 }
       
   633 
       
   634 
       
   635 static void qt_set_windows_resources()
       
   636 {
       
   637     if (QApplication::type() != QApplication::Tty)
       
   638         (void) QApplication::style(); // trigger creation of application style
       
   639     qt_set_windows_font_resources();
       
   640     qt_set_windows_color_resources();
       
   641 }
       
   642 
       
   643 void QApplicationPrivate::initializeWidgetPaletteHash()
       
   644 {
       
   645     QPalette pal = *QApplicationPrivate::sys_pal;
       
   646     QColor menuCol(qt_colorref2qrgb(GetSysColor(COLOR_MENU)));
       
   647     QColor menuText(qt_colorref2qrgb(GetSysColor(COLOR_MENUTEXT)));
       
   648     BOOL isFlat = false;
       
   649     if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
       
   650         && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
       
   651         SystemParametersInfo(SPI_GETFLATMENU, 0, &isFlat, 0);
       
   652     QPalette menu(pal);
       
   653     // we might need a special color group for the menu.
       
   654     menu.setColor(QPalette::Active, QPalette::Button, menuCol);
       
   655     menu.setColor(QPalette::Active, QPalette::Text, menuText);
       
   656     menu.setColor(QPalette::Active, QPalette::WindowText, menuText);
       
   657     menu.setColor(QPalette::Active, QPalette::ButtonText, menuText);
       
   658     const QColor fg = menu.foreground().color(), btn = menu.button().color();
       
   659     QColor disabled(qt_colorref2qrgb(GetSysColor(COLOR_GRAYTEXT)));
       
   660     menu.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
       
   661     menu.setColor(QPalette::Disabled, QPalette::Text, disabled);
       
   662     menu.setColor(QPalette::Disabled, QPalette::Highlight,
       
   663                     QColor(qt_colorref2qrgb(GetSysColor(
       
   664                                             (QSysInfo::WindowsVersion >= QSysInfo::WV_XP
       
   665                                             && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)
       
   666                                             && isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT))));
       
   667     menu.setColor(QPalette::Disabled, QPalette::HighlightedText, disabled);
       
   668     menu.setColor(QPalette::Disabled, QPalette::Button,
       
   669                     menu.color(QPalette::Active, QPalette::Button));
       
   670     menu.setColor(QPalette::Inactive, QPalette::Button,
       
   671                     menu.color(QPalette::Active, QPalette::Button));
       
   672     menu.setColor(QPalette::Inactive, QPalette::Text,
       
   673                     menu.color(QPalette::Active, QPalette::Text));
       
   674     menu.setColor(QPalette::Inactive, QPalette::WindowText,
       
   675                     menu.color(QPalette::Active, QPalette::WindowText));
       
   676     menu.setColor(QPalette::Inactive, QPalette::ButtonText,
       
   677                     menu.color(QPalette::Active, QPalette::ButtonText));
       
   678     menu.setColor(QPalette::Inactive, QPalette::Highlight,
       
   679                     menu.color(QPalette::Active, QPalette::Highlight));
       
   680     menu.setColor(QPalette::Inactive, QPalette::HighlightedText,
       
   681                     menu.color(QPalette::Active, QPalette::HighlightedText));
       
   682     menu.setColor(QPalette::Inactive, QPalette::ButtonText,
       
   683                     pal.color(QPalette::Inactive, QPalette::Dark));
       
   684     QApplication::setPalette(menu, "QMenu");
       
   685 
       
   686     if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
       
   687         && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) && isFlat) {
       
   688         QColor menubar(qt_colorref2qrgb(GetSysColor(COLOR_MENUBAR)));
       
   689         menu.setColor(QPalette::Active, QPalette::Button, menubar);
       
   690         menu.setColor(QPalette::Disabled, QPalette::Button, menubar);
       
   691         menu.setColor(QPalette::Inactive, QPalette::Button, menubar);
       
   692     }
       
   693     QApplication::setPalette(menu, "QMenuBar");
       
   694 }
       
   695 
       
   696 /*****************************************************************************
       
   697   qt_init() - initializes Qt for Windows
       
   698  *****************************************************************************/
       
   699 
       
   700 typedef BOOL (WINAPI *PtrSetProcessDPIAware) (VOID);
       
   701 static PtrSetProcessDPIAware ptrSetProcessDPIAware = 0;
       
   702 PtrUpdateLayeredWindow ptrUpdateLayeredWindow = 0;
       
   703 PtrUpdateLayeredWindowIndirect ptrUpdateLayeredWindowIndirect = 0;
       
   704 static BOOL WINAPI qt_updateLayeredWindowIndirect(HWND hwnd, const Q_UPDATELAYEREDWINDOWINFO *info)
       
   705 {
       
   706     return (*ptrUpdateLayeredWindow)(hwnd, info->hdcDst, info->pptDst, info->psize, info->hdcSrc,
       
   707                                      info->pptSrc, info->crKey, info->pblend, info->dwFlags);
       
   708 }
       
   709 
       
   710 void qt_init(QApplicationPrivate *priv, int)
       
   711 {
       
   712 
       
   713     int argc = priv->argc;
       
   714     char **argv = priv->argv;
       
   715     int i, j;
       
   716 
       
   717   // Get command line params
       
   718 
       
   719     j = argc ? 1 : 0;
       
   720     for (i=1; i<argc; i++) {
       
   721         if (argv[i] && *argv[i] != '-') {
       
   722             argv[j++] = argv[i];
       
   723             continue;
       
   724         }
       
   725 #if defined(QT_DEBUG)
       
   726         if (qstrcmp(argv[i], "-nograb") == 0)
       
   727             appNoGrab = !appNoGrab;
       
   728         else
       
   729 #endif // QT_DEBUG
       
   730             argv[j++] = argv[i];
       
   731     }
       
   732     if(j < priv->argc) {
       
   733         priv->argv[j] = 0;
       
   734         priv->argc = j;
       
   735     }
       
   736 
       
   737 #ifndef Q_WS_WINCE
       
   738     // No message boxes but important ones
       
   739     SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
       
   740 #endif
       
   741 
       
   742 #ifndef Q_WS_WINCE
       
   743     // Initialize OLE/COM
       
   744     //         S_OK means success and S_FALSE means that it has already
       
   745     //         been initialized
       
   746     HRESULT r;
       
   747     r = OleInitialize(0);
       
   748     if (r != S_OK && r != S_FALSE) {
       
   749         qWarning("Qt: Could not initialize OLE (error %x)", (unsigned int)r);
       
   750     }
       
   751 #endif
       
   752 
       
   753     // Misc. initialization
       
   754 #if defined(QT_DEBUG) && !defined(Q_WS_WINCE)
       
   755     GdiSetBatchLimit(1);
       
   756 #endif
       
   757 
       
   758     // initialize key mapper
       
   759     QKeyMapper::changeKeyboard();
       
   760 
       
   761     QColormap::initialize();
       
   762     QFont::initialize();
       
   763 #ifndef QT_NO_CURSOR
       
   764     QCursorData::initialize();
       
   765 #endif
       
   766     qApp->setObjectName(priv->appName());
       
   767 
       
   768     // default font
       
   769 #ifndef Q_WS_WINCE
       
   770     HGDIOBJ stockFont = GetStockObject(DEFAULT_GUI_FONT);
       
   771 #else
       
   772     HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT);
       
   773 #endif
       
   774 
       
   775     LOGFONT lf;
       
   776     GetObject(stockFont, sizeof(lf), &lf);
       
   777     QFont systemFont = qt_LOGFONTtoQFont(lf, true);
       
   778 
       
   779 #ifndef Q_WS_WINCE
       
   780     if (systemFont.family() == QLatin1String("MS Shell Dlg")) {
       
   781         systemFont.setFamily(QLatin1String("MS Shell Dlg 2"));
       
   782     }
       
   783 #endif
       
   784 
       
   785     QApplicationPrivate::setSystemFont(systemFont);
       
   786 
       
   787     // QFont::locale_init();  ### Uncomment when it does something on Windows
       
   788 
       
   789     if (QApplication::desktopSettingsAware())
       
   790         qt_set_windows_resources();
       
   791 
       
   792     initWinTabFunctions();
       
   793     QApplicationPrivate::inputContext = new QWinInputContext(0);
       
   794 
       
   795     // Read the initial cleartype settings...
       
   796     qt_win_read_cleartype_settings();
       
   797     qt_win_owndc_required = false;
       
   798 
       
   799     extern void qt_win_initialize_directdraw();
       
   800     qt_win_initialize_directdraw();
       
   801 
       
   802 #ifndef Q_OS_WINCE
       
   803     ptrUpdateLayeredWindowIndirect =
       
   804         (PtrUpdateLayeredWindowIndirect) QLibrary::resolve(QLatin1String("user32"),
       
   805                                                            "UpdateLayeredWindowIndirect");
       
   806     ptrUpdateLayeredWindow =
       
   807         (PtrUpdateLayeredWindow) QLibrary::resolve(QLatin1String("user32"),
       
   808                                                    "UpdateLayeredWindow");
       
   809 
       
   810     if (ptrUpdateLayeredWindow && !ptrUpdateLayeredWindowIndirect)
       
   811         ptrUpdateLayeredWindowIndirect = qt_updateLayeredWindowIndirect;
       
   812 
       
   813     // Notify Vista and Windows 7 that we support highter DPI settings
       
   814     ptrSetProcessDPIAware = (PtrSetProcessDPIAware)
       
   815         QLibrary::resolve(QLatin1String("user32"), "SetProcessDPIAware");
       
   816     if (ptrSetProcessDPIAware)
       
   817         ptrSetProcessDPIAware();
       
   818 #endif
       
   819 
       
   820     priv->GetGestureInfo = 0;
       
   821     priv->GetGestureExtraArgs = 0;
       
   822     priv->CloseGestureInfoHandle = 0;
       
   823     priv->SetGestureConfig = 0;
       
   824     priv->GetGestureConfig = 0;
       
   825     priv->BeginPanningFeedback = 0;
       
   826     priv->UpdatePanningFeedback = 0;
       
   827     priv->EndPanningFeedback = 0;
       
   828 
       
   829 #if defined(Q_WS_WINCE_WM) && defined(QT_WINCE_GESTURES)
       
   830     priv->GetGestureInfo = (PtrGetGestureInfo) &TKGetGestureInfo;
       
   831     priv->GetGestureExtraArgs = (PtrGetGestureExtraArgs) &TKGetGestureExtraArguments;
       
   832 #elif !defined(Q_WS_WINCE)
       
   833     priv->GetGestureInfo =
       
   834             (PtrGetGestureInfo)QLibrary::resolve(QLatin1String("user32"),
       
   835                                                  "GetGestureInfo");
       
   836     priv->GetGestureExtraArgs =
       
   837             (PtrGetGestureExtraArgs)QLibrary::resolve(QLatin1String("user32"),
       
   838                                                       "GetGestureExtraArgs");
       
   839     priv->CloseGestureInfoHandle =
       
   840             (PtrCloseGestureInfoHandle)QLibrary::resolve(QLatin1String("user32"),
       
   841                                                          "CloseGestureInfoHandle");
       
   842     priv->SetGestureConfig =
       
   843             (PtrSetGestureConfig)QLibrary::resolve(QLatin1String("user32"),
       
   844                                                    "SetGestureConfig");
       
   845     priv->GetGestureConfig =
       
   846             (PtrGetGestureConfig)QLibrary::resolve(QLatin1String("user32"),
       
   847                                                    "GetGestureConfig");
       
   848     priv->BeginPanningFeedback =
       
   849             (PtrBeginPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"),
       
   850                                                        "BeginPanningFeedback");
       
   851     priv->UpdatePanningFeedback =
       
   852             (PtrUpdatePanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"),
       
   853                                                         "UpdatePanningFeedback");
       
   854     priv->EndPanningFeedback =
       
   855         (PtrEndPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"),
       
   856                                                    "EndPanningFeedback");
       
   857 #endif
       
   858 }
       
   859 
       
   860 /*****************************************************************************
       
   861   qt_cleanup() - cleans up when the application is finished
       
   862  *****************************************************************************/
       
   863 
       
   864 void qt_cleanup()
       
   865 {
       
   866     unregWinClasses();
       
   867     QPixmapCache::clear();
       
   868 
       
   869 #ifndef QT_NO_CURSOR
       
   870     QCursorData::cleanup();
       
   871 #endif
       
   872     QFont::cleanup();
       
   873     QColormap::cleanup();
       
   874     if (displayDC) {
       
   875         ReleaseDC(0, displayDC);
       
   876         displayDC = 0;
       
   877     }
       
   878 
       
   879     delete QApplicationPrivate::inputContext;
       
   880     QApplicationPrivate::inputContext = 0;
       
   881 
       
   882 #ifndef Q_WS_WINCE
       
   883   // Deinitialize OLE/COM
       
   884     OleUninitialize();
       
   885 #endif
       
   886 }
       
   887 
       
   888 
       
   889 /*****************************************************************************
       
   890   Platform specific global and internal functions
       
   891  *****************************************************************************/
       
   892 
       
   893 Q_GUI_EXPORT HDC qt_win_display_dc()                        // get display DC
       
   894 {
       
   895     Q_ASSERT(qApp && qApp->thread() == QThread::currentThread());
       
   896     if (!displayDC)
       
   897         displayDC = GetDC(0);
       
   898     return displayDC;
       
   899 }
       
   900 
       
   901 bool qt_nograb()                                // application no-grab option
       
   902 {
       
   903 #if defined(QT_DEBUG)
       
   904     return appNoGrab;
       
   905 #else
       
   906     return false;
       
   907 #endif
       
   908 }
       
   909 
       
   910 typedef QHash<QString, int> WinClassNameHash;
       
   911 Q_GLOBAL_STATIC(WinClassNameHash, winclassNames)
       
   912 
       
   913 const QString qt_reg_winclass(QWidget *w)        // register window class
       
   914 {
       
   915     int flags = w->windowFlags();
       
   916     int type = flags & Qt::WindowType_Mask;
       
   917 
       
   918     uint style;
       
   919     bool icon;
       
   920     QString cname;
       
   921     if (flags & Qt::MSWindowsOwnDC) {
       
   922         cname = QLatin1String("QWidgetOwnDC");
       
   923         style = CS_DBLCLKS;
       
   924 #ifndef Q_WS_WINCE
       
   925         style |= CS_OWNDC;
       
   926 #endif
       
   927         icon  = true;
       
   928     } else if (type == Qt::Tool || type == Qt::ToolTip){
       
   929         style = CS_DBLCLKS;
       
   930         if (w->inherits("QTipLabel") || w->inherits("QAlphaWidget")) {
       
   931             if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
       
   932                 && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) {
       
   933                 style |= CS_DROPSHADOW;
       
   934             }
       
   935             cname = QLatin1String("QToolTip");
       
   936         } else {
       
   937             cname = QLatin1String("QTool");
       
   938         }
       
   939 #ifndef Q_WS_WINCE
       
   940         style |= CS_SAVEBITS;
       
   941 #endif
       
   942         icon = false;
       
   943     } else if (type == Qt::Popup) {
       
   944         cname = QLatin1String("QPopup");
       
   945         style = CS_DBLCLKS;
       
   946 #ifndef Q_WS_WINCE
       
   947         style |= CS_SAVEBITS;
       
   948 #endif
       
   949         if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
       
   950             && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
       
   951             style |= CS_DROPSHADOW;
       
   952         icon = false;
       
   953     } else {
       
   954         cname = QLatin1String("QWidget");
       
   955         style = CS_DBLCLKS;
       
   956         icon  = true;
       
   957     }
       
   958 
       
   959 #ifndef Q_WS_WINCE
       
   960     // force CS_OWNDC when the GL graphics system is
       
   961     // used as the default renderer
       
   962     if (qt_win_owndc_required)
       
   963         style |= CS_OWNDC;
       
   964 #endif
       
   965 
       
   966 #ifdef Q_OS_WINCE
       
   967     // We need to register the classes with the
       
   968     // unique ID on WinCE to make sure we can
       
   969     // move the windows to the front when starting
       
   970     // a second instance.
       
   971     wchar_t uniqueAppID[MAX_PATH];
       
   972     GetModuleFileName(0, uniqueAppID, MAX_PATH);
       
   973     cname = QString::number(RegisterWindowMessage(
       
   974               (const wchar_t *) QString::fromWCharArray(uniqueAppID).toLower().replace(QLatin1Char('\\'),
       
   975               QLatin1Char('_')).utf16()));
       
   976 #endif
       
   977 
       
   978     // since multiple Qt versions can be used in one process
       
   979     // each one has to have window class names with a unique name
       
   980     // The first instance gets the unmodified name; if the class
       
   981     // has already been registered by another instance of Qt then
       
   982     // add an instance-specific ID, the address of the window proc.
       
   983     static int classExists = -1;
       
   984 
       
   985     if (classExists == -1) {
       
   986         WNDCLASS wcinfo;
       
   987         classExists = GetClassInfo((HINSTANCE)qWinAppInst(), (wchar_t*)cname.utf16(), &wcinfo);
       
   988         classExists = classExists && wcinfo.lpfnWndProc != QtWndProc;
       
   989     }
       
   990 
       
   991     if (classExists)
       
   992         cname += QString::number((quintptr)QtWndProc);
       
   993 
       
   994     if (winclassNames()->contains(cname))        // already registered in our list
       
   995         return cname;
       
   996 
       
   997     WNDCLASS wc;
       
   998     wc.style        = style;
       
   999     wc.lpfnWndProc  = (WNDPROC)QtWndProc;
       
  1000     wc.cbClsExtra   = 0;
       
  1001     wc.cbWndExtra   = 0;
       
  1002     wc.hInstance    = qWinAppInst();
       
  1003     if (icon) {
       
  1004         wc.hIcon = (HICON)LoadImage(qWinAppInst(), L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
       
  1005 #ifndef Q_WS_WINCE
       
  1006         if (!wc.hIcon)
       
  1007             wc.hIcon = (HICON)LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
       
  1008 #endif
       
  1009     } else {
       
  1010         wc.hIcon    = 0;
       
  1011     }
       
  1012     wc.hCursor      = 0;
       
  1013 #ifndef Q_WS_WINCE
       
  1014     wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW);
       
  1015 #else
       
  1016     wc.hbrBackground = 0;
       
  1017 #endif
       
  1018     wc.lpszMenuName  = 0;
       
  1019     wc.lpszClassName = (wchar_t*)cname.utf16();
       
  1020 
       
  1021     ATOM atom = RegisterClass(&wc);
       
  1022 
       
  1023 #ifndef QT_NO_DEBUG
       
  1024     if (!atom)
       
  1025         qErrnoWarning("QApplication::regClass: Registering window class failed.");
       
  1026 #else
       
  1027     Q_UNUSED(atom);
       
  1028 #endif
       
  1029 
       
  1030     winclassNames()->insert(cname, 1);
       
  1031     return cname;
       
  1032 }
       
  1033 
       
  1034 Q_GUI_EXPORT const QString qt_getRegisteredWndClass()
       
  1035 {
       
  1036     QWidget w;
       
  1037     return qt_reg_winclass(&w);
       
  1038 }
       
  1039 
       
  1040 static void unregWinClasses()
       
  1041 {
       
  1042     WinClassNameHash *hash = winclassNames();
       
  1043     QHash<QString, int>::ConstIterator it = hash->constBegin();
       
  1044     while (it != hash->constEnd()) {
       
  1045         UnregisterClass((wchar_t*)it.key().utf16(), qWinAppInst());
       
  1046         ++it;
       
  1047     }
       
  1048     hash->clear();
       
  1049 }
       
  1050 
       
  1051 
       
  1052 /*****************************************************************************
       
  1053   Safe configuration (move,resize,setGeometry) mechanism to avoid
       
  1054   recursion when processing messages.
       
  1055  *****************************************************************************/
       
  1056 
       
  1057 struct QWinConfigRequest {
       
  1058     WId         id;                                        // widget to be configured
       
  1059     int         req;                                        // 0=move, 1=resize, 2=setGeo
       
  1060     int         x, y, w, h;                                // request parameters
       
  1061 };
       
  1062 
       
  1063 static QList<QWinConfigRequest*> *configRequests = 0;
       
  1064 
       
  1065 void qWinRequestConfig(WId id, int req, int x, int y, int w, int h)
       
  1066 {
       
  1067     if (!configRequests)                        // create queue
       
  1068         configRequests = new QList<QWinConfigRequest*>;
       
  1069     QWinConfigRequest *r = new QWinConfigRequest;
       
  1070     r->id = id;                                        // create new request
       
  1071     r->req = req;
       
  1072     r->x = x;
       
  1073     r->y = y;
       
  1074     r->w = w;
       
  1075     r->h = h;
       
  1076     configRequests->append(r);                // store request in queue
       
  1077 }
       
  1078 
       
  1079 static void qWinProcessConfigRequests()                // perform requests in queue
       
  1080 {
       
  1081     if (!configRequests)
       
  1082         return;
       
  1083     QWinConfigRequest *r;
       
  1084     for (;;) {
       
  1085         if (configRequests->isEmpty())
       
  1086             break;
       
  1087         r = configRequests->takeLast();
       
  1088         QWidget *w = QWidget::find(r->id);
       
  1089         QRect rect(r->x, r->y, r->w, r->h);
       
  1090         int req = r->req;
       
  1091         delete r;
       
  1092 
       
  1093         if ( w ) {                              // widget exists
       
  1094             if (w->testAttribute(Qt::WA_WState_ConfigPending))
       
  1095                 return;                         // biting our tail
       
  1096             if (req == 0)
       
  1097                 w->move(rect.topLeft());
       
  1098             else if (req == 1)
       
  1099                 w->resize(rect.size());
       
  1100             else
       
  1101                 w->setGeometry(rect);
       
  1102         }
       
  1103     }
       
  1104     delete configRequests;
       
  1105     configRequests = 0;
       
  1106 }
       
  1107 
       
  1108 
       
  1109 /*****************************************************************************
       
  1110     GUI event dispatcher
       
  1111  *****************************************************************************/
       
  1112 
       
  1113 class QGuiEventDispatcherWin32 : public QEventDispatcherWin32
       
  1114 {
       
  1115     Q_DECLARE_PRIVATE(QEventDispatcherWin32)
       
  1116 public:
       
  1117     QGuiEventDispatcherWin32(QObject *parent = 0);
       
  1118     bool processEvents(QEventLoop::ProcessEventsFlags flags);
       
  1119 };
       
  1120 
       
  1121 QGuiEventDispatcherWin32::QGuiEventDispatcherWin32(QObject *parent)
       
  1122     : QEventDispatcherWin32(parent)
       
  1123 {
       
  1124     createInternalHwnd();
       
  1125 }
       
  1126 
       
  1127 bool QGuiEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
       
  1128 {
       
  1129     if (!QEventDispatcherWin32::processEvents(flags))
       
  1130         return false;
       
  1131 
       
  1132     if (configRequests)                        // any pending configs?
       
  1133         qWinProcessConfigRequests();
       
  1134 
       
  1135     return true;
       
  1136 }
       
  1137 
       
  1138 void QApplicationPrivate::createEventDispatcher()
       
  1139 {
       
  1140     Q_Q(QApplication);
       
  1141     if (q->type() != QApplication::Tty)
       
  1142         eventDispatcher = new QGuiEventDispatcherWin32(q);
       
  1143     else
       
  1144         eventDispatcher = new QEventDispatcherWin32(q);
       
  1145 }
       
  1146 
       
  1147 /*****************************************************************************
       
  1148   Platform specific QApplication members
       
  1149  *****************************************************************************/
       
  1150 
       
  1151 #ifdef QT3_SUPPORT
       
  1152 void QApplication::setMainWidget(QWidget *mainWidget)
       
  1153 {
       
  1154     QApplicationPrivate::main_widget = mainWidget;
       
  1155     if (QApplicationPrivate::main_widget && windowIcon().isNull()
       
  1156         && QApplicationPrivate::main_widget->testAttribute(Qt::WA_SetWindowIcon))
       
  1157         setWindowIcon(QApplicationPrivate::main_widget->windowIcon());
       
  1158 }
       
  1159 #endif
       
  1160 
       
  1161 #ifndef QT_NO_CURSOR
       
  1162 
       
  1163 /*****************************************************************************
       
  1164   QApplication cursor stack
       
  1165  *****************************************************************************/
       
  1166 
       
  1167 void QApplication::setOverrideCursor(const QCursor &cursor)
       
  1168 {
       
  1169     qApp->d_func()->cursor_list.prepend(cursor);
       
  1170     SetCursor(qApp->d_func()->cursor_list.first().handle());
       
  1171 }
       
  1172 
       
  1173 void QApplication::restoreOverrideCursor()
       
  1174 {
       
  1175     if (qApp->d_func()->cursor_list.isEmpty())
       
  1176         return;
       
  1177     qApp->d_func()->cursor_list.removeFirst();
       
  1178 
       
  1179     if (!qApp->d_func()->cursor_list.isEmpty()) {
       
  1180         SetCursor(qApp->d_func()->cursor_list.first().handle());
       
  1181     } else {
       
  1182         QWidget *w = QWidget::find(curWin);
       
  1183         if (w)
       
  1184             SetCursor(w->cursor().handle());
       
  1185         else
       
  1186             SetCursor(QCursor(Qt::ArrowCursor).handle());
       
  1187     }
       
  1188 }
       
  1189 
       
  1190 #endif
       
  1191 
       
  1192 /*
       
  1193   Internal function called from QWidget::setCursor()
       
  1194    force is true if this function is called from dispatchEnterLeave, it means that the
       
  1195    mouse is actually directly under this widget.
       
  1196 */
       
  1197 
       
  1198 #ifndef QT_NO_CURSOR
       
  1199 void qt_win_set_cursor(QWidget *w, bool force)
       
  1200 {
       
  1201     static QPointer<QWidget> lastUnderMouse = 0;
       
  1202     if (force) {
       
  1203         lastUnderMouse = w;
       
  1204     } else if (w->testAttribute(Qt::WA_WState_Created) && lastUnderMouse
       
  1205                && lastUnderMouse->effectiveWinId() == w->effectiveWinId()) {
       
  1206         w = lastUnderMouse;
       
  1207     }
       
  1208 
       
  1209     if (!curWin && w && w->internalWinId())
       
  1210         return;
       
  1211     QWidget* cW = w && !w->internalWinId() ? w : QWidget::find(curWin);
       
  1212     if (!cW || cW->window() != w->window() ||
       
  1213          !cW->isVisible() || !cW->underMouse() || QApplication::overrideCursor())
       
  1214         return;
       
  1215 
       
  1216     SetCursor(cW->cursor().handle());
       
  1217 }
       
  1218 #endif // QT_NO_CURSOR
       
  1219 
       
  1220 Qt::KeyboardModifiers qt_win_getKeyboardModifiers()
       
  1221 {
       
  1222     Qt::KeyboardModifiers modifiers = Qt::NoModifier;
       
  1223     if (GetKeyState(VK_SHIFT) < 0)
       
  1224         modifiers |= Qt::ShiftModifier;
       
  1225     if (GetKeyState(VK_CONTROL) < 0)
       
  1226         modifiers |= Qt::ControlModifier;
       
  1227     if (GetKeyState(VK_MENU) < 0)
       
  1228         modifiers |= Qt::AltModifier;
       
  1229     return modifiers;
       
  1230 }
       
  1231 
       
  1232 /*****************************************************************************
       
  1233   Routines to find a Qt widget from a screen position
       
  1234  *****************************************************************************/
       
  1235 
       
  1236 QWidget *QApplication::topLevelAt(const QPoint &pos)
       
  1237 {
       
  1238     POINT p;
       
  1239     HWND  win;
       
  1240     QWidget *w;
       
  1241     p.x = pos.x();
       
  1242     p.y = pos.y();
       
  1243     win = WindowFromPoint(p);
       
  1244     if (!win)
       
  1245         return 0;
       
  1246 
       
  1247     w = QWidget::find(win);
       
  1248     while (!w && win) {
       
  1249         win = GetParent(win);
       
  1250         w = QWidget::find(win);
       
  1251     }
       
  1252     return w ? w->window() : 0;
       
  1253 }
       
  1254 
       
  1255 void QApplication::beep()
       
  1256 {
       
  1257     MessageBeep(MB_OK);
       
  1258 }
       
  1259 
       
  1260 static void alert_widget(QWidget *widget, int duration)
       
  1261 {
       
  1262 #ifdef Q_OS_WINCE
       
  1263     Q_UNUSED(widget);
       
  1264     Q_UNUSED(duration);
       
  1265 #else
       
  1266     bool stopFlash = duration < 0;
       
  1267 
       
  1268     if (widget && (!widget->isActiveWindow() || stopFlash)) {
       
  1269         DWORD timeOut = GetCaretBlinkTime();
       
  1270         if (timeOut <= 0)
       
  1271             timeOut = 250;
       
  1272 
       
  1273         UINT flashCount;
       
  1274         if (duration == 0)
       
  1275             flashCount = 10;
       
  1276         else
       
  1277             flashCount = duration/timeOut;
       
  1278 
       
  1279         FLASHWINFO info;
       
  1280         info.cbSize = sizeof(info);
       
  1281         info.hwnd = widget->window()->winId();
       
  1282         info.dwFlags = stopFlash ? FLASHW_STOP : FLASHW_TRAY;
       
  1283         info.dwTimeout = stopFlash ? 0 : timeOut;
       
  1284         info.uCount = stopFlash ? 0 : flashCount;
       
  1285 
       
  1286         FlashWindowEx(&info);
       
  1287     }
       
  1288 #endif
       
  1289 }
       
  1290 
       
  1291 void QApplication::alert(QWidget *widget, int duration)
       
  1292 {
       
  1293     if (!QApplicationPrivate::checkInstance("alert"))
       
  1294         return;
       
  1295 
       
  1296     if (widget) {
       
  1297         alert_widget(widget, duration);
       
  1298     } else {
       
  1299         const QWidgetList toplevels(topLevelWidgets());
       
  1300         for (int i = 0; i < toplevels.count(); ++i) {
       
  1301             QWidget *topLevel = toplevels.at(i);
       
  1302             alert_widget(topLevel, duration);
       
  1303         }
       
  1304     }
       
  1305 }
       
  1306 
       
  1307 QString QApplicationPrivate::appName() const
       
  1308 {
       
  1309     return QCoreApplicationPrivate::appName();
       
  1310 }
       
  1311 
       
  1312 
       
  1313 /*****************************************************************************
       
  1314   Main event loop
       
  1315  *****************************************************************************/
       
  1316 
       
  1317 extern uint qGlobalPostedEventsCount();
       
  1318 
       
  1319 void QApplication::winFocus(QWidget *widget, bool gotFocus)
       
  1320 {
       
  1321     if (d_func()->inPopupMode()) // some delayed focus event to ignore
       
  1322         return;
       
  1323     if (gotFocus) {
       
  1324         setActiveWindow(widget);
       
  1325         if (QApplicationPrivate::active_window
       
  1326             && (QApplicationPrivate::active_window->windowType() == Qt::Dialog)) {
       
  1327             // raise the entire application, not just the dialog
       
  1328             QWidget* mw = QApplicationPrivate::active_window;
       
  1329 #ifndef Q_WS_WINCE
       
  1330             while(mw->parentWidget() && (mw->windowType() == Qt::Dialog))
       
  1331                 mw = mw->parentWidget()->window();
       
  1332             if (mw->testAttribute(Qt::WA_WState_Created) && mw != QApplicationPrivate::active_window)
       
  1333                 SetWindowPos(mw->internalWinId(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
       
  1334 #else
       
  1335             // On Desktop Windows, we set the first parent of the dialog on top
       
  1336             // Child windows will be automatically set above again.
       
  1337             // On Windows CE we pass no parent in CreateWindowEx as otherwise
       
  1338             // dialogs get embedded into the parent window. Thus we need to
       
  1339             // manually iterate and reactivate all windows from bottom up.
       
  1340             QList<QWidget*> raiseList;
       
  1341             raiseList.push_back(mw);
       
  1342             while(mw->parentWidget() && (mw->windowType() == Qt::Dialog)) {
       
  1343                 mw = mw->parentWidget()->window();
       
  1344                 raiseList.push_back(mw);
       
  1345             }
       
  1346             while(!raiseList.isEmpty()) {
       
  1347                 mw = raiseList.takeLast();
       
  1348                 if (mw->testAttribute(Qt::WA_WState_Created)) {
       
  1349                     HWND state = HWND_TOP;
       
  1350                     if (mw->windowFlags() & Qt::WindowStaysOnBottomHint)
       
  1351                         state = HWND_BOTTOM;
       
  1352                     else if (mw->windowFlags() & Qt::WindowStaysOnTopHint)
       
  1353                         state = HWND_TOPMOST;
       
  1354                     SetWindowPos(mw->internalWinId(), state, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
       
  1355                 }
       
  1356             }
       
  1357 #endif
       
  1358         }
       
  1359     } else {
       
  1360         setActiveWindow(0);
       
  1361     }
       
  1362 }
       
  1363 
       
  1364 
       
  1365 //
       
  1366 // QtWndProc() receives all messages from the main event loop
       
  1367 //
       
  1368 
       
  1369 static bool inLoop = false;
       
  1370 static int inputcharset = CP_ACP;
       
  1371 
       
  1372 #define RETURN(x) { inLoop=false;return x; }
       
  1373 
       
  1374 static bool qt_is_translatable_mouse_event(UINT message)
       
  1375 {
       
  1376     return (((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) ||
       
  1377                 (message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK))
       
  1378             && message != WM_MOUSEWHEEL
       
  1379             && message != WM_MOUSEHWHEEL)
       
  1380 
       
  1381 #ifndef Q_WS_WINCE
       
  1382             || (message >= WM_NCMOUSEMOVE && message <= WM_NCMBUTTONDBLCLK)
       
  1383 #endif
       
  1384             ;
       
  1385 }
       
  1386 
       
  1387 extern "C"
       
  1388 LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       
  1389 {
       
  1390     bool result = true;
       
  1391     QEvent::Type evt_type = QEvent::None;
       
  1392     QETWidget *widget = 0;
       
  1393 
       
  1394         // there is no need to process pakcets from tablet unless
       
  1395         // it is actually on the tablet, a flag to let us know...
       
  1396         int nPackets;        // the number of packets we get from the queue
       
  1397 
       
  1398     long res = 0;
       
  1399     if (!qApp)                                // unstable app state
       
  1400         RETURN(QWinInputContext::DefWindowProc(hwnd,message,wParam,lParam))
       
  1401 
       
  1402     QScopedLoopLevelCounter loopLevelCounter(QThreadData::get2(qApp->thread()));
       
  1403 
       
  1404 #if 0
       
  1405     // make sure we update widgets also when the user resizes
       
  1406     if (inLoop && qApp->loopLevel())
       
  1407         qApp->sendPostedEvents(0, QEvent::Paint);
       
  1408 #endif
       
  1409 
       
  1410     inLoop = true;
       
  1411 
       
  1412     MSG msg;
       
  1413     msg.hwnd = hwnd;                                // create MSG structure
       
  1414     msg.message = message;                        // time and pt fields ignored
       
  1415     msg.wParam = wParam;
       
  1416     msg.lParam = lParam;
       
  1417     msg.pt.x = GET_X_LPARAM(lParam);
       
  1418     msg.pt.y = GET_Y_LPARAM(lParam);
       
  1419     // If it's a non-client-area message the coords are screen coords, otherwise they are
       
  1420     // client coords.
       
  1421 #ifndef Q_WS_WINCE
       
  1422     if (message < WM_NCMOUSEMOVE || message > WM_NCMBUTTONDBLCLK)
       
  1423 #endif
       
  1424         ClientToScreen(msg.hwnd, &msg.pt);
       
  1425 
       
  1426     /*
       
  1427     // sometimes the autograb is not released, so the clickevent is sent
       
  1428     // to the wrong window. We ignore this for now, because it doesn't
       
  1429     // cause any problems.
       
  1430     if (msg.message == WM_LBUTTONDOWN || msg.message == WM_RBUTTONDOWN || msg.message == WM_MBUTTONDOWN) {
       
  1431         HWND handle = WindowFromPoint(msg.pt);
       
  1432         if (msg.hwnd != handle) {
       
  1433             msg.hwnd = handle;
       
  1434             hwnd = handle;
       
  1435         }
       
  1436     }
       
  1437     */
       
  1438 
       
  1439 #if defined(QT_NON_COMMERCIAL)
       
  1440     QT_NC_WNDPROC
       
  1441 #endif
       
  1442 
       
  1443     // send through app filter
       
  1444     if (qApp->filterEvent(&msg, &res))
       
  1445         return res;
       
  1446 
       
  1447     // close any opened ime candidate window (enabled only on a popup widget)
       
  1448     if (imeParentWnd  && QApplication::activePopupWidget()
       
  1449         && (message == WM_MBUTTONDOWN || message == WM_XBUTTONDOWN
       
  1450         || message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN
       
  1451 #ifndef Q_WS_WINCE
       
  1452         || message == WM_NCMBUTTONDOWN || message == WM_NCLBUTTONDOWN
       
  1453         || message == WM_NCRBUTTONDOWN)) {
       
  1454 #else
       
  1455                                       )) {
       
  1456 #endif
       
  1457             ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0);
       
  1458     }
       
  1459 
       
  1460     switch (message) {
       
  1461 #ifndef Q_WS_WINCE
       
  1462     case WM_QUERYENDSESSION: {
       
  1463         if (sm_smActive) // bogus message from windows
       
  1464             RETURN(true);
       
  1465 
       
  1466         sm_smActive = true;
       
  1467         sm_blockUserInput = true; // prevent user-interaction outside interaction windows
       
  1468         sm_cancel = false;
       
  1469         if (qt_session_manager_self)
       
  1470             qApp->commitData(*qt_session_manager_self);
       
  1471         if (lParam & ENDSESSION_LOGOFF) {
       
  1472             _flushall();
       
  1473         }
       
  1474         RETURN(!sm_cancel);
       
  1475     }
       
  1476     case WM_ENDSESSION: {
       
  1477         sm_smActive = false;
       
  1478         sm_blockUserInput = false;
       
  1479         bool endsession = (bool) wParam;
       
  1480 
       
  1481         // we receive the message for each toplevel window included internal hidden ones,
       
  1482         // but the aboutToQuit signal should be emitted only once.
       
  1483         QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
       
  1484         if (endsession && !qAppPriv->aboutToQuitEmitted) {
       
  1485             qAppPriv->aboutToQuitEmitted = true;
       
  1486             int index = QApplication::staticMetaObject.indexOfSignal("aboutToQuit()");
       
  1487             qApp->qt_metacall(QMetaObject::InvokeMetaMethod, index,0);
       
  1488             // since the process will be killed immediately quit() has no real effect
       
  1489             QApplication::quit();
       
  1490         }
       
  1491 
       
  1492         RETURN(0);
       
  1493     }
       
  1494     case WM_DISPLAYCHANGE:
       
  1495         if (QApplication::type() == QApplication::Tty)
       
  1496             break;
       
  1497         if (qt_desktopWidget) {
       
  1498             qt_desktopWidget->move(GetSystemMetrics(76), GetSystemMetrics(77));
       
  1499             QSize sz(GetSystemMetrics(78), GetSystemMetrics(79));
       
  1500             if (sz == qt_desktopWidget->size()) {
       
  1501                  // a screen resized without changing size of the virtual desktop
       
  1502                 QResizeEvent rs(sz, qt_desktopWidget->size());
       
  1503                 QApplication::sendEvent(qt_desktopWidget, &rs);
       
  1504             } else {
       
  1505                 qt_desktopWidget->resize(sz);
       
  1506             }
       
  1507         }
       
  1508         break;
       
  1509 #endif
       
  1510 
       
  1511     case WM_SETTINGCHANGE:
       
  1512 #ifdef Q_WS_WINCE
       
  1513         // CE SIP hide/show
       
  1514         if (wParam == SPI_SETSIPINFO) {
       
  1515             QResizeEvent re(QSize(0, 0), QSize(0, 0)); // Calculated by QDesktopWidget
       
  1516             QApplication::sendEvent(qt_desktopWidget, &re);
       
  1517             break;
       
  1518         }
       
  1519 #endif
       
  1520         // ignore spurious XP message when user logs in again after locking
       
  1521         if (QApplication::type() == QApplication::Tty)
       
  1522             break;
       
  1523         if (QApplication::desktopSettingsAware() && wParam != SPI_SETWORKAREA) {
       
  1524             widget = (QETWidget*)QWidget::find(hwnd);
       
  1525             if (widget) {
       
  1526                 if (wParam == SPI_SETNONCLIENTMETRICS)
       
  1527                     widget->markFrameStrutDirty();
       
  1528             }
       
  1529         }
       
  1530         else if (qt_desktopWidget && wParam == SPI_SETWORKAREA) {
       
  1531             qt_desktopWidget->move(GetSystemMetrics(76), GetSystemMetrics(77));
       
  1532             QSize sz(GetSystemMetrics(78), GetSystemMetrics(79));
       
  1533             if (sz == qt_desktopWidget->size()) {
       
  1534                  // a screen resized without changing size of the virtual desktop
       
  1535                 QResizeEvent rs(sz, qt_desktopWidget->size());
       
  1536                 QApplication::sendEvent(qt_desktopWidget, &rs);
       
  1537             } else {
       
  1538                 qt_desktopWidget->resize(sz);
       
  1539             }
       
  1540         }
       
  1541 
       
  1542         if (wParam == SPI_SETFONTSMOOTHINGTYPE) {
       
  1543             qt_win_read_cleartype_settings();
       
  1544             foreach (QWidget *w, QApplication::topLevelWidgets()) {
       
  1545                 if (!w->isVisible())
       
  1546                     continue;
       
  1547                 ((QETWidget *) w)->forceUpdate();
       
  1548             }
       
  1549         }
       
  1550 
       
  1551         break;
       
  1552     case WM_SYSCOLORCHANGE:
       
  1553         if (QApplication::type() == QApplication::Tty)
       
  1554             break;
       
  1555         if (QApplication::desktopSettingsAware()) {
       
  1556             widget = (QETWidget*)QWidget::find(hwnd);
       
  1557             if (widget && !widget->parentWidget())
       
  1558                 qt_set_windows_color_resources();
       
  1559         }
       
  1560         break;
       
  1561 
       
  1562     case WM_LBUTTONDOWN:
       
  1563     case WM_MBUTTONDOWN:
       
  1564     case WM_RBUTTONDOWN:
       
  1565     case WM_XBUTTONDOWN:
       
  1566         if (qt_win_ignoreNextMouseReleaseEvent)
       
  1567             qt_win_ignoreNextMouseReleaseEvent = false;
       
  1568         break;
       
  1569 
       
  1570     case WM_LBUTTONUP:
       
  1571     case WM_MBUTTONUP:
       
  1572     case WM_RBUTTONUP:
       
  1573     case WM_XBUTTONUP:
       
  1574         if (qt_win_ignoreNextMouseReleaseEvent) {
       
  1575             qt_win_ignoreNextMouseReleaseEvent = false;
       
  1576             if (qt_button_down && qt_button_down->internalWinId() == autoCaptureWnd) {
       
  1577                 releaseAutoCapture();
       
  1578                 qt_button_down = 0;
       
  1579             }
       
  1580 
       
  1581             RETURN(0);
       
  1582         }
       
  1583         break;
       
  1584 
       
  1585     default:
       
  1586         break;
       
  1587     }
       
  1588 
       
  1589     if (!widget)
       
  1590         widget = (QETWidget*)QWidget::find(hwnd);
       
  1591     if (!widget)                                // don't know this widget
       
  1592         goto do_default;
       
  1593 
       
  1594     if (app_do_modal)        {                        // modal event handling
       
  1595         int ret = 0;
       
  1596         if (!qt_try_modal(widget, &msg, ret))
       
  1597             RETURN(ret);
       
  1598     }
       
  1599 
       
  1600     res = 0;
       
  1601     if (widget->winEvent(&msg, &res))                // send through widget filter
       
  1602         RETURN(res);
       
  1603 
       
  1604     if (qt_is_translatable_mouse_event(message)) {
       
  1605         if (QApplication::activePopupWidget() != 0) { // in popup mode
       
  1606             POINT curPos = msg.pt;
       
  1607             QWidget* w = QApplication::widgetAt(curPos.x, curPos.y);
       
  1608             if (w)
       
  1609                 widget = (QETWidget*)w;
       
  1610         }
       
  1611 
       
  1612         if (!qt_tabletChokeMouse) {
       
  1613             result = widget->translateMouseEvent(msg);        // mouse event
       
  1614 #if defined(Q_WS_WINCE) && !defined(QT_NO_CONTEXTMENU)
       
  1615             if (message == WM_LBUTTONDOWN && widget != QApplication::activePopupWidget()) {
       
  1616                 QWidget* alienWidget = widget;
       
  1617                 if ((alienWidget != QApplication::activePopupWidget()) && (alienWidget->contextMenuPolicy() != Qt::PreventContextMenu)) {
       
  1618                     QPoint pos(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
       
  1619                     QPoint globalPos(msg.pt.x, msg.pt.y);
       
  1620                     // In case we are using Alien, then the widget to
       
  1621                     // send the context menu event is a different one
       
  1622                     if (!alienWidget->testAttribute(Qt::WA_NativeWindow) && !alienWidget->testAttribute(Qt::WA_PaintOnScreen)) {
       
  1623                         alienWidget = QApplication::widgetAt(globalPos);
       
  1624                         if (alienWidget)
       
  1625                             pos = alienWidget->mapFromGlobal(globalPos);
       
  1626                     }
       
  1627                     if (alienWidget) {
       
  1628                         SHRGINFO shrg;
       
  1629                         shrg.cbSize = sizeof(shrg);
       
  1630                         shrg.hwndClient = hwnd;
       
  1631                         shrg.ptDown.x = GET_X_LPARAM(lParam);
       
  1632                         shrg.ptDown.y = GET_Y_LPARAM(lParam);
       
  1633                         shrg.dwFlags = SHRG_RETURNCMD | SHRG_NOANIMATION;
       
  1634                         resolveAygLibs();
       
  1635                         if (ptrRecognizeGesture && (ptrRecognizeGesture(&shrg) == GN_CONTEXTMENU)) {
       
  1636                             if (QApplication::activePopupWidget())
       
  1637                                 QApplication::activePopupWidget()->close();
       
  1638                             QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos);
       
  1639                             result = qt_sendSpontaneousEvent(alienWidget, &e);
       
  1640                         }
       
  1641                     }
       
  1642                 }
       
  1643             }
       
  1644 #endif
       
  1645         } else {
       
  1646             // Sometimes we only get a WM_MOUSEMOVE message
       
  1647             // and sometimes we get both a WM_MOUSEMOVE and
       
  1648             // a WM_LBUTTONDOWN/UP, this creates a spurious mouse
       
  1649             // press/release event, using the PeekMessage
       
  1650             // will help us fix this.  This leaves us with a
       
  1651             // question:
       
  1652             //    This effectively kills using the mouse AND the
       
  1653             //    tablet simultaneously, well creates wacky input.
       
  1654             //    Is this going to be a problem? (probably not)
       
  1655             bool next_is_button = false;
       
  1656             bool is_mouse_move = (message == WM_MOUSEMOVE);
       
  1657             if (is_mouse_move) {
       
  1658                 MSG msg1;
       
  1659                 if (PeekMessage(&msg1, msg.hwnd, WM_MOUSEFIRST,
       
  1660                                 WM_MOUSELAST, PM_NOREMOVE))
       
  1661                     next_is_button = (msg1.message == WM_LBUTTONUP
       
  1662                                        || msg1.message == WM_LBUTTONDOWN);
       
  1663             }
       
  1664             if (!is_mouse_move || (is_mouse_move && !next_is_button))
       
  1665                 qt_tabletChokeMouse = false;
       
  1666         }
       
  1667     } else {
       
  1668         switch (message) {
       
  1669         case WM_TOUCH:
       
  1670             result = QApplicationPrivate::instance()->translateTouchEvent(msg);
       
  1671             break;
       
  1672         case WM_KEYDOWN:                        // keyboard event
       
  1673         case WM_SYSKEYDOWN:
       
  1674             qt_keymapper_private()->updateKeyMap(msg);
       
  1675             // fall-through intended
       
  1676         case WM_KEYUP:
       
  1677         case WM_SYSKEYUP:
       
  1678 #if Q_OS_WINCE_WM
       
  1679         case WM_HOTKEY:
       
  1680             if(HIWORD(msg.lParam) == VK_TBACK) {
       
  1681                 const bool hotKeyDown = !(LOWORD(msg.lParam) & MOD_KEYUP);
       
  1682                 msg.lParam = 0x69 << 16;
       
  1683                 msg.wParam = VK_BACK;
       
  1684                 if (hotKeyDown) {
       
  1685                     msg.message = WM_KEYDOWN;
       
  1686                     qt_keymapper_private()->updateKeyMap(msg);
       
  1687                 } else {
       
  1688                     msg.message = WM_KEYUP;
       
  1689                 }
       
  1690             }
       
  1691             // fall-through intended
       
  1692 #endif
       
  1693         case WM_IME_CHAR:
       
  1694         case WM_IME_KEYDOWN:
       
  1695         case WM_CHAR: {
       
  1696             MSG msg1;
       
  1697             bool anyMsg = PeekMessage(&msg1, msg.hwnd, 0, 0, PM_NOREMOVE);
       
  1698             if (anyMsg && msg1.message == WM_DEADCHAR) {
       
  1699                 result = true; // consume event since there is a dead char next
       
  1700                 break;
       
  1701             }
       
  1702             QWidget *g = QWidget::keyboardGrabber();
       
  1703             if (g && qt_get_tablet_widget() && hwnd == qt_get_tablet_widget()->winId()) {
       
  1704                 // if we get an event for the internal tablet widget,
       
  1705                 // then don't send it to the keyboard grabber, but
       
  1706                 // send it to the widget itself (we don't use it right
       
  1707                 // now, just in case).
       
  1708                 g = 0;
       
  1709             }
       
  1710             if (g)
       
  1711                 widget = (QETWidget*)g;
       
  1712             else if (QApplication::activePopupWidget())
       
  1713                 widget = (QETWidget*)QApplication::activePopupWidget()->focusWidget()
       
  1714                        ? (QETWidget*)QApplication::activePopupWidget()->focusWidget()
       
  1715                        : (QETWidget*)QApplication::activePopupWidget();
       
  1716             else if (QApplication::focusWidget())
       
  1717                 widget = (QETWidget*)QApplication::focusWidget();
       
  1718             else if (!widget || widget->internalWinId() == GetFocus()) // We faked the message to go to exactly that widget.
       
  1719                 widget = (QETWidget*)widget->window();
       
  1720             if (widget->isEnabled())
       
  1721                 result = sm_blockUserInput
       
  1722                             ? true
       
  1723                             : qt_keymapper_private()->translateKeyEvent(widget, msg, g != 0);
       
  1724             break;
       
  1725         }
       
  1726         case WM_SYSCHAR:
       
  1727             result = true;                        // consume event
       
  1728             break;
       
  1729 
       
  1730         case WM_MOUSEWHEEL:
       
  1731         case WM_MOUSEHWHEEL:
       
  1732             result = widget->translateWheelEvent(msg);
       
  1733             break;
       
  1734 
       
  1735         case WM_APPCOMMAND:
       
  1736             {
       
  1737                 uint cmd = GET_APPCOMMAND_LPARAM(lParam);
       
  1738                 uint uDevice = GET_DEVICE_LPARAM(lParam);
       
  1739                 uint dwKeys = GET_KEYSTATE_LPARAM(lParam);
       
  1740 
       
  1741                 int state = translateButtonState(dwKeys, QEvent::KeyPress, 0);
       
  1742 
       
  1743                 switch (uDevice) {
       
  1744                 case FAPPCOMMAND_KEY:
       
  1745                     {
       
  1746                         int key = 0;
       
  1747 
       
  1748                         switch(cmd) {
       
  1749                         case APPCOMMAND_BASS_BOOST:
       
  1750                             key = Qt::Key_BassBoost;
       
  1751                             break;
       
  1752                         case APPCOMMAND_BASS_DOWN:
       
  1753                             key = Qt::Key_BassDown;
       
  1754                             break;
       
  1755                         case APPCOMMAND_BASS_UP:
       
  1756                             key = Qt::Key_BassUp;
       
  1757                             break;
       
  1758                         case APPCOMMAND_TREBLE_DOWN:
       
  1759                             key = Qt::Key_TrebleDown;
       
  1760                             break;
       
  1761                         case APPCOMMAND_TREBLE_UP:
       
  1762                             key = Qt::Key_TrebleUp;
       
  1763                             break;
       
  1764                         case APPCOMMAND_HELP:
       
  1765                             key = Qt::Key_Help;
       
  1766                             break;
       
  1767                         case APPCOMMAND_FIND:
       
  1768                             key = Qt::Key_Search;
       
  1769                             break;
       
  1770                         default:
       
  1771                             break;
       
  1772                         }
       
  1773                         if (key) {
       
  1774                             bool res = false;
       
  1775                             QWidget *g = QWidget::keyboardGrabber();
       
  1776                             if (g)
       
  1777                                 widget = (QETWidget*)g;
       
  1778                             else if (QApplication::focusWidget())
       
  1779                                 widget = (QETWidget*)QApplication::focusWidget();
       
  1780                             else
       
  1781                                 widget = (QETWidget*)widget->window();
       
  1782                             if (widget->isEnabled()) {
       
  1783                                 res = QKeyMapper::sendKeyEvent(widget, g != 0, QEvent::KeyPress, key,
       
  1784                                                                Qt::KeyboardModifier(state),
       
  1785                                                                QString(), false, 0, 0, 0, 0);
       
  1786                             }
       
  1787                             if (res)
       
  1788                                 return true;
       
  1789                         }
       
  1790                     }
       
  1791                     break;
       
  1792 
       
  1793                 default:
       
  1794                     break;
       
  1795                 }
       
  1796 
       
  1797                 result = false;
       
  1798             }
       
  1799             break;
       
  1800 
       
  1801 #ifndef Q_WS_WINCE
       
  1802         case WM_NCHITTEST:
       
  1803             if (widget->isWindow()) {
       
  1804                 QPoint pos = widget->mapFromGlobal(QPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
       
  1805                 // don't show resize-cursors for fixed-size widgets
       
  1806                 QRect fs = widget->frameStrut();
       
  1807                 if (!widget->isMinimized()) {
       
  1808                     if (widget->minimumHeight() == widget->maximumHeight()) {
       
  1809                         if (pos.y() < -(fs.top() - fs.left()))
       
  1810                             return HTCAPTION;
       
  1811                         if (pos.y() >= widget->height())
       
  1812                             return HTBORDER;
       
  1813                     }
       
  1814                     if (widget->minimumWidth() == widget->maximumWidth() && (pos.x() < 0 || pos.x() >= widget->width()))
       
  1815                         return HTBORDER;
       
  1816                 }
       
  1817             }
       
  1818 
       
  1819             result = false;
       
  1820             break;
       
  1821 #endif
       
  1822 
       
  1823         case WM_SYSCOMMAND: {
       
  1824 #ifndef Q_WS_WINCE
       
  1825             bool window_state_change = false;
       
  1826             Qt::WindowStates oldstate = Qt::WindowStates(widget->dataPtr()->window_state);
       
  1827             // MSDN:In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are
       
  1828             // used internally by the system. To obtain the correct result when testing the value of
       
  1829             // wParam, an application must combine the value 0xFFF0 with the wParam value by using
       
  1830             // the bitwise AND operator.
       
  1831             switch(0xfff0 & wParam) {
       
  1832             case SC_CONTEXTHELP:
       
  1833 #ifndef QT_NO_WHATSTHIS
       
  1834                 QWhatsThis::enterWhatsThisMode();
       
  1835 #endif
       
  1836                 DefWindowProc(hwnd, WM_NCPAINT, 1, 0);
       
  1837                 break;
       
  1838 #if defined(QT_NON_COMMERCIAL)
       
  1839                 QT_NC_SYSCOMMAND
       
  1840 #endif
       
  1841             case SC_MINIMIZE:
       
  1842                 window_state_change = true;
       
  1843                 widget->dataPtr()->window_state |= Qt::WindowMinimized;
       
  1844                 if (widget->isVisible()) {
       
  1845                     QHideEvent e;
       
  1846                     qt_sendSpontaneousEvent(widget, &e);
       
  1847                     widget->hideChildren(true);
       
  1848                     const QString title = widget->windowIconText();
       
  1849                     if (!title.isEmpty())
       
  1850                         widget->setWindowTitle_helper(title);
       
  1851                 }
       
  1852                 result = false;
       
  1853                 break;
       
  1854             case SC_MAXIMIZE:
       
  1855                 if(widget->isWindow())
       
  1856                     widget->topData()->normalGeometry = widget->geometry();
       
  1857             case SC_RESTORE:
       
  1858                 window_state_change = true;
       
  1859                 if ((0xfff0 & wParam) == SC_MAXIMIZE)
       
  1860                     widget->dataPtr()->window_state |= Qt::WindowMaximized;
       
  1861                 else if (!widget->isMinimized())
       
  1862                     widget->dataPtr()->window_state &= ~Qt::WindowMaximized;
       
  1863 
       
  1864                 if (widget->isMinimized()) {
       
  1865                     widget->dataPtr()->window_state &= ~Qt::WindowMinimized;
       
  1866                     widget->showChildren(true);
       
  1867                     QShowEvent e;
       
  1868                     qt_sendSpontaneousEvent(widget, &e);
       
  1869                     const QString title = widget->windowTitle();
       
  1870                     if (!title.isEmpty())
       
  1871                         widget->setWindowTitle_helper(title);
       
  1872                 }
       
  1873                 result = false;
       
  1874                 break;
       
  1875             default:
       
  1876                 result = false;
       
  1877                 break;
       
  1878             }
       
  1879 
       
  1880             if (window_state_change) {
       
  1881                 QWindowStateChangeEvent e(oldstate);
       
  1882                 qt_sendSpontaneousEvent(widget, &e);
       
  1883             }
       
  1884 #endif // #ifndef Q_OS_WINCE
       
  1885 
       
  1886             break;
       
  1887         }
       
  1888 
       
  1889         case WM_SETTINGCHANGE:
       
  1890             if ( QApplication::type() == QApplication::Tty )
       
  1891                 break;
       
  1892 
       
  1893             if (!msg.wParam) {
       
  1894                 QString area = QString::fromWCharArray((wchar_t*)msg.lParam);
       
  1895                 if (area == QLatin1String("intl")) {
       
  1896                     QLocalePrivate::updateSystemPrivate();
       
  1897                     if (!widget->testAttribute(Qt::WA_SetLocale))
       
  1898                         widget->dptr()->setLocale_helper(QLocale(), true);
       
  1899                 }
       
  1900             }
       
  1901             else if (msg.wParam == SPI_SETICONTITLELOGFONT) {
       
  1902                 if (QApplication::desktopSettingsAware()) {
       
  1903                     widget = (QETWidget*)QWidget::find(hwnd);
       
  1904                     if (widget && !widget->parentWidget()) {
       
  1905                         qt_set_windows_font_resources();
       
  1906                     }
       
  1907                 }
       
  1908             }
       
  1909             break;
       
  1910 
       
  1911         case WM_PAINT:                                // paint event
       
  1912         case WM_ERASEBKGND:                        // erase window background
       
  1913             result = widget->translatePaintEvent(msg);
       
  1914             break;
       
  1915 
       
  1916 #ifndef Q_WS_WINCE
       
  1917         case WM_ENTERSIZEMOVE:
       
  1918             autoCaptureWnd = hwnd;
       
  1919             QApplicationPrivate::inSizeMove = true;
       
  1920             break;
       
  1921         case WM_EXITSIZEMOVE:
       
  1922             autoCaptureWnd = 0;
       
  1923             QApplicationPrivate::inSizeMove = false;
       
  1924             break;
       
  1925 #endif
       
  1926         case WM_MOVE:                                // move window
       
  1927         case WM_SIZE:                                // resize window
       
  1928             result = widget->translateConfigEvent(msg);
       
  1929             break;
       
  1930 
       
  1931         case WM_ACTIVATEAPP:
       
  1932             if (wParam == FALSE) {
       
  1933                 QApplication::setActiveWindow(0);
       
  1934                 // Another application was activated while our popups are open,
       
  1935                 // then close all popups.  In case some popup refuses to close,
       
  1936                 // we give up after 1024 attempts (to avoid an infinite loop).
       
  1937                 int maxiter = 1024;
       
  1938                 QWidget *popup;
       
  1939                 while ((popup=QApplication::activePopupWidget()) && maxiter--)
       
  1940                     popup->close();
       
  1941             }
       
  1942             break;
       
  1943 
       
  1944         case WM_ACTIVATE:
       
  1945             if ( QApplication::type() == QApplication::Tty )
       
  1946                 break;
       
  1947 
       
  1948             if (ptrWTOverlap && ptrWTEnable) {
       
  1949                 // cooperate with other tablet applications, but when
       
  1950                 // we get focus, I want to use the tablet...
       
  1951                 if (qt_tablet_context && GET_WM_ACTIVATE_STATE(wParam, lParam)) {
       
  1952                     if (ptrWTEnable(qt_tablet_context, true))
       
  1953                         ptrWTOverlap(qt_tablet_context, true);
       
  1954                 }
       
  1955             }
       
  1956             if (QApplication::activePopupWidget() && LOWORD(wParam) == WA_INACTIVE &&
       
  1957                 QWidget::find((HWND)lParam) == 0) {
       
  1958                 // Another application was activated while our popups are open,
       
  1959                 // then close all popups.  In case some popup refuses to close,
       
  1960                 // we give up after 1024 attempts (to avoid an infinite loop).
       
  1961                 int maxiter = 1024;
       
  1962                 QWidget *popup;
       
  1963                 while ((popup=QApplication::activePopupWidget()) && maxiter--)
       
  1964                     popup->close();
       
  1965             }
       
  1966 
       
  1967             if (LOWORD(wParam) != WA_INACTIVE) {
       
  1968                 // WM_ACTIVATEAPP handles the "true" false case, as this is only when the application
       
  1969                 // loses focus. Doing it here would result in the widget getting focus to not know
       
  1970                 // where it got it from; it would simply get a 0 value as the old focus widget.
       
  1971 #ifdef Q_WS_WINCE
       
  1972                 {
       
  1973 #ifdef Q_WS_WINCE_WM
       
  1974                     // On Windows mobile we do not receive WM_SYSCOMMAND / SC_MINIMIZE messages.
       
  1975                     // Thus we have to unset the minimized state explicitly. We must do this for all
       
  1976                     // top-level widgets, because we get the HWND of a random widget here.
       
  1977                     foreach (QWidget* tlw, QApplication::topLevelWidgets()) {
       
  1978                         if (tlw->isMinimized())
       
  1979                             tlw->setWindowState(tlw->windowState() & ~Qt::WindowMinimized);
       
  1980                     }
       
  1981 #else
       
  1982                     // On Windows CE we do not receive WM_SYSCOMMAND / SC_MINIMIZE messages.
       
  1983                     // Thus we have to unset the minimized state explicitly.
       
  1984                     if (widget->windowState() & Qt::WindowMinimized)
       
  1985                         widget->setWindowState(widget->windowState() & ~Qt::WindowMinimized);
       
  1986 #endif  // Q_WS_WINCE_WM
       
  1987 
       
  1988 #else
       
  1989                 if (!(widget->windowState() & Qt::WindowMinimized)) {
       
  1990 #endif
       
  1991                     // Ignore the activate message send by WindowsXP to a minimized window
       
  1992 #ifdef Q_WS_WINCE_WM
       
  1993                     if  (widget->windowState() & Qt::WindowFullScreen)
       
  1994                         qt_wince_hide_taskbar(widget->winId());
       
  1995 #endif
       
  1996                     qApp->winFocus(widget, true);
       
  1997                     // reset any window alert flashes
       
  1998                     alert_widget(widget, -1);
       
  1999                 }
       
  2000             }
       
  2001 
       
  2002             // Windows tries to activate a modally blocked window.
       
  2003             // This happens when restoring an application after "Show Desktop"
       
  2004             if (app_do_modal && LOWORD(wParam) == WA_ACTIVE) {
       
  2005                 QWidget *top = 0;
       
  2006                 if (!QApplicationPrivate::tryModalHelper(widget, &top) && top && widget != top) {
       
  2007                     if (top->isVisible()) {
       
  2008                         top->activateWindow();
       
  2009                     } else {
       
  2010                         // This is the case when native file dialogs are shown
       
  2011                         QWidget *p = (top->parentWidget() ? top->parentWidget()->window() : 0);
       
  2012                         if (p && p->isVisible())
       
  2013                             p->activateWindow();
       
  2014                     }
       
  2015                 }
       
  2016             }
       
  2017             break;
       
  2018 
       
  2019 #ifndef Q_WS_WINCE
       
  2020             case WM_MOUSEACTIVATE:
       
  2021                 if (widget->window()->windowType() == Qt::Tool) {
       
  2022                     QWidget *w = widget;
       
  2023                     if (!w->window()->focusWidget()) {
       
  2024                         while (w && (w->focusPolicy() & Qt::ClickFocus) == 0) {
       
  2025                             if (w->isWindow()) {
       
  2026                                 QWidget *fw = w;
       
  2027                                 while ((fw = fw->nextInFocusChain()) != w && fw->focusPolicy() == Qt::NoFocus)
       
  2028                                     ;
       
  2029                                 if (fw != w)
       
  2030                                    break;
       
  2031                                 QWidget *pw = w->parentWidget();
       
  2032                                 while (pw) {
       
  2033                                     pw = pw->window();
       
  2034                                     if (pw && pw->isVisible() && pw->focusWidget()) {
       
  2035                                         Q_ASSERT(pw->testAttribute(Qt::WA_WState_Created));
       
  2036                                         SetWindowPos(pw->internalWinId(), HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
       
  2037                                         break;
       
  2038                                     }
       
  2039                                     pw = pw->parentWidget();
       
  2040                                 }
       
  2041                                 RETURN(MA_NOACTIVATE);
       
  2042                             }
       
  2043                             w = w->parentWidget();
       
  2044                         }
       
  2045                     }
       
  2046                 }
       
  2047                 RETURN(MA_ACTIVATE);
       
  2048                 break;
       
  2049 #endif
       
  2050             case WM_SHOWWINDOW:
       
  2051                 if (lParam == SW_PARENTOPENING) {
       
  2052                     if (widget->testAttribute(Qt::WA_WState_Hidden))
       
  2053                         RETURN(0);
       
  2054                 }
       
  2055                 if (widget->isWindow() && widget->testAttribute(Qt::WA_WState_Visible)
       
  2056                     && !widget->testWindowState(Qt::WindowMinimized)) {
       
  2057                     if (lParam == SW_PARENTOPENING) {
       
  2058                         QShowEvent e;
       
  2059                         qt_sendSpontaneousEvent(widget, &e);
       
  2060                         widget->showChildren(true);
       
  2061                     } else if (lParam == SW_PARENTCLOSING) {
       
  2062                         QHideEvent e;
       
  2063                         qt_sendSpontaneousEvent(widget, &e);
       
  2064                         widget->hideChildren(true);
       
  2065                     }
       
  2066                 }
       
  2067                 if  (!wParam && autoCaptureWnd == widget->internalWinId())
       
  2068                     releaseAutoCapture();
       
  2069                 result = false;
       
  2070                 break;
       
  2071 
       
  2072         case WM_PALETTECHANGED:                        // our window changed palette
       
  2073             if (QColormap::hPal() && (WId)wParam == widget->internalWinId())
       
  2074                 RETURN(0);                        // otherwise: FALL THROUGH!
       
  2075             // FALL THROUGH
       
  2076         case WM_QUERYNEWPALETTE:                // realize own palette
       
  2077             if (QColormap::hPal()) {
       
  2078                 Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created));
       
  2079                 HDC hdc = GetDC(widget->internalWinId());
       
  2080                 HPALETTE hpalOld = SelectPalette(hdc, QColormap::hPal(), FALSE);
       
  2081                 uint n = RealizePalette(hdc);
       
  2082                 if (n)
       
  2083                     InvalidateRect(widget->internalWinId(), 0, TRUE);
       
  2084                 SelectPalette(hdc, hpalOld, TRUE);
       
  2085                 RealizePalette(hdc);
       
  2086                 ReleaseDC(widget->internalWinId(), hdc);
       
  2087                 RETURN(n);
       
  2088             }
       
  2089             break;
       
  2090         case WM_CLOSE:                                // close window
       
  2091             widget->translateCloseEvent(msg);
       
  2092             RETURN(0);                                // always handled
       
  2093 
       
  2094         case WM_DESTROY:                        // destroy window
       
  2095             if (hwnd == curWin) {
       
  2096                 QWidget *enter = QWidget::mouseGrabber();
       
  2097                 if (enter == widget)
       
  2098                     enter = 0;
       
  2099                 QApplicationPrivate::dispatchEnterLeave(enter, widget);
       
  2100                 curWin = enter ? enter->effectiveWinId() : 0;
       
  2101                 qt_last_mouse_receiver = enter;
       
  2102             }
       
  2103             if (widget == popupButtonFocus)
       
  2104                 popupButtonFocus = 0;
       
  2105             result = false;
       
  2106             break;
       
  2107 
       
  2108 #ifndef Q_WS_WINCE
       
  2109         case WM_WINDOWPOSCHANGING:
       
  2110             {
       
  2111                 result = false;
       
  2112                 if (widget->isWindow()) {
       
  2113                     WINDOWPOS *winPos = (WINDOWPOS *)lParam;
       
  2114                     if (widget->layout() && widget->layout()->hasHeightForWidth()
       
  2115                         && !(winPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE))) {
       
  2116                         QRect fs = widget->frameStrut();
       
  2117                         QRect rect = widget->geometry();
       
  2118                         QRect newRect = QRect(winPos->x + fs.left(),
       
  2119                                               winPos->y + fs.top(),
       
  2120                                               winPos->cx - fs.left() - fs.right(),
       
  2121                                               winPos->cy - fs.top() - fs.bottom());
       
  2122 
       
  2123                         QSize newSize = QLayout::closestAcceptableSize(widget, newRect.size());
       
  2124 
       
  2125                         int dh = newSize.height() - newRect.height();
       
  2126                         int dw = newSize.width() - newRect.width();
       
  2127                         if (!dw && ! dh)
       
  2128                             break; // Size OK
       
  2129 
       
  2130                         if (rect.y() != newRect.y()) {
       
  2131                             newRect.setTop(newRect.top() - dh);
       
  2132                         } else {
       
  2133                             newRect.setBottom(newRect.bottom() + dh);
       
  2134                         }
       
  2135 
       
  2136                         if (rect.x() != newRect.x()) {
       
  2137                             newRect.setLeft(newRect.left() - dw);
       
  2138                         } else {
       
  2139                             newRect.setRight(newRect.right() + dw);
       
  2140                         }
       
  2141 
       
  2142                         winPos->x = newRect.x() - fs.left();
       
  2143                         winPos->y = newRect.y() - fs.top();
       
  2144                         winPos->cx = newRect.width() + fs.left() + fs.right();
       
  2145                         winPos->cy = newRect.height() + fs.top() + fs.bottom();
       
  2146 
       
  2147                         RETURN(0);
       
  2148                     }
       
  2149                     if (widget->windowFlags() & Qt::WindowStaysOnBottomHint) {
       
  2150                         winPos->hwndInsertAfter = HWND_BOTTOM;
       
  2151                     }
       
  2152                 }
       
  2153             }
       
  2154             break;
       
  2155 
       
  2156         case WM_GETMINMAXINFO:
       
  2157             if (widget->xtra()) {
       
  2158                 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
       
  2159                 QWExtra *x = widget->xtra();
       
  2160                 QRect fs = widget->frameStrut();
       
  2161                 if ( x->minw > 0 )
       
  2162                     mmi->ptMinTrackSize.x = x->minw + fs.right() + fs.left();
       
  2163                 if ( x->minh > 0 )
       
  2164                     mmi->ptMinTrackSize.y = x->minh + fs.top() + fs.bottom();
       
  2165                 qint32 maxw = (x->maxw >= x->minw) ? x->maxw : x->minw;
       
  2166                 qint32 maxh = (x->maxh >= x->minh) ? x->maxh : x->minh;
       
  2167                 if ( maxw < QWIDGETSIZE_MAX ) {
       
  2168                     mmi->ptMaxTrackSize.x = maxw + fs.right() + fs.left();
       
  2169                     // windows with title bar have an implicit size limit of 112 pixels
       
  2170                     if (widget->windowFlags() & Qt::WindowTitleHint)
       
  2171                         mmi->ptMaxTrackSize.x = qMax<long>(mmi->ptMaxTrackSize.x, 112);
       
  2172                 }
       
  2173                 if ( maxh < QWIDGETSIZE_MAX )
       
  2174                     mmi->ptMaxTrackSize.y = maxh + fs.top() + fs.bottom();
       
  2175                 RETURN(0);
       
  2176             }
       
  2177             break;
       
  2178 
       
  2179             case WM_CONTEXTMENU:
       
  2180             {
       
  2181                 // it's not VK_APPS or Shift+F10, but a click in the NC area
       
  2182                 if (lParam != (int)0xffffffff) {
       
  2183                     result = false;
       
  2184                     break;
       
  2185                 }
       
  2186 
       
  2187                 QWidget *fw = QWidget::keyboardGrabber();
       
  2188                 if (!fw) {
       
  2189                     if (QApplication::activePopupWidget())
       
  2190                         fw = (QApplication::activePopupWidget()->focusWidget()
       
  2191                                                   ? QApplication::activePopupWidget()->focusWidget()
       
  2192                                                   : QApplication::activePopupWidget());
       
  2193                     else if (QApplication::focusWidget())
       
  2194                         fw = QApplication::focusWidget();
       
  2195                     else if (widget)
       
  2196                         fw = widget->window();
       
  2197                 }
       
  2198                 if (fw && fw->isEnabled()) {
       
  2199                     QPoint pos = fw->inputMethodQuery(Qt::ImMicroFocus).toRect().center();
       
  2200                     QContextMenuEvent e(QContextMenuEvent::Keyboard, pos, fw->mapToGlobal(pos),
       
  2201                                       qt_win_getKeyboardModifiers());
       
  2202                     result = qt_sendSpontaneousEvent(fw, &e);
       
  2203                 }
       
  2204             }
       
  2205             break;
       
  2206 #endif
       
  2207 
       
  2208         case WM_IME_STARTCOMPOSITION:
       
  2209         case WM_IME_ENDCOMPOSITION:
       
  2210         case WM_IME_COMPOSITION: {
       
  2211             QWidget *fw = QApplication::focusWidget();
       
  2212             QWinInputContext *im = fw ? qobject_cast<QWinInputContext *>(fw->inputContext()) : 0;
       
  2213             if (fw && im) {
       
  2214                 if(message == WM_IME_STARTCOMPOSITION)
       
  2215                     result = im->startComposition();
       
  2216                 else if (message == WM_IME_ENDCOMPOSITION)
       
  2217                     result = im->endComposition();
       
  2218                 else if (message == WM_IME_COMPOSITION)
       
  2219                     result = im->composition(lParam);
       
  2220             }
       
  2221             break;
       
  2222         }
       
  2223         case WM_IME_REQUEST: {
       
  2224             QWidget *fw = QApplication::focusWidget();
       
  2225             QWinInputContext *im = fw ? qobject_cast<QWinInputContext *>(fw->inputContext()) : 0;
       
  2226             if (fw && im) {
       
  2227                 if(wParam == IMR_RECONVERTSTRING) {
       
  2228                     int ret = im->reconvertString((RECONVERTSTRING *)lParam);
       
  2229                     if (ret == -1) {
       
  2230                         result = false;
       
  2231                     } else {
       
  2232                         return ret;
       
  2233                     }
       
  2234                 } else if (wParam == IMR_CONFIRMRECONVERTSTRING) {
       
  2235                     RETURN(TRUE);
       
  2236                 } else {
       
  2237                     // in all other cases, call DefWindowProc()
       
  2238                     result = false;
       
  2239                 }
       
  2240             }
       
  2241             break;
       
  2242         }
       
  2243 #ifndef Q_WS_WINCE
       
  2244         case WM_CHANGECBCHAIN:
       
  2245         case WM_DRAWCLIPBOARD:
       
  2246 #endif
       
  2247         case WM_RENDERFORMAT:
       
  2248         case WM_RENDERALLFORMATS:
       
  2249 #ifndef QT_NO_CLIPBOARD
       
  2250         case WM_DESTROYCLIPBOARD:
       
  2251             if (qt_clipboard) {
       
  2252                 QClipboardEvent e(reinterpret_cast<QEventPrivate *>(&msg));
       
  2253                 qt_sendSpontaneousEvent(qt_clipboard, &e);
       
  2254                 RETURN(0);
       
  2255             }
       
  2256             result = false;
       
  2257             break;
       
  2258 #endif //QT_NO_CLIPBOARD
       
  2259 #ifndef QT_NO_ACCESSIBILITY
       
  2260         case WM_GETOBJECT:
       
  2261             {
       
  2262                 // Ignoring all requests while starting up
       
  2263                 if (QApplication::startingUp() || QApplication::closingDown() || (DWORD)lParam != OBJID_CLIENT) {
       
  2264                     result = false;
       
  2265                     break;
       
  2266                 }
       
  2267 
       
  2268                 typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN);
       
  2269                 static PtrLresultFromObject ptrLresultFromObject = 0;
       
  2270                 static bool oleaccChecked = false;
       
  2271 
       
  2272                 if (!oleaccChecked) {
       
  2273                     oleaccChecked = true;
       
  2274 #if !defined(Q_OS_WINCE)
       
  2275                     ptrLresultFromObject = (PtrLresultFromObject)QLibrary::resolve(QLatin1String("oleacc.dll"), "LresultFromObject");
       
  2276 #endif
       
  2277                 }
       
  2278                 if (ptrLresultFromObject) {
       
  2279                     QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(widget);
       
  2280                     if (!acc) {
       
  2281                         result = false;
       
  2282                         break;
       
  2283                     }
       
  2284 
       
  2285                     // and get an instance of the IAccessibile implementation
       
  2286                     IAccessible *iface = qt_createWindowsAccessible(acc);
       
  2287                     res = ptrLresultFromObject(IID_IAccessible, wParam, iface);  // ref == 2
       
  2288                     iface->Release(); // the client will release the object again, and then it will destroy itself
       
  2289 
       
  2290                     if (res > 0)
       
  2291                         RETURN(res);
       
  2292                 }
       
  2293             }
       
  2294             result = false;
       
  2295             break;
       
  2296         case WM_GETTEXT:
       
  2297             if (!widget->isWindow()) {
       
  2298                 int ret = 0;
       
  2299                 QAccessibleInterface *acc = QAccessible::queryAccessibleInterface(widget);
       
  2300                 if (acc) {
       
  2301                     QString text = acc->text(QAccessible::Name, 0);
       
  2302                     if (text.isEmpty())
       
  2303                         text = widget->objectName();
       
  2304                     ret = qMin<int>(wParam - 1, text.size());
       
  2305                     text.resize(ret);
       
  2306                     memcpy((void *)lParam, text.utf16(), (text.size() + 1) * sizeof(ushort));
       
  2307                     delete acc;
       
  2308                 }
       
  2309                 if (!ret) {
       
  2310                     result = false;
       
  2311                     break;
       
  2312                 }
       
  2313                 RETURN(ret);
       
  2314             }
       
  2315             result = false;
       
  2316             break;
       
  2317 #endif
       
  2318         case WT_PACKET:
       
  2319             if (ptrWTPacketsGet) {
       
  2320                 if ((nPackets = ptrWTPacketsGet(qt_tablet_context, QT_TABLET_NPACKETQSIZE, &localPacketBuf))) {
       
  2321                     result = widget->translateTabletEvent(msg, localPacketBuf, nPackets);
       
  2322                 }
       
  2323             }
       
  2324             break;
       
  2325         case WT_PROXIMITY:
       
  2326             if (ptrWTPacketsGet) {
       
  2327                 bool enteredProximity = LOWORD(lParam) != 0;
       
  2328                 PACKET proximityBuffer[QT_TABLET_NPACKETQSIZE];
       
  2329                 int totalPacks = ptrWTPacketsGet(qt_tablet_context, QT_TABLET_NPACKETQSIZE, proximityBuffer);
       
  2330                 if (totalPacks > 0 && enteredProximity) {
       
  2331                     uint currentCursor = proximityBuffer[0].pkCursor;
       
  2332                     if (!tCursorInfo()->contains(currentCursor))
       
  2333                         tabletInit(currentCursor, qt_tablet_context);
       
  2334                     currentTabletPointer = tCursorInfo()->value(currentCursor);
       
  2335                 }
       
  2336                 qt_tabletChokeMouse = false;
       
  2337 #ifndef QT_NO_TABLETEVENT
       
  2338                 QTabletEvent tabletProximity(enteredProximity ? QEvent::TabletEnterProximity
       
  2339                                                               : QEvent::TabletLeaveProximity,
       
  2340                                              QPoint(), QPoint(), QPointF(), currentTabletPointer.currentDevice, currentTabletPointer.currentPointerType, 0, 0,
       
  2341                                              0, 0, 0, 0, 0, currentTabletPointer.llId);
       
  2342                 QApplication::sendEvent(qApp, &tabletProximity);
       
  2343 #endif // QT_NO_TABLETEVENT
       
  2344             }
       
  2345             break;
       
  2346 #ifdef Q_WS_WINCE_WM
       
  2347         case WM_SETFOCUS: {
       
  2348             HIMC hC;
       
  2349             hC = ImmGetContext(hwnd);
       
  2350             ImmSetOpenStatus(hC, TRUE);
       
  2351             ImmEscape(NULL, hC, IME_ESC_SET_MODE, (LPVOID)IM_SPELL);
       
  2352             result = false;
       
  2353         }
       
  2354         break;
       
  2355 #endif
       
  2356         case WM_KILLFOCUS:
       
  2357             if (!QWidget::find((HWND)wParam)) { // we don't get focus, so unset it now
       
  2358                 if (!widget->hasFocus()) // work around Windows bug after minimizing/restoring
       
  2359                     widget = (QETWidget*)QApplication::focusWidget();
       
  2360                 HWND focus = ::GetFocus();
       
  2361                 //if there is a current widget and the new widget belongs to the same toplevel window
       
  2362                 //or if the current widget was embedded into non-qt window (i.e. we won't get WM_ACTIVATEAPP)
       
  2363                 //then we clear the focus on the widget
       
  2364                 //in case the new widget belongs to a different widget hierarchy, clearing the focus
       
  2365                 //will be handled because the active window will change
       
  2366                 const bool embedded = widget && ((QETWidget*)widget->window())->topData()->embedded;
       
  2367                 if (widget && (embedded || ::IsChild(widget->window()->internalWinId(), focus))) {
       
  2368                     widget->clearFocus();
       
  2369                     result = true;
       
  2370                 } else {
       
  2371                     result = false;
       
  2372                 }
       
  2373             } else {
       
  2374                 result = false;
       
  2375             }
       
  2376             break;
       
  2377         case WM_THEMECHANGED:
       
  2378             if ((widget->windowType() == Qt::Desktop) || !qApp || QApplication::closingDown()
       
  2379                                                          || QApplication::type() == QApplication::Tty)
       
  2380                 break;
       
  2381 
       
  2382             if (widget->testAttribute(Qt::WA_WState_Polished))
       
  2383                 QApplication::style()->unpolish(widget);
       
  2384 
       
  2385             if (widget->testAttribute(Qt::WA_WState_Polished))
       
  2386                 QApplication::style()->polish(widget);
       
  2387             widget->repolishStyle(*QApplication::style());
       
  2388             if (widget->isVisible())
       
  2389                 widget->update();
       
  2390             break;
       
  2391 
       
  2392 #ifndef Q_WS_WINCE
       
  2393         case WM_INPUTLANGCHANGE: {
       
  2394             wchar_t info[7];
       
  2395             if (!GetLocaleInfo(MAKELCID(lParam, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, info, 6)) {
       
  2396                 inputcharset = CP_ACP;
       
  2397             } else {
       
  2398                 inputcharset = QString::fromWCharArray(info).toInt();
       
  2399             }
       
  2400             QKeyMapper::changeKeyboard();
       
  2401             break;
       
  2402         }
       
  2403 #else
       
  2404         case WM_COMMAND: {
       
  2405             bool OkCommand = (LOWORD(wParam) == 0x1);
       
  2406             bool CancelCommand = (LOWORD(wParam) == 0x2);
       
  2407             if (OkCommand)
       
  2408                 QApplication::postEvent(widget, new QEvent(QEvent::OkRequest));
       
  2409             if (CancelCommand)
       
  2410                 QApplication::postEvent(widget, new QEvent(QEvent::Close));
       
  2411             else
       
  2412 #ifndef QT_NO_MENUBAR
       
  2413                 QMenuBar::wceCommands(LOWORD(wParam), (HWND) lParam);
       
  2414 #endif
       
  2415             result = true;
       
  2416         }
       
  2417             break;
       
  2418         case WM_HELP:
       
  2419             QApplication::postEvent(widget, new QEvent(QEvent::HelpRequest));
       
  2420             result = true;
       
  2421             break;
       
  2422 #endif
       
  2423 
       
  2424         case WM_MOUSELEAVE:
       
  2425             // We receive a mouse leave for curWin, meaning
       
  2426             // the mouse was moved outside our widgets
       
  2427             if (widget->internalWinId() == curWin) {
       
  2428                 bool dispatch = !widget->underMouse();
       
  2429                 // hasMouse is updated when dispatching enter/leave,
       
  2430                 // so test if it is actually up-to-date
       
  2431                 if (!dispatch) {
       
  2432                     QRect geom = widget->geometry();
       
  2433                     if (widget->parentWidget() && !widget->isWindow()) {
       
  2434                         QPoint gp = widget->parentWidget()->mapToGlobal(widget->pos());
       
  2435                         geom.setX(gp.x());
       
  2436                         geom.setY(gp.y());
       
  2437                     }
       
  2438                     QPoint cpos = QCursor::pos();
       
  2439                     dispatch = !geom.contains(cpos);
       
  2440                     if ( !dispatch && !QWidget::mouseGrabber()) {
       
  2441                         QWidget *hittest = QApplication::widgetAt(cpos);
       
  2442                         dispatch = !hittest || hittest->internalWinId() != curWin;
       
  2443                     }
       
  2444                     if (!dispatch) {
       
  2445                         HRGN hrgn = qt_tryCreateRegion(QRegion::Rectangle, 0,0,0,0);
       
  2446                         if (GetWindowRgn(curWin, hrgn) != ERROR) {
       
  2447                             QPoint lcpos = widget->mapFromGlobal(cpos);
       
  2448                             dispatch = !PtInRegion(hrgn, lcpos.x(), lcpos.y());
       
  2449                         }
       
  2450                         DeleteObject(hrgn);
       
  2451                     }
       
  2452                 }
       
  2453                 if (dispatch) {
       
  2454                     if (qt_last_mouse_receiver && !qt_last_mouse_receiver->internalWinId())
       
  2455                         QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver);
       
  2456                     else
       
  2457                         QApplicationPrivate::dispatchEnterLeave(0, QWidget::find((WId)curWin));
       
  2458                     curWin = 0;
       
  2459                     qt_last_mouse_receiver = 0;
       
  2460                 }
       
  2461             }
       
  2462             break;
       
  2463 
       
  2464         case WM_CANCELMODE:
       
  2465             {
       
  2466                 // this goes through QMenuBar's event filter
       
  2467                 QEvent e(QEvent::ActivationChange);
       
  2468                 QApplication::sendEvent(qApp, &e);
       
  2469             }
       
  2470             break;
       
  2471 
       
  2472         case WM_IME_NOTIFY:
       
  2473             // special handling for ime, only for widgets in a popup
       
  2474             if (wParam  == IMN_OPENCANDIDATE) {
       
  2475                 imeParentWnd = hwnd;
       
  2476                 if (QApplication::activePopupWidget()) {
       
  2477                     // temporarily disable the mouse grab to allow mouse input in
       
  2478                     // the ime candidate window. The actual handle is untouched
       
  2479                     if (autoCaptureWnd)
       
  2480                         ReleaseCapture();
       
  2481                 }
       
  2482             } else if (wParam  == IMN_CLOSECANDIDATE) {
       
  2483                 imeParentWnd = 0;
       
  2484                 if (QApplication::activePopupWidget()) {
       
  2485                     // undo the action above, when candidate window is closed
       
  2486                     if (autoCaptureWnd)
       
  2487                         SetCapture(autoCaptureWnd);
       
  2488                 }
       
  2489             }
       
  2490             result = false;
       
  2491             break;
       
  2492         case WM_GESTURE: {
       
  2493             GESTUREINFO gi;
       
  2494             memset(&gi, 0, sizeof(GESTUREINFO));
       
  2495             gi.cbSize = sizeof(GESTUREINFO);
       
  2496 
       
  2497             QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
       
  2498             BOOL bResult = false;
       
  2499             if (qAppPriv->GetGestureInfo)
       
  2500                 bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi);
       
  2501             if (bResult) {
       
  2502 //                if (gi.dwID == GID_BEGIN) {
       
  2503 //                    // find the alien widget for the gesture position.
       
  2504 //                    // This might not be accurate as the position is the center
       
  2505 //                    // point of two fingers for multi-finger gestures.
       
  2506 //                    QPoint pt(gi.ptsLocation.x, gi.ptsLocation.y);
       
  2507 //                    QWidget *w = widget->childAt(widget->mapFromGlobal(pt));
       
  2508 //                    qAppPriv->gestureWidget = w ? w : widget;
       
  2509 //                }
       
  2510 //                if (qAppPriv->gestureWidget)
       
  2511 //                    static_cast<QETWidget*>(qAppPriv->gestureWidget)->translateGestureEvent(msg, gi);
       
  2512 //                if (qAppPriv->CloseGestureInfoHandle)
       
  2513 //                    qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam);
       
  2514 //                if (gi.dwID == GID_END)
       
  2515 //                    qAppPriv->gestureWidget = 0;
       
  2516 //            } else {
       
  2517 //                DWORD dwErr = GetLastError();
       
  2518 //                if (dwErr > 0)
       
  2519 //                    qWarning() << "translateGestureEvent: error = " << dwErr;
       
  2520             }
       
  2521             result = true;
       
  2522             break;
       
  2523         }
       
  2524         default:
       
  2525             result = false;                        // event was not processed
       
  2526             break;
       
  2527         }
       
  2528     }
       
  2529 
       
  2530     if (evt_type != QEvent::None) {                // simple event
       
  2531         QEvent e(evt_type);
       
  2532         result = qt_sendSpontaneousEvent(widget, &e);
       
  2533     }
       
  2534 
       
  2535     if (result)
       
  2536         RETURN(false);
       
  2537 
       
  2538 do_default:
       
  2539     RETURN(QWinInputContext::DefWindowProc(hwnd,message,wParam,lParam))
       
  2540 }
       
  2541 
       
  2542 
       
  2543 /*****************************************************************************
       
  2544   Modal widgets; We have implemented our own modal widget mechanism
       
  2545   to get total control.
       
  2546   A modal widget without a parent becomes application-modal.
       
  2547   A modal widget with a parent becomes modal to its parent and grandparents..
       
  2548 
       
  2549   QApplicationPrivate::enterModal()
       
  2550         Enters modal state
       
  2551         Arguments:
       
  2552             QWidget *widget        A modal widget
       
  2553 
       
  2554   QApplicationPrivate::leaveModal()
       
  2555         Leaves modal state for a widget
       
  2556         Arguments:
       
  2557             QWidget *widget        A modal widget
       
  2558  *****************************************************************************/
       
  2559 
       
  2560 bool QApplicationPrivate::modalState()
       
  2561 {
       
  2562     return app_do_modal;
       
  2563 }
       
  2564 
       
  2565 void QApplicationPrivate::enterModal_sys(QWidget *widget)
       
  2566 {
       
  2567     if (!qt_modal_stack)
       
  2568         qt_modal_stack = new QWidgetList;
       
  2569 
       
  2570     releaseAutoCapture();
       
  2571     ClipCursor(0);
       
  2572     QWidget *leave = qt_last_mouse_receiver;
       
  2573     if (!leave)
       
  2574         leave = QWidget::find((WId)curWin);
       
  2575     QApplicationPrivate::dispatchEnterLeave(0, leave);
       
  2576     qt_modal_stack->insert(0, widget);
       
  2577     app_do_modal = true;
       
  2578     curWin = 0;
       
  2579     qt_last_mouse_receiver = 0;
       
  2580     qt_win_ignoreNextMouseReleaseEvent = false;
       
  2581 }
       
  2582 
       
  2583 void QApplicationPrivate::leaveModal_sys(QWidget *widget)
       
  2584 {
       
  2585     if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
       
  2586         if (qt_modal_stack->isEmpty()) {
       
  2587             delete qt_modal_stack;
       
  2588             qt_modal_stack = 0;
       
  2589             QPoint p(QCursor::pos());
       
  2590             app_do_modal = false; // necessary, we may get recursively into qt_try_modal below
       
  2591             QWidget* w = QApplication::widgetAt(p.x(), p.y());
       
  2592             QWidget *leave = qt_last_mouse_receiver;
       
  2593             if (!leave)
       
  2594                 leave = QWidget::find((WId)curWin);
       
  2595             if (QWidget *grabber = QWidget::mouseGrabber()) {
       
  2596                 w = grabber;
       
  2597                 if (leave == w)
       
  2598                     leave = 0;
       
  2599             }
       
  2600             QApplicationPrivate::dispatchEnterLeave(w, leave); // send synthetic enter event
       
  2601             curWin = w ? w->effectiveWinId() : 0;
       
  2602             qt_last_mouse_receiver = w;
       
  2603         }
       
  2604         qt_win_ignoreNextMouseReleaseEvent = true;
       
  2605     }
       
  2606     app_do_modal = qt_modal_stack != 0;
       
  2607 }
       
  2608 
       
  2609 bool qt_try_modal(QWidget *widget, MSG *msg, int& ret)
       
  2610 {
       
  2611 #if defined(Q_OS_WINCE)
       
  2612     Q_UNUSED(ret);
       
  2613 #endif
       
  2614     QWidget * top = 0;
       
  2615 
       
  2616     if (QApplicationPrivate::tryModalHelper(widget, &top))
       
  2617         return true;
       
  2618 
       
  2619     int type = msg->message;
       
  2620 
       
  2621     bool block_event = false;
       
  2622 #ifndef Q_WS_WINCE
       
  2623     if (type != WM_NCHITTEST) {
       
  2624 #endif
       
  2625         if ((type >= WM_MOUSEFIRST && type <= WM_MOUSELAST) ||
       
  2626              type == WM_MOUSEWHEEL || type == WM_MOUSEHWHEEL ||
       
  2627              type == WM_MOUSELEAVE ||
       
  2628              (type >= WM_KEYFIRST && type <= WM_KEYLAST)
       
  2629 #ifndef Q_WS_WINCE
       
  2630             || type == WM_NCMOUSEMOVE
       
  2631 #endif
       
  2632          ) {
       
  2633             if (type == WM_MOUSEMOVE
       
  2634 #ifndef Q_WS_WINCE
       
  2635                  || type == WM_NCMOUSEMOVE
       
  2636 #endif
       
  2637             ) {
       
  2638 #ifndef QT_NO_CURSOR
       
  2639                 QCursor *c = qt_grab_cursor();
       
  2640                 if (!c)
       
  2641                     c = QApplication::overrideCursor();
       
  2642                 if (c)                                // application cursor defined
       
  2643                     SetCursor(c->handle());
       
  2644                 else
       
  2645                     SetCursor(QCursor(Qt::ArrowCursor).handle());
       
  2646 #endif // QT_NO_CURSOR
       
  2647             }
       
  2648             block_event = true;
       
  2649         } else if (type == WM_CLOSE) {
       
  2650             block_event = true;
       
  2651         }
       
  2652 #ifndef Q_WS_WINCE
       
  2653         else if (type == WM_MOUSEACTIVATE || type == WM_NCLBUTTONDOWN){
       
  2654             if (!top->isActiveWindow()) {
       
  2655                 top->activateWindow();
       
  2656             } else {
       
  2657                 QApplication::beep();
       
  2658             }
       
  2659             block_event = true;
       
  2660             ret = MA_NOACTIVATEANDEAT;
       
  2661         } else if (type == WM_SYSCOMMAND) {
       
  2662             if (!(msg->wParam == SC_RESTORE && widget->isMinimized()))
       
  2663                 block_event = true;
       
  2664         }
       
  2665     }
       
  2666 #endif
       
  2667 
       
  2668     return !block_event;
       
  2669 }
       
  2670 
       
  2671 
       
  2672 /*****************************************************************************
       
  2673   Popup widget mechanism
       
  2674 
       
  2675   openPopup()
       
  2676         Adds a widget to the list of popup widgets
       
  2677         Arguments:
       
  2678             QWidget *widget        The popup widget to be added
       
  2679 
       
  2680   closePopup()
       
  2681         Removes a widget from the list of popup widgets
       
  2682         Arguments:
       
  2683             QWidget *widget        The popup widget to be removed
       
  2684  *****************************************************************************/
       
  2685 
       
  2686 void QApplicationPrivate::openPopup(QWidget *popup)
       
  2687 {
       
  2688     if (!QApplicationPrivate::popupWidgets)
       
  2689         QApplicationPrivate::popupWidgets = new QWidgetList;
       
  2690     QApplicationPrivate::popupWidgets->append(popup);
       
  2691     if (!popup->isEnabled())
       
  2692         return;
       
  2693 
       
  2694     // close any opened 'ime candidate window'
       
  2695     if (imeParentWnd)
       
  2696         ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0);
       
  2697 
       
  2698     if (QApplicationPrivate::popupWidgets->count() == 1 && !qt_nograb()) {
       
  2699         Q_ASSERT(popup->testAttribute(Qt::WA_WState_Created));
       
  2700         setAutoCapture(popup->internalWinId());        // grab mouse/keyboard
       
  2701     }
       
  2702     // Popups are not focus-handled by the window system (the first
       
  2703     // popup grabbed the keyboard), so we have to do that manually: A
       
  2704     // new popup gets the focus
       
  2705     if (popup->focusWidget()) {
       
  2706         popup->focusWidget()->setFocus(Qt::PopupFocusReason);
       
  2707     } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup
       
  2708         if (QWidget *fw = QApplication::focusWidget()) {
       
  2709             QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason);
       
  2710             QApplication::sendEvent(fw, &e);
       
  2711         }
       
  2712     }
       
  2713 }
       
  2714 
       
  2715 void QApplicationPrivate::closePopup(QWidget *popup)
       
  2716 {
       
  2717     if (!QApplicationPrivate::popupWidgets)
       
  2718         return;
       
  2719     QApplicationPrivate::popupWidgets->removeAll(popup);
       
  2720     POINT curPos;
       
  2721     GetCursorPos(&curPos);
       
  2722 
       
  2723     // close any opened 'ime candidate window'
       
  2724     if (imeParentWnd)
       
  2725         ::SendMessage(imeParentWnd, WM_IME_ENDCOMPOSITION, 0, 0);
       
  2726 
       
  2727     if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup
       
  2728         delete QApplicationPrivate::popupWidgets;
       
  2729         QApplicationPrivate::popupWidgets = 0;
       
  2730         replayPopupMouseEvent = (!popup->geometry().contains(QPoint(curPos.x, curPos.y))
       
  2731                                 && !popup->testAttribute(Qt::WA_NoMouseReplay));
       
  2732         if (!popup->isEnabled())
       
  2733             return;
       
  2734         if (!qt_nograb())                        // grabbing not disabled
       
  2735             releaseAutoCapture();
       
  2736         QWidget *fw = QApplicationPrivate::active_window ? QApplicationPrivate::active_window->focusWidget()
       
  2737             : QApplication::focusWidget();
       
  2738         if (fw) {
       
  2739             if (fw != QApplication::focusWidget()) {
       
  2740                 fw->setFocus(Qt::PopupFocusReason);
       
  2741             } else {
       
  2742                 QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason);
       
  2743                 QApplication::sendEvent(fw, &e);
       
  2744             }
       
  2745         }
       
  2746     } else {
       
  2747         // Popups are not focus-handled by the window system (the
       
  2748         // first popup grabbed the keyboard), so we have to do that
       
  2749         // manually: A popup was closed, so the previous popup gets
       
  2750         // the focus.
       
  2751         QWidget* aw = QApplicationPrivate::popupWidgets->last();
       
  2752         if (QApplicationPrivate::popupWidgets->count() == 1) {
       
  2753             Q_ASSERT(aw->testAttribute(Qt::WA_WState_Created));
       
  2754             setAutoCapture(aw->internalWinId());
       
  2755         }
       
  2756         if (QWidget *fw = aw->focusWidget())
       
  2757             fw->setFocus(Qt::PopupFocusReason);
       
  2758     }
       
  2759 }
       
  2760 
       
  2761 
       
  2762 
       
  2763 
       
  2764 /*****************************************************************************
       
  2765   Event translation; translates Windows events to Qt events
       
  2766  *****************************************************************************/
       
  2767 
       
  2768 //
       
  2769 // Auto-capturing for mouse press and mouse release
       
  2770 //
       
  2771 
       
  2772 static void setAutoCapture(HWND h)
       
  2773 {
       
  2774     if (autoCaptureWnd)
       
  2775         releaseAutoCapture();
       
  2776     autoCaptureWnd = h;
       
  2777     SetCapture(h);
       
  2778 }
       
  2779 
       
  2780 static void releaseAutoCapture()
       
  2781 {
       
  2782     if (autoCaptureWnd) {
       
  2783         ReleaseCapture();
       
  2784         autoCaptureWnd = 0;
       
  2785     }
       
  2786 }
       
  2787 
       
  2788 
       
  2789 //
       
  2790 // Mouse event translation
       
  2791 //
       
  2792 // Non-client mouse messages are not translated
       
  2793 //
       
  2794 
       
  2795 static const ushort mouseTbl[] = {
       
  2796     WM_MOUSEMOVE,        QEvent::MouseMove,               0,
       
  2797     WM_LBUTTONDOWN,      QEvent::MouseButtonPress,        Qt::LeftButton,
       
  2798     WM_LBUTTONUP,        QEvent::MouseButtonRelease,      Qt::LeftButton,
       
  2799     WM_LBUTTONDBLCLK,    QEvent::MouseButtonDblClick,     Qt::LeftButton,
       
  2800     WM_RBUTTONDOWN,      QEvent::MouseButtonPress,        Qt::RightButton,
       
  2801     WM_RBUTTONUP,        QEvent::MouseButtonRelease,      Qt::RightButton,
       
  2802     WM_RBUTTONDBLCLK,    QEvent::MouseButtonDblClick,     Qt::RightButton,
       
  2803     WM_MBUTTONDOWN,      QEvent::MouseButtonPress,        Qt::MidButton,
       
  2804     WM_MBUTTONUP,        QEvent::MouseButtonRelease,      Qt::MidButton,
       
  2805     WM_MBUTTONDBLCLK,    QEvent::MouseButtonDblClick,     Qt::MidButton,
       
  2806     // use XButton1 for now, the real X button is decided later
       
  2807     WM_XBUTTONDOWN,      QEvent::MouseButtonPress,        Qt::XButton1,
       
  2808     WM_XBUTTONUP,        QEvent::MouseButtonRelease,      Qt::XButton1,
       
  2809     WM_XBUTTONDBLCLK,    QEvent::MouseButtonDblClick,     Qt::XButton1,
       
  2810 
       
  2811 #ifndef Q_WS_WINCE
       
  2812     WM_NCMOUSEMOVE,      QEvent::NonClientAreaMouseMove,           0,
       
  2813     WM_NCLBUTTONDOWN,    QEvent::NonClientAreaMouseButtonPress,    Qt::LeftButton,
       
  2814     WM_NCLBUTTONUP,      QEvent::NonClientAreaMouseButtonRelease,  Qt::LeftButton,
       
  2815     WM_NCLBUTTONDBLCLK,  QEvent::NonClientAreaMouseButtonDblClick, Qt::LeftButton,
       
  2816     WM_NCRBUTTONDOWN,    QEvent::NonClientAreaMouseButtonPress,    Qt::RightButton,
       
  2817     WM_NCRBUTTONUP,      QEvent::NonClientAreaMouseButtonRelease,  Qt::RightButton,
       
  2818     WM_NCRBUTTONDBLCLK,  QEvent::NonClientAreaMouseButtonDblClick, Qt::RightButton,
       
  2819     WM_NCMBUTTONDOWN,    QEvent::NonClientAreaMouseButtonPress,    Qt::MidButton,
       
  2820     WM_NCMBUTTONUP,      QEvent::NonClientAreaMouseButtonRelease,  Qt::MidButton,
       
  2821     WM_NCMBUTTONDBLCLK,  QEvent::NonClientAreaMouseButtonDblClick, Qt::MidButton,
       
  2822 #endif
       
  2823 
       
  2824     0,                        0,                                0
       
  2825 };
       
  2826 
       
  2827 static int translateButtonState(int s, int type, int button)
       
  2828 {
       
  2829     Q_UNUSED(type);
       
  2830     Q_UNUSED(button);
       
  2831     int bst = 0;
       
  2832     if (s & MK_LBUTTON)
       
  2833         bst |= Qt::LeftButton;
       
  2834     if (s & MK_MBUTTON)
       
  2835         bst |= Qt::MidButton;
       
  2836     if (s & MK_RBUTTON)
       
  2837         bst |= Qt::RightButton;
       
  2838     if (s & MK_SHIFT)
       
  2839         bst |= Qt::ShiftModifier;
       
  2840     if (s & MK_CONTROL)
       
  2841         bst |= Qt::ControlModifier;
       
  2842 
       
  2843     if (s & MK_XBUTTON1)
       
  2844         bst |= Qt::XButton1;
       
  2845     if (s & MK_XBUTTON2)
       
  2846         bst |= Qt::XButton2;
       
  2847 
       
  2848     if (GetKeyState(VK_MENU) < 0)
       
  2849         bst |= Qt::AltModifier;
       
  2850 
       
  2851     if ((GetKeyState(VK_LWIN) < 0) ||
       
  2852          (GetKeyState(VK_RWIN) < 0))
       
  2853         bst |= Qt::MetaModifier;
       
  2854 
       
  2855     return bst;
       
  2856 }
       
  2857 
       
  2858 void qt_win_eatMouseMove()
       
  2859 {
       
  2860     // after closing a windows dialog with a double click (i.e. open a file)
       
  2861     // the message queue still contains a dubious WM_MOUSEMOVE message where
       
  2862     // the left button is reported to be down (wParam != 0).
       
  2863     // remove all those messages (usually 1) and post the last one with a
       
  2864     // reset button state
       
  2865 
       
  2866     MSG msg = {0, 0, 0, 0, 0, {0, 0} };
       
  2867     while (PeekMessage(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE))
       
  2868         ;
       
  2869     if (msg.message == WM_MOUSEMOVE)
       
  2870         PostMessage(msg.hwnd, msg.message, 0, msg.lParam);
       
  2871 }
       
  2872 
       
  2873 // In DnD, the mouse release event never appears, so the
       
  2874 // mouse button state machine must be manually reset
       
  2875 void QApplication::winMouseButtonUp()
       
  2876 {
       
  2877     qt_button_down = 0;
       
  2878     releaseAutoCapture();
       
  2879 }
       
  2880 
       
  2881 void QETWidget::repolishStyle(QStyle &)
       
  2882 {
       
  2883     QEvent e(QEvent::StyleChange);
       
  2884     QApplication::sendEvent(this, &e);
       
  2885 }
       
  2886 
       
  2887 bool QETWidget::translateMouseEvent(const MSG &msg)
       
  2888 {
       
  2889     if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
       
  2890         Q_ASSERT(internalWinId());
       
  2891 
       
  2892     static QPoint pos;
       
  2893     static POINT gpos={-1,-1};
       
  2894     QEvent::Type type;                                // event parameters
       
  2895     int           button;
       
  2896     int           state;
       
  2897     int           i;
       
  2898 
       
  2899     if (sm_blockUserInput) //block user interaction during session management
       
  2900         return true;
       
  2901 
       
  2902     // Compress mouse move events
       
  2903     if (msg.message == WM_MOUSEMOVE) {
       
  2904         MSG mouseMsg;
       
  2905         while (PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEFIRST,
       
  2906                WM_MOUSELAST, PM_NOREMOVE)) {
       
  2907             if (mouseMsg.message == WM_MOUSEMOVE) {
       
  2908 #define PEEKMESSAGE_IS_BROKEN 1
       
  2909 #ifdef PEEKMESSAGE_IS_BROKEN
       
  2910                 // Since the Windows PeekMessage() function doesn't
       
  2911                 // correctly return the wParam for WM_MOUSEMOVE events
       
  2912                 // if there is a key release event in the queue
       
  2913                 // _before_ the mouse event, we have to also consider
       
  2914                 // key release events (kls 2003-05-13):
       
  2915                 MSG keyMsg;
       
  2916                 bool done = false;
       
  2917                 while (PeekMessage(&keyMsg, 0, WM_KEYFIRST, WM_KEYLAST,
       
  2918                        PM_NOREMOVE)) {
       
  2919                     if (keyMsg.time < mouseMsg.time) {
       
  2920                         if ((keyMsg.lParam & 0xC0000000) == 0x40000000) {
       
  2921                             PeekMessage(&keyMsg, 0, keyMsg.message,
       
  2922                                         keyMsg.message, PM_REMOVE);
       
  2923                         } else {
       
  2924                             done = true;
       
  2925                             break;
       
  2926                         }
       
  2927                     } else {
       
  2928                         break; // no key event before the WM_MOUSEMOVE event
       
  2929                     }
       
  2930                 }
       
  2931                 if (done)
       
  2932                     break;
       
  2933 #else
       
  2934                 // Actually the following 'if' should work instead of
       
  2935                 // the above key event checking, but apparently
       
  2936                 // PeekMessage() is broken :-(
       
  2937                 if (mouseMsg.wParam != msg.wParam)
       
  2938                     break; // leave the message in the queue because
       
  2939                            // the key state has changed
       
  2940 #endif
       
  2941                 MSG *msgPtr = (MSG *)(&msg);
       
  2942                 // Update the passed in MSG structure with the
       
  2943                 // most recent one.
       
  2944                 msgPtr->lParam = mouseMsg.lParam;
       
  2945                 msgPtr->wParam = mouseMsg.wParam;
       
  2946                 msgPtr->pt = mouseMsg.pt;
       
  2947                 // Remove the mouse move message
       
  2948                 PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEMOVE,
       
  2949                             WM_MOUSEMOVE, PM_REMOVE);
       
  2950             } else {
       
  2951                 break; // there was no more WM_MOUSEMOVE event
       
  2952             }
       
  2953         }
       
  2954     }
       
  2955 
       
  2956     for (i=0; (UINT)mouseTbl[i] != msg.message && mouseTbl[i]; i += 3)
       
  2957         ;
       
  2958     if (!mouseTbl[i])
       
  2959         return false;
       
  2960     type   = (QEvent::Type)mouseTbl[++i];        // event type
       
  2961     button = mouseTbl[++i];                        // which button
       
  2962     if (button == Qt::XButton1) {
       
  2963         switch(GET_XBUTTON_WPARAM(msg.wParam)) {
       
  2964         case XBUTTON1:
       
  2965             button = Qt::XButton1;
       
  2966             break;
       
  2967         case XBUTTON2:
       
  2968             button = Qt::XButton2;
       
  2969             break;
       
  2970         }
       
  2971     }
       
  2972     state  = translateButtonState(msg.wParam, type, button); // button state
       
  2973     const QPoint widgetPos = mapFromGlobal(QPoint(msg.pt.x, msg.pt.y));
       
  2974     QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos);
       
  2975     if (alienWidget && alienWidget->internalWinId())
       
  2976         alienWidget = 0;
       
  2977 
       
  2978     if (type == QEvent::MouseMove || type == QEvent::NonClientAreaMouseMove
       
  2979             || type == QEvent::TabletMove) {
       
  2980 
       
  2981         if (!(state & Qt::MouseButtonMask))
       
  2982             qt_button_down = 0;
       
  2983 #ifndef QT_NO_CURSOR
       
  2984         QCursor *c = qt_grab_cursor();
       
  2985         if (!c)
       
  2986             c = QApplication::overrideCursor();
       
  2987         if (c)                                // application cursor defined
       
  2988             SetCursor(c->handle());
       
  2989         else if (type != QEvent::NonClientAreaMouseMove && !qt_button_down) {
       
  2990             // use  widget cursor if widget is enabled
       
  2991             QWidget *w = alienWidget ? alienWidget : this;
       
  2992             while (!w->isWindow() && !w->isEnabled())
       
  2993                 w = w->parentWidget();
       
  2994             SetCursor(w->cursor().handle());
       
  2995         }
       
  2996 #endif // QT_NO_CURSOR
       
  2997 
       
  2998         HWND id = effectiveWinId();
       
  2999         QWidget *mouseGrabber = QWidget::mouseGrabber();
       
  3000         QWidget *activePopupWidget = QApplication::activePopupWidget();
       
  3001         if (mouseGrabber) {
       
  3002             if (!activePopupWidget || (activePopupWidget == this && !rect().contains(widgetPos)))
       
  3003                 id = mouseGrabber->effectiveWinId();
       
  3004         } else if (type == QEvent::NonClientAreaMouseMove) {
       
  3005             id = 0;
       
  3006         }
       
  3007 
       
  3008         if (curWin != id) {                // new current window
       
  3009             if (id == 0) {
       
  3010                 QWidget *leave = qt_last_mouse_receiver;
       
  3011                 if (!leave)
       
  3012                     leave = QWidget::find(curWin);
       
  3013                 QApplicationPrivate::dispatchEnterLeave(0, leave);
       
  3014                 qt_last_mouse_receiver = 0;
       
  3015                 curWin = 0;
       
  3016             } else {
       
  3017                 QWidget *leave = 0;
       
  3018                 if (curWin && qt_last_mouse_receiver)
       
  3019                     leave = qt_last_mouse_receiver;
       
  3020                 else
       
  3021                     leave = QWidget::find(curWin);
       
  3022                 QWidget *enter = alienWidget ? alienWidget : this;
       
  3023                 if (mouseGrabber && activePopupWidget) {
       
  3024                     if (leave != mouseGrabber)
       
  3025                         enter = mouseGrabber;
       
  3026                     else
       
  3027                         enter = activePopupWidget == this ? this : mouseGrabber;
       
  3028                 }
       
  3029                 QApplicationPrivate::dispatchEnterLeave(enter, leave);
       
  3030                 qt_last_mouse_receiver = enter;
       
  3031                 curWin = enter ? enter->effectiveWinId() : 0;
       
  3032             }
       
  3033 #ifndef Q_OS_WINCE
       
  3034 
       
  3035             if (curWin != 0) {
       
  3036                 static bool trackMouseEventLookup = false;
       
  3037                 typedef BOOL (WINAPI *PtrTrackMouseEvent)(LPTRACKMOUSEEVENT);
       
  3038                 static PtrTrackMouseEvent ptrTrackMouseEvent = 0;
       
  3039                 if (!trackMouseEventLookup) {
       
  3040                     trackMouseEventLookup = true;
       
  3041                     ptrTrackMouseEvent = (PtrTrackMouseEvent)QLibrary::resolve(QLatin1String("comctl32"), "_TrackMouseEvent");
       
  3042                 }
       
  3043                 if (ptrTrackMouseEvent && !qApp->d_func()->inPopupMode()) {
       
  3044                     // We always have to set the tracking, since
       
  3045                     // Windows detects more leaves than we do..
       
  3046                     TRACKMOUSEEVENT tme;
       
  3047                     tme.cbSize = sizeof(TRACKMOUSEEVENT);
       
  3048                     tme.dwFlags = 0x00000002;    // TME_LEAVE
       
  3049                     tme.hwndTrack = curWin;      // Track on window receiving msgs
       
  3050                     tme.dwHoverTime = (DWORD)-1; // HOVER_DEFAULT
       
  3051                     ptrTrackMouseEvent(&tme);
       
  3052                 }
       
  3053             }
       
  3054 #endif // Q_OS_WINCE
       
  3055         }
       
  3056 
       
  3057         POINT curPos = msg.pt;
       
  3058         if (curPos.x == gpos.x && curPos.y == gpos.y)
       
  3059             return true;                        // same global position
       
  3060         gpos = curPos;
       
  3061 
       
  3062         Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
  3063         ScreenToClient(internalWinId(), &curPos);
       
  3064 
       
  3065         pos.rx() = curPos.x;
       
  3066         pos.ry() = curPos.y;
       
  3067         pos = d_func()->mapFromWS(pos);
       
  3068     } else {
       
  3069         gpos = msg.pt;
       
  3070         pos = mapFromGlobal(QPoint(gpos.x, gpos.y));
       
  3071 
       
  3072         // mouse button pressed
       
  3073         if (!qt_button_down && (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick)) {
       
  3074             QWidget *tlw = window();
       
  3075             if (QWidget *child = tlw->childAt(mapTo(tlw, pos)))
       
  3076                 qt_button_down = child;
       
  3077             else
       
  3078                 qt_button_down = this;
       
  3079         }
       
  3080     }
       
  3081 
       
  3082     bool res = false;
       
  3083 
       
  3084     bool nonClientAreaEvent = type >= QEvent::NonClientAreaMouseMove
       
  3085                                 && type <= QEvent::NonClientAreaMouseButtonDblClick;
       
  3086 
       
  3087     if (qApp->d_func()->inPopupMode()) {                        // in popup mode
       
  3088 
       
  3089         if (nonClientAreaEvent)
       
  3090             return false;
       
  3091 
       
  3092         replayPopupMouseEvent = false;
       
  3093         QWidget* activePopupWidget = QApplication::activePopupWidget();
       
  3094         QWidget *target = activePopupWidget;
       
  3095         const QPoint globalPos(gpos.x, gpos.y);
       
  3096 
       
  3097         if (target != this) {
       
  3098             if ((windowType() == Qt::Popup) && rect().contains(pos) && 0)
       
  3099                 target = this;
       
  3100             else                                // send to last popup
       
  3101                 pos = target->mapFromGlobal(globalPos);
       
  3102         }
       
  3103         QWidget *popupChild = target->childAt(pos);
       
  3104         bool releaseAfter = false;
       
  3105         switch (type) {
       
  3106             case QEvent::MouseButtonPress:
       
  3107             case QEvent::MouseButtonDblClick:
       
  3108                 popupButtonFocus = popupChild;
       
  3109                 break;
       
  3110             case QEvent::MouseButtonRelease:
       
  3111             case QEvent::TabletRelease:
       
  3112 
       
  3113                 releaseAfter = true;
       
  3114                 break;
       
  3115             default:
       
  3116                 break;                                // nothing for mouse move
       
  3117         }
       
  3118 
       
  3119         if (target->isEnabled()) {
       
  3120             if (popupButtonFocus) {
       
  3121                 target = popupButtonFocus;
       
  3122             } else if (popupChild) {
       
  3123                 target = popupChild;
       
  3124             }
       
  3125 
       
  3126             pos = target->mapFromGlobal(globalPos);
       
  3127                 QMouseEvent e(type, pos, globalPos,
       
  3128                             Qt::MouseButton(button),
       
  3129                             Qt::MouseButtons(state & Qt::MouseButtonMask),
       
  3130                             Qt::KeyboardModifiers(state & Qt::KeyboardModifierMask));
       
  3131                 res = QApplicationPrivate::sendMouseEvent(target, &e, alienWidget, this, &qt_button_down,
       
  3132                                                           qt_last_mouse_receiver);
       
  3133             res = res && e.isAccepted();
       
  3134         } else {
       
  3135             // close disabled popups when a mouse button is pressed or released
       
  3136             switch (type) {
       
  3137             case QEvent::MouseButtonPress:
       
  3138             case QEvent::MouseButtonDblClick:
       
  3139             case QEvent::MouseButtonRelease:
       
  3140                 target->close();
       
  3141                 break;
       
  3142             default:
       
  3143                 break;
       
  3144             }
       
  3145         }
       
  3146 
       
  3147         if (releaseAfter) {
       
  3148             popupButtonFocus = 0;
       
  3149             qt_button_down = 0;
       
  3150         }
       
  3151 
       
  3152         if (type == QEvent::MouseButtonPress
       
  3153             && QApplication::activePopupWidget() != activePopupWidget
       
  3154             && replayPopupMouseEvent) {
       
  3155             // the popup dissappeared. Replay the event
       
  3156             QWidget* w = QApplication::widgetAt(gpos.x, gpos.y);
       
  3157             if (w && !QApplicationPrivate::isBlockedByModal(w)) {
       
  3158                 Q_ASSERT(w->testAttribute(Qt::WA_WState_Created));
       
  3159                 HWND hwndTarget = w->effectiveWinId();
       
  3160                 if (QWidget::mouseGrabber() == 0)
       
  3161                     setAutoCapture(hwndTarget);
       
  3162                 if (!w->isActiveWindow())
       
  3163                     w->activateWindow();
       
  3164                 POINT widgetpt = gpos;
       
  3165                 ScreenToClient(hwndTarget, &widgetpt);
       
  3166                 LPARAM lParam = MAKELPARAM(widgetpt.x, widgetpt.y);
       
  3167                 PostMessage(hwndTarget, msg.message, msg.wParam, lParam);
       
  3168             }
       
  3169         } else if (type == QEvent::MouseButtonRelease && button == Qt::RightButton
       
  3170                 && QApplication::activePopupWidget() == activePopupWidget) {
       
  3171             // popup still alive and received right-button-release
       
  3172 #if !defined(QT_NO_CONTEXTMENU)
       
  3173             QContextMenuEvent e2(QContextMenuEvent::Mouse, pos, globalPos,
       
  3174                               qt_win_getKeyboardModifiers());
       
  3175             bool res2 = QApplication::sendSpontaneousEvent( target, &e2 );
       
  3176             if (!res) // RMB not accepted
       
  3177                 res = res2 && e2.isAccepted();
       
  3178 #endif
       
  3179         }
       
  3180     } else {                                        // not popup mode
       
  3181         int bs = state & Qt::MouseButtonMask;
       
  3182         if ((type == QEvent::MouseButtonPress ||
       
  3183               type == QEvent::MouseButtonDblClick) && bs == button) {
       
  3184             Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
  3185             if (QWidget::mouseGrabber() == 0)
       
  3186                 setAutoCapture(internalWinId());
       
  3187         } else if (type == QEvent::MouseButtonRelease && bs == 0) {
       
  3188             if (QWidget::mouseGrabber() == 0)
       
  3189                 releaseAutoCapture();
       
  3190         }
       
  3191 
       
  3192         const QPoint globalPos(gpos.x,gpos.y);
       
  3193         QWidget *widget = QApplicationPrivate::pickMouseReceiver(this, globalPos, pos, type,
       
  3194                                                                  Qt::MouseButtons(bs),
       
  3195                                                                  qt_button_down, alienWidget);
       
  3196         if (!widget)
       
  3197             return false; // don't send event
       
  3198 
       
  3199         QMouseEvent e(type, pos, globalPos, Qt::MouseButton(button),
       
  3200                       Qt::MouseButtons(state & Qt::MouseButtonMask),
       
  3201                       Qt::KeyboardModifiers(state & Qt::KeyboardModifierMask));
       
  3202 
       
  3203         res = QApplicationPrivate::sendMouseEvent(widget, &e, alienWidget, this, &qt_button_down,
       
  3204                                                   qt_last_mouse_receiver);
       
  3205 
       
  3206         // non client area events are only informational, you cannot "handle" them
       
  3207         res = res && e.isAccepted() && !nonClientAreaEvent;
       
  3208 #if !defined(QT_NO_CONTEXTMENU)
       
  3209         if (type == QEvent::MouseButtonRelease && button == Qt::RightButton) {
       
  3210             QContextMenuEvent e2(QContextMenuEvent::Mouse, pos, globalPos,
       
  3211                               qt_win_getKeyboardModifiers());
       
  3212             bool res2 = QApplication::sendSpontaneousEvent(widget, &e2);
       
  3213             if (!res)
       
  3214                 res = res2 && e2.isAccepted();
       
  3215         }
       
  3216 #endif
       
  3217 
       
  3218         if (type != QEvent::MouseMove)
       
  3219             pos.rx() = pos.ry() = -9999;        // init for move compression
       
  3220     }
       
  3221     return res;
       
  3222 }
       
  3223 
       
  3224 bool QETWidget::translateWheelEvent(const MSG &msg)
       
  3225 {
       
  3226     int  state = 0;
       
  3227 
       
  3228     if (sm_blockUserInput) // block user interaction during session management
       
  3229         return true;
       
  3230 
       
  3231     state = translateButtonState(GET_KEYSTATE_WPARAM(msg.wParam), 0, 0);
       
  3232 
       
  3233     int delta;
       
  3234     if (msg.message == WM_MOUSEWHEEL || msg.message == WM_MOUSEHWHEEL)
       
  3235         delta = (short) HIWORD (msg.wParam);
       
  3236     else
       
  3237         delta = (int) msg.wParam;
       
  3238 
       
  3239     Qt::Orientation orient = (msg.message == WM_MOUSEHWHEEL || state&Qt::AltModifier
       
  3240 #if 0
       
  3241     // disabled for now - Trenton's one-wheel mouse makes trouble...
       
  3242     // "delta" for usual wheels is +-120. +-240 seems to indicate
       
  3243     // the second wheel see more recent MSDN for WM_MOUSEWHEEL
       
  3244 
       
  3245     ( // <- parantheses added to make update happy, remove if the
       
  3246       // #if 0 is removed
       
  3247         || delta == 240 || delta == -240)?Qt::Horizontal:Vertical;
       
  3248     if (delta == 240 || delta == -240)
       
  3249         delta /= 2;
       
  3250 #endif
       
  3251        ) ? Qt::Horizontal : Qt::Vertical;
       
  3252 
       
  3253     // according to the MSDN documentation on WM_MOUSEHWHEEL:
       
  3254     // a positive value indicates that the wheel was rotated to the right;
       
  3255     // a negative value indicates that the wheel was rotated to the left.
       
  3256     // Qt defines this value as the exact opposite, so we have to flip the value!
       
  3257     if (msg.message == WM_MOUSEHWHEEL)
       
  3258         delta = -delta;
       
  3259 
       
  3260     QPoint globalPos;
       
  3261 
       
  3262     globalPos.rx() = (short)LOWORD (msg.lParam);
       
  3263     globalPos.ry() = (short)HIWORD (msg.lParam);
       
  3264 
       
  3265 
       
  3266     // if there is a widget under the mouse and it is not shadowed
       
  3267     // by modality, we send the event to it first
       
  3268     int ret = 0;
       
  3269     QWidget* w = QApplication::widgetAt(globalPos);
       
  3270     if (!w || !qt_try_modal(w, (MSG*)&msg, ret)) {
       
  3271         //synaptics touchpad shows its own widget at this position
       
  3272         //so widgetAt() will fail with that HWND, try child of this widget
       
  3273         w = this->childAt(this->mapFromGlobal(globalPos));
       
  3274         if (!w)
       
  3275             w = this;
       
  3276     }
       
  3277 
       
  3278     // send the event to the widget or its ancestors
       
  3279     {
       
  3280         QWidget* popup = QApplication::activePopupWidget();
       
  3281         if (popup && w->window() != popup)
       
  3282             popup->close();
       
  3283 #ifndef QT_NO_WHEELEVENT
       
  3284         QWheelEvent e(w->mapFromGlobal(globalPos), globalPos, delta,
       
  3285                       Qt::MouseButtons(state & Qt::MouseButtonMask),
       
  3286                       Qt::KeyboardModifier(state & Qt::KeyboardModifierMask), orient);
       
  3287 
       
  3288         if (QApplication::sendSpontaneousEvent(w, &e))
       
  3289 #else
       
  3290         Q_UNUSED(orient);
       
  3291 #endif //QT_NO_WHEELEVENT
       
  3292             return true;
       
  3293     }
       
  3294 
       
  3295     // send the event to the widget that has the focus or its ancestors, if different
       
  3296     if (w != QApplication::focusWidget() && (w = QApplication::focusWidget())) {
       
  3297         QWidget* popup = QApplication::activePopupWidget();
       
  3298         if (popup && w->window() != popup)
       
  3299             popup->close();
       
  3300 #ifndef QT_NO_WHEELEVENT
       
  3301         QWheelEvent e(w->mapFromGlobal(globalPos), globalPos, delta,
       
  3302                       Qt::MouseButtons(state & Qt::MouseButtonMask),
       
  3303                       Qt::KeyboardModifier(state & Qt::KeyboardModifierMask), orient);
       
  3304         if (QApplication::sendSpontaneousEvent(w, &e))
       
  3305 #endif //QT_NO_WHEELEVENT
       
  3306             return true;
       
  3307     }
       
  3308     return false;
       
  3309 }
       
  3310 
       
  3311 
       
  3312 //
       
  3313 // Windows Wintab to QTabletEvent translation
       
  3314 //
       
  3315 
       
  3316 // the following is adapted from the wintab syspress example (public domain)
       
  3317 /* -------------------------------------------------------------------------- */
       
  3318 static void tabletInit(UINT wActiveCsr, HCTX hTab)
       
  3319 {
       
  3320     /* browse WinTab's many info items to discover pressure handling. */
       
  3321     if (ptrWTInfo && ptrWTGet) {
       
  3322         AXIS np;
       
  3323         LOGCONTEXT lc;
       
  3324         BYTE wPrsBtn;
       
  3325         BYTE logBtns[32];
       
  3326         UINT size;
       
  3327 
       
  3328         /* discover the LOGICAL button generated by the pressure channel. */
       
  3329         /* get the PHYSICAL button from the cursor category and run it */
       
  3330         /* through that cursor's button map (usually the identity map). */
       
  3331         wPrsBtn = (BYTE)-1;
       
  3332         ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_NPBUTTON, &wPrsBtn);
       
  3333         size = ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_BUTTONMAP, &logBtns);
       
  3334         if ((UINT)wPrsBtn < size)
       
  3335             wPrsBtn = logBtns[wPrsBtn];
       
  3336 
       
  3337         /* get the current context for its device variable. */
       
  3338         ptrWTGet(hTab, &lc);
       
  3339 
       
  3340         /* get the size of the pressure axis. */
       
  3341         QTabletDeviceData tdd;
       
  3342         ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &np);
       
  3343         tdd.minPressure = int(np.axMin);
       
  3344         tdd.maxPressure = int(np.axMax);
       
  3345 
       
  3346         ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_TPRESSURE, &np);
       
  3347         tdd.minTanPressure = int(np.axMin);
       
  3348         tdd.maxTanPressure = int(np.axMax);
       
  3349 
       
  3350         LOGCONTEXT lcMine;
       
  3351 
       
  3352       	/* get default region */
       
  3353         ptrWTInfo(WTI_DEFCONTEXT, 0, &lcMine);
       
  3354 
       
  3355         tdd.minX = 0;
       
  3356         tdd.maxX = int(lcMine.lcInExtX) - int(lcMine.lcInOrgX);
       
  3357 
       
  3358         tdd.minY = 0;
       
  3359         tdd.maxY = int(lcMine.lcInExtY) - int(lcMine.lcInOrgY);
       
  3360 
       
  3361         tdd.minZ = 0;
       
  3362         tdd.maxZ = int(lcMine.lcInExtZ) - int(lcMine.lcInOrgZ);
       
  3363 
       
  3364         int csr_type,
       
  3365             csr_physid;
       
  3366         ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_TYPE, &csr_type);
       
  3367         ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_PHYSID, &csr_physid);
       
  3368         tdd.llId = csr_type & 0x0F06;
       
  3369         tdd.llId = (tdd.llId << 24) | csr_physid;
       
  3370 #ifndef QT_NO_TABLETEVENT
       
  3371         if (((csr_type & 0x0006) == 0x0002) && ((csr_type & 0x0F06) != 0x0902)) {
       
  3372             tdd.currentDevice = QTabletEvent::Stylus;
       
  3373         } else {
       
  3374             switch (csr_type & 0x0F06) {
       
  3375             case 0x0802:
       
  3376                 tdd.currentDevice = QTabletEvent::Stylus;
       
  3377                 break;
       
  3378             case 0x0902:
       
  3379                 tdd.currentDevice = QTabletEvent::Airbrush;
       
  3380                 break;
       
  3381             case 0x0004:
       
  3382                 tdd.currentDevice = QTabletEvent::FourDMouse;
       
  3383                 break;
       
  3384             case 0x0006:
       
  3385                 tdd.currentDevice = QTabletEvent::Puck;
       
  3386                 break;
       
  3387             case 0x0804:
       
  3388                 tdd.currentDevice = QTabletEvent::RotationStylus;
       
  3389                 break;
       
  3390             default:
       
  3391                 tdd.currentDevice = QTabletEvent::NoDevice;
       
  3392             }
       
  3393         }
       
  3394 
       
  3395         switch (wActiveCsr % 3) {
       
  3396         case 2:
       
  3397             tdd.currentPointerType = QTabletEvent::Eraser;
       
  3398             break;
       
  3399         case 1:
       
  3400             tdd.currentPointerType = QTabletEvent::Pen;
       
  3401             break;
       
  3402         case 0:
       
  3403             tdd.currentPointerType = QTabletEvent::Cursor;
       
  3404             break;
       
  3405         default:
       
  3406             tdd.currentPointerType = QTabletEvent::UnknownPointer;
       
  3407         }
       
  3408 #endif // QT_NO_TABLETEVENT
       
  3409         tCursorInfo()->insert(wActiveCsr, tdd);
       
  3410     }
       
  3411 }
       
  3412 
       
  3413 bool QETWidget::translateTabletEvent(const MSG &msg, PACKET *localPacketBuf,
       
  3414                                       int numPackets)
       
  3415 {
       
  3416     Q_UNUSED(msg);
       
  3417     POINT ptNew;
       
  3418     static DWORD btnNew, btnOld, btnChange;
       
  3419     qreal prsNew;
       
  3420     ORIENTATION ort;
       
  3421     static bool button_pressed = false;
       
  3422     int i,
       
  3423         tiltX,
       
  3424         tiltY;
       
  3425     bool sendEvent = false;
       
  3426     QEvent::Type t;
       
  3427     int z = 0;
       
  3428     qreal rotation = 0.0;
       
  3429     qreal tangentialPressure;
       
  3430 
       
  3431     // the most common event that we get...
       
  3432     t = QEvent::TabletMove;
       
  3433     for (i = 0; i < numPackets; i++) {
       
  3434         // get the unique ID of the device...
       
  3435         btnOld = btnNew;
       
  3436         btnNew = localPacketBuf[i].pkButtons;
       
  3437         btnChange = btnOld ^ btnNew;
       
  3438 
       
  3439         if (btnNew & btnChange) {
       
  3440             button_pressed = true;
       
  3441             t = QEvent::TabletPress;
       
  3442         }
       
  3443         ptNew.x = UINT(localPacketBuf[i].pkX);
       
  3444         ptNew.y = UINT(localPacketBuf[i].pkY);
       
  3445 #ifndef QT_NO_TABLETEVENT
       
  3446         z = (currentTabletPointer.currentDevice == QTabletEvent::FourDMouse) ? UINT(localPacketBuf[i].pkZ) : 0;
       
  3447 #else
       
  3448         Q_UNUSED(z);
       
  3449 #endif // QT_NO_TABLETEVENT
       
  3450         prsNew = 0.0;
       
  3451         QRect desktopArea = QApplication::desktop()->geometry();
       
  3452         QPointF hiResGlobal = currentTabletPointer.scaleCoord(ptNew.x, ptNew.y, desktopArea.left(),
       
  3453                                                               desktopArea.width(), desktopArea.top(),
       
  3454                                                               desktopArea.height());
       
  3455 
       
  3456         if (btnNew) {
       
  3457 #ifndef QT_NO_TABLETEVENT
       
  3458             if (currentTabletPointer.currentPointerType == QTabletEvent::Pen || currentTabletPointer.currentPointerType == QTabletEvent::Eraser)
       
  3459                 prsNew = localPacketBuf[i].pkNormalPressure
       
  3460                             / qreal(currentTabletPointer.maxPressure
       
  3461                                     - currentTabletPointer.minPressure);
       
  3462             else
       
  3463 #endif // QT_NO_TABLETEVENT
       
  3464                 prsNew = 0;
       
  3465         } else if (button_pressed) {
       
  3466             // One button press, should only give one button release
       
  3467             t = QEvent::TabletRelease;
       
  3468             button_pressed = false;
       
  3469         }
       
  3470         QPoint globalPos(qRound(hiResGlobal.x()), qRound(hiResGlobal.y()));
       
  3471 
       
  3472         if (t == QEvent::TabletPress)
       
  3473         {
       
  3474             qt_button_down = QApplication::widgetAt(globalPos);
       
  3475         }
       
  3476 
       
  3477         // make sure the tablet event get's sent to the proper widget...
       
  3478         QWidget *w = 0;
       
  3479 
       
  3480         if (qt_button_down)
       
  3481             w = qt_button_down; // Pass it to the thing that's grabbed it.
       
  3482         else
       
  3483             w = QApplication::widgetAt(globalPos);
       
  3484 
       
  3485         if (!w)
       
  3486             w = this;
       
  3487 
       
  3488         if (t == QEvent::TabletRelease)
       
  3489         {
       
  3490             if (qt_win_ignoreNextMouseReleaseEvent) {
       
  3491                 qt_win_ignoreNextMouseReleaseEvent = false;
       
  3492                 if (qt_button_down && qt_button_down->internalWinId() == autoCaptureWnd) {
       
  3493                     releaseAutoCapture();
       
  3494                     qt_button_down = 0;
       
  3495                 }
       
  3496             }
       
  3497 
       
  3498         }
       
  3499 
       
  3500         QPoint localPos = w->mapFromGlobal(globalPos);
       
  3501 #ifndef QT_NO_TABLETEVENT
       
  3502         if (currentTabletPointer.currentDevice == QTabletEvent::Airbrush) {
       
  3503             tangentialPressure = localPacketBuf[i].pkTangentPressure
       
  3504                                 / qreal(currentTabletPointer.maxTanPressure
       
  3505                                         - currentTabletPointer.minTanPressure);
       
  3506         } else {
       
  3507             tangentialPressure = 0.0;
       
  3508         }
       
  3509 #else
       
  3510         tangentialPressure = 0.0;
       
  3511 #endif // QT_NO_TABLETEVENT
       
  3512 
       
  3513         if (!qt_tablet_tilt_support) {
       
  3514             tiltX = tiltY = 0;
       
  3515             rotation = 0.0;
       
  3516         } else {
       
  3517             ort = localPacketBuf[i].pkOrientation;
       
  3518             // convert from azimuth and altitude to x tilt and y tilt
       
  3519             // what follows is the optimized version.  Here are the equations
       
  3520             // I used to get to this point (in case things change :)
       
  3521             // X = sin(azimuth) * cos(altitude)
       
  3522             // Y = cos(azimuth) * cos(altitude)
       
  3523             // Z = sin(altitude)
       
  3524             // X Tilt = arctan(X / Z)
       
  3525             // Y Tilt = arctan(Y / Z)
       
  3526             double radAzim = (ort.orAzimuth / 10) * (Q_PI / 180);
       
  3527             //double radAlt = abs(ort.orAltitude / 10) * (Q_PI / 180);
       
  3528             double tanAlt = tan((abs(ort.orAltitude / 10)) * (Q_PI / 180));
       
  3529 
       
  3530             double degX = atan(sin(radAzim) / tanAlt);
       
  3531             double degY = atan(cos(radAzim) / tanAlt);
       
  3532             tiltX = int(degX * (180 / Q_PI));
       
  3533             tiltY = int(-degY * (180 / Q_PI));
       
  3534             rotation = ort.orTwist;
       
  3535         }
       
  3536 #ifndef QT_NO_TABLETEVENT
       
  3537         QTabletEvent e(t, localPos, globalPos, hiResGlobal, currentTabletPointer.currentDevice,
       
  3538                        currentTabletPointer.currentPointerType, prsNew, tiltX, tiltY,
       
  3539                        tangentialPressure, rotation, z, QApplication::keyboardModifiers(), currentTabletPointer.llId);
       
  3540         sendEvent = QApplication::sendSpontaneousEvent(w, &e);
       
  3541 #endif // QT_NO_TABLETEVENT
       
  3542     }
       
  3543     return sendEvent;
       
  3544 }
       
  3545 
       
  3546 extern bool qt_is_gui_used;
       
  3547 static void initWinTabFunctions()
       
  3548 {
       
  3549 #if defined(Q_OS_WINCE)
       
  3550     return;
       
  3551 #else
       
  3552     if (!qt_is_gui_used)
       
  3553         return;
       
  3554 
       
  3555     QLibrary library(QLatin1String("wintab32"));
       
  3556     if (library.load()) {
       
  3557         ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW");
       
  3558         ptrWTGet = (PtrWTGet)library.resolve("WTGetW");
       
  3559         ptrWTEnable = (PtrWTEnable)library.resolve("WTEnable");
       
  3560         ptrWTOverlap = (PtrWTEnable)library.resolve("WTOverlap");
       
  3561         ptrWTPacketsGet = (PtrWTPacketsGet)library.resolve("WTPacketsGet");
       
  3562     }
       
  3563 #endif // Q_OS_WINCE
       
  3564 }
       
  3565 
       
  3566 
       
  3567 //
       
  3568 // Paint event translation
       
  3569 //
       
  3570 bool QETWidget::translatePaintEvent(const MSG &msg)
       
  3571 {
       
  3572     if (!isWindow() && testAttribute(Qt::WA_NativeWindow))
       
  3573         Q_ASSERT(internalWinId());
       
  3574 
       
  3575     Q_ASSERT(testAttribute(Qt::WA_WState_Created));
       
  3576     if (!GetUpdateRect(internalWinId(), 0, FALSE)) { // The update bounding rect is invalid
       
  3577         d_func()->hd = 0;
       
  3578         setAttribute(Qt::WA_PendingUpdate, false);
       
  3579         return false;
       
  3580     }
       
  3581 
       
  3582     if (msg.message == WM_ERASEBKGND)
       
  3583         return true;
       
  3584 
       
  3585     setAttribute(Qt::WA_PendingUpdate, false);
       
  3586     const QRegion dirtyInBackingStore(qt_dirtyRegion(this));
       
  3587     // Make sure the invalidated region contains the region we're about to repaint.
       
  3588     // BeginPaint will set the clip to the invalidated region and it is impossible
       
  3589     // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient
       
  3590     // as it may return an invalid context (especially on Windows Vista).
       
  3591     if (!dirtyInBackingStore.isEmpty())
       
  3592         InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false);
       
  3593     PAINTSTRUCT ps;
       
  3594     d_func()->hd = BeginPaint(internalWinId(), &ps);
       
  3595 
       
  3596     const QRect updateRect(QPoint(ps.rcPaint.left, ps.rcPaint.top),
       
  3597                            QPoint(ps.rcPaint.right, ps.rcPaint.bottom));
       
  3598 
       
  3599     // Mapping region from system to qt (32 bit) coordinate system.
       
  3600     d_func()->syncBackingStore(updateRect.translated(data->wrect.topLeft()));
       
  3601 
       
  3602     d_func()->hd = 0;
       
  3603     EndPaint(internalWinId(), &ps);
       
  3604 
       
  3605     return true;
       
  3606 }
       
  3607 
       
  3608 //
       
  3609 // Window move and resize (configure) events
       
  3610 //
       
  3611 
       
  3612 bool QETWidget::translateConfigEvent(const MSG &msg)
       
  3613 {
       
  3614     if (!testAttribute(Qt::WA_WState_Created))                // in QWidget::create()
       
  3615         return true;
       
  3616     if (testAttribute(Qt::WA_WState_ConfigPending))
       
  3617         return true;
       
  3618     if (testAttribute(Qt::WA_DontShowOnScreen))
       
  3619         return true;
       
  3620     if (!isWindow())
       
  3621         return true;
       
  3622     setAttribute(Qt::WA_WState_ConfigPending);                // set config flag
       
  3623     QRect cr = geometry();
       
  3624     if (msg.message == WM_SIZE) {                // resize event
       
  3625         WORD a = LOWORD(msg.lParam);
       
  3626         WORD b = HIWORD(msg.lParam);
       
  3627         QSize oldSize = size();
       
  3628         QSize newSize(a, b);
       
  3629 #ifdef Q_WS_WINCE_WM
       
  3630         if (isFullScreen() && (oldSize.width() == newSize.height()) && (oldSize.height() == newSize.width()))
       
  3631             qt_wince_hide_taskbar(internalWinId());
       
  3632 #endif
       
  3633         cr.setSize(newSize);
       
  3634         if (msg.wParam != SIZE_MINIMIZED)
       
  3635             data->crect = cr;
       
  3636         if (isWindow()) {                        // update title/icon text
       
  3637             d_func()->createTLExtra();
       
  3638             // Capture SIZE_MINIMIZED without preceding WM_SYSCOMMAND
       
  3639             // (like Windows+M)
       
  3640             if (msg.wParam == SIZE_MINIMIZED && !isMinimized()) {
       
  3641 #ifndef Q_WS_WINCE
       
  3642                 const QString title = windowIconText();
       
  3643                 if (!title.isEmpty())
       
  3644                     d_func()->setWindowTitle_helper(title);
       
  3645 #endif
       
  3646                 data->window_state |= Qt::WindowMinimized;
       
  3647                 if (isVisible()) {
       
  3648                     QHideEvent e;
       
  3649                     QApplication::sendSpontaneousEvent(this, &e);
       
  3650                     hideChildren(true);
       
  3651                 }
       
  3652             } else if (msg.wParam != SIZE_MINIMIZED && isMinimized()) {
       
  3653 #ifndef Q_WS_WINCE
       
  3654                 const QString title = windowTitle();
       
  3655                 if (!title.isEmpty())
       
  3656                     d_func()->setWindowTitle_helper(title);
       
  3657 #endif
       
  3658                 data->window_state &= ~Qt::WindowMinimized;
       
  3659                 showChildren(true);
       
  3660                 QShowEvent e;
       
  3661                 QApplication::sendSpontaneousEvent(this, &e);
       
  3662             }
       
  3663         }
       
  3664         if (msg.wParam != SIZE_MINIMIZED && oldSize != newSize) {
       
  3665             if (isVisible()) {
       
  3666                 QTLWExtra *tlwExtra = maybeTopData();
       
  3667                 static bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
       
  3668                 const bool hasStaticContents = tlwExtra && tlwExtra->backingStore
       
  3669                                                && tlwExtra->backingStore->hasStaticContents();
       
  3670                 // If we have a backing store with static contents, we have to disable the top-level
       
  3671                 // resize optimization in order to get invalidated regions for resized widgets.
       
  3672                 // The optimization discards all invalidateBuffer() calls since we're going to
       
  3673                 // repaint everything anyways, but that's not the case with static contents.
       
  3674                 if (!slowResize && tlwExtra && !hasStaticContents)
       
  3675                     tlwExtra->inTopLevelResize = true;
       
  3676                 QResizeEvent e(newSize, oldSize);
       
  3677                 QApplication::sendSpontaneousEvent(this, &e);
       
  3678                 if (d_func()->paintOnScreen()) {
       
  3679                     QRegion updateRegion(rect());
       
  3680                     if (testAttribute(Qt::WA_StaticContents))
       
  3681                         updateRegion -= QRect(0, 0, oldSize.width(), oldSize.height());
       
  3682                     d_func()->syncBackingStore(updateRegion);
       
  3683                 } else {
       
  3684                     d_func()->syncBackingStore();
       
  3685                 }
       
  3686                 if (!slowResize && tlwExtra)
       
  3687                     tlwExtra->inTopLevelResize = false;
       
  3688             } else {
       
  3689                 QResizeEvent *e = new QResizeEvent(newSize, oldSize);
       
  3690                 QApplication::postEvent(this, e);
       
  3691             }
       
  3692         }
       
  3693 } else if (msg.message == WM_MOVE) {        // move event
       
  3694         int a = (int) (short) LOWORD(msg.lParam);
       
  3695         int b = (int) (short) HIWORD(msg.lParam);
       
  3696         QPoint oldPos = geometry().topLeft();
       
  3697         QPoint newCPos(a, b);
       
  3698         // Ignore silly Windows move event to wild pos after iconify.
       
  3699 #if !defined(Q_WS_WINCE)
       
  3700         if (!IsIconic(internalWinId()) && newCPos != oldPos) {
       
  3701 #endif
       
  3702             cr.moveTopLeft(newCPos);
       
  3703             data->crect = cr;
       
  3704             if (isVisible()) {
       
  3705                 QMoveEvent e(newCPos, oldPos);  // cpos (client position)
       
  3706                 QApplication::sendSpontaneousEvent(this, &e);
       
  3707             } else {
       
  3708                 QMoveEvent * e = new QMoveEvent(newCPos, oldPos);
       
  3709                 QApplication::postEvent(this, e);
       
  3710             }
       
  3711 #if !defined(Q_WS_WINCE)
       
  3712         }
       
  3713 #endif
       
  3714     }
       
  3715     setAttribute(Qt::WA_WState_ConfigPending, false);                // clear config flag
       
  3716     return true;
       
  3717 }
       
  3718 
       
  3719 
       
  3720 //
       
  3721 // Close window event translation.
       
  3722 //
       
  3723 // This class is a friend of QApplication because it needs to emit the
       
  3724 // lastWindowClosed() signal when the last top level widget is closed.
       
  3725 //
       
  3726 
       
  3727 bool QETWidget::translateCloseEvent(const MSG &)
       
  3728 {
       
  3729     return d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
       
  3730 }
       
  3731 
       
  3732 bool QETWidget::translateGestureEvent(const MSG &, const GESTUREINFO &gi)
       
  3733 {
       
  3734     const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y);
       
  3735     QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos);
       
  3736     if (alienWidget && alienWidget->internalWinId())
       
  3737         alienWidget = 0;
       
  3738     QWidget *widget = alienWidget ? alienWidget : this;
       
  3739 
       
  3740     QNativeGestureEvent event;
       
  3741     event.sequenceId = gi.dwSequenceID;
       
  3742     event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y);
       
  3743     event.argument = gi.ullArguments;
       
  3744 
       
  3745     switch (gi.dwID) {
       
  3746     case GID_BEGIN:
       
  3747         event.gestureType = QNativeGestureEvent::GestureBegin;
       
  3748         break;
       
  3749     case GID_END:
       
  3750         event.gestureType = QNativeGestureEvent::GestureEnd;
       
  3751         break;
       
  3752     case GID_ZOOM:
       
  3753         event.gestureType = QNativeGestureEvent::Zoom;
       
  3754         break;
       
  3755     case GID_PAN:
       
  3756         event.gestureType = QNativeGestureEvent::Pan;
       
  3757         break;
       
  3758     case GID_ROTATE:
       
  3759         event.gestureType = QNativeGestureEvent::Rotate;
       
  3760         break;
       
  3761     case GID_TWOFINGERTAP:
       
  3762     case GID_ROLLOVER:
       
  3763     default:
       
  3764         break;
       
  3765     }
       
  3766     if (event.gestureType != QNativeGestureEvent::None)
       
  3767         qt_sendSpontaneousEvent(widget, &event);
       
  3768     return true;
       
  3769 }
       
  3770 
       
  3771 
       
  3772 void  QApplication::setCursorFlashTime(int msecs)
       
  3773 {
       
  3774     SetCaretBlinkTime(msecs / 2);
       
  3775     QApplicationPrivate::cursor_flash_time = msecs;
       
  3776 }
       
  3777 
       
  3778 
       
  3779 int QApplication::cursorFlashTime()
       
  3780 {
       
  3781     int blink = (int)GetCaretBlinkTime();
       
  3782     if (!blink)
       
  3783         return QApplicationPrivate::cursor_flash_time;
       
  3784     if (blink > 0)
       
  3785         return 2*blink;
       
  3786     return 0;
       
  3787 }
       
  3788 
       
  3789 
       
  3790 void QApplication::setDoubleClickInterval(int ms)
       
  3791 {
       
  3792 #ifndef Q_WS_WINCE
       
  3793     SetDoubleClickTime(ms);
       
  3794 #endif
       
  3795     QApplicationPrivate::mouse_double_click_time = ms;
       
  3796 }
       
  3797 
       
  3798 int QApplication::doubleClickInterval()
       
  3799 {
       
  3800     int ms = GetDoubleClickTime();
       
  3801     if (ms != 0)
       
  3802         return ms;
       
  3803     return QApplicationPrivate::mouse_double_click_time;
       
  3804 }
       
  3805 
       
  3806 
       
  3807 void QApplication::setKeyboardInputInterval(int ms)
       
  3808 {
       
  3809     QApplicationPrivate::keyboard_input_time = ms;
       
  3810 }
       
  3811 
       
  3812 int QApplication::keyboardInputInterval()
       
  3813 {
       
  3814     // FIXME: get from the system
       
  3815     return QApplicationPrivate::keyboard_input_time;
       
  3816 }
       
  3817 
       
  3818 #ifndef QT_NO_WHEELEVENT
       
  3819 void QApplication::setWheelScrollLines(int n)
       
  3820 {
       
  3821 #ifdef SPI_SETWHEELSCROLLLINES
       
  3822     if (n < 0)
       
  3823         n = 0;
       
  3824     SystemParametersInfo(SPI_SETWHEELSCROLLLINES, (uint)n, 0, 0);
       
  3825 #else
       
  3826     QApplicationPrivate::wheel_scroll_lines = n;
       
  3827 #endif
       
  3828 }
       
  3829 
       
  3830 int QApplication::wheelScrollLines()
       
  3831 {
       
  3832 #ifdef SPI_GETWHEELSCROLLLINES
       
  3833     uint i = 3;
       
  3834     SystemParametersInfo(SPI_GETWHEELSCROLLLINES, sizeof(uint), &i, 0);
       
  3835     if (i > INT_MAX)
       
  3836         i = INT_MAX;
       
  3837     return i;
       
  3838 #else
       
  3839     return QApplicationPrivate::wheel_scroll_lines;
       
  3840 #endif
       
  3841 }
       
  3842 #endif //QT_NO_WHEELEVENT
       
  3843 
       
  3844 static bool effect_override = false;
       
  3845 
       
  3846 void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
       
  3847 {
       
  3848     effect_override = true;
       
  3849     switch (effect) {
       
  3850     case Qt::UI_AnimateMenu:
       
  3851         QApplicationPrivate::animate_menu = enable;
       
  3852         break;
       
  3853     case Qt::UI_FadeMenu:
       
  3854         QApplicationPrivate::fade_menu = enable;
       
  3855         break;
       
  3856     case Qt::UI_AnimateCombo:
       
  3857         QApplicationPrivate::animate_combo = enable;
       
  3858         break;
       
  3859     case Qt::UI_AnimateTooltip:
       
  3860         QApplicationPrivate::animate_tooltip = enable;
       
  3861         break;
       
  3862     case Qt::UI_FadeTooltip:
       
  3863         QApplicationPrivate::fade_tooltip = enable;
       
  3864         break;
       
  3865     case Qt::UI_AnimateToolBox:
       
  3866         QApplicationPrivate::animate_toolbox = enable;
       
  3867         break;
       
  3868     default:
       
  3869         QApplicationPrivate::animate_ui = enable;
       
  3870         break;
       
  3871     }
       
  3872 }
       
  3873 
       
  3874 bool QApplication::isEffectEnabled(Qt::UIEffect effect)
       
  3875 {
       
  3876     if (QColormap::instance().depth() < 16)
       
  3877         return false;
       
  3878 
       
  3879     if (!effect_override && desktopSettingsAware()) {
       
  3880         // we know that they can be used when we are here
       
  3881         BOOL enabled = false;
       
  3882         UINT api;
       
  3883         switch (effect) {
       
  3884         case Qt::UI_AnimateMenu:
       
  3885             api = SPI_GETMENUANIMATION;
       
  3886             break;
       
  3887         case Qt::UI_FadeMenu:
       
  3888             api = SPI_GETMENUFADE;
       
  3889             break;
       
  3890         case Qt::UI_AnimateCombo:
       
  3891             api = SPI_GETCOMBOBOXANIMATION;
       
  3892             break;
       
  3893         case Qt::UI_AnimateTooltip:
       
  3894             api = SPI_GETTOOLTIPANIMATION;
       
  3895             break;
       
  3896         case Qt::UI_FadeTooltip:
       
  3897             api = SPI_GETTOOLTIPFADE;
       
  3898             break;
       
  3899         default:
       
  3900             api = SPI_GETUIEFFECTS;
       
  3901             break;
       
  3902         }
       
  3903         SystemParametersInfo(api, 0, &enabled, 0);
       
  3904         return enabled;
       
  3905     }
       
  3906 
       
  3907     switch(effect) {
       
  3908     case Qt::UI_AnimateMenu:
       
  3909         return QApplicationPrivate::animate_menu;
       
  3910     case Qt::UI_FadeMenu:
       
  3911         return QApplicationPrivate::fade_menu;
       
  3912     case Qt::UI_AnimateCombo:
       
  3913         return QApplicationPrivate::animate_combo;
       
  3914     case Qt::UI_AnimateTooltip:
       
  3915         return QApplicationPrivate::animate_tooltip;
       
  3916     case Qt::UI_FadeTooltip:
       
  3917         return QApplicationPrivate::fade_tooltip;
       
  3918     case Qt::UI_AnimateToolBox:
       
  3919         return QApplicationPrivate::animate_toolbox;
       
  3920     default:
       
  3921         return QApplicationPrivate::animate_ui;
       
  3922     }
       
  3923 }
       
  3924 
       
  3925 #ifndef QT_NO_SESSIONMANAGER
       
  3926 
       
  3927 bool QSessionManager::allowsInteraction()
       
  3928 {
       
  3929     sm_blockUserInput = false;
       
  3930     return true;
       
  3931 }
       
  3932 
       
  3933 bool QSessionManager::allowsErrorInteraction()
       
  3934 {
       
  3935     sm_blockUserInput = false;
       
  3936     return true;
       
  3937 }
       
  3938 
       
  3939 void QSessionManager::release()
       
  3940 {
       
  3941     if (sm_smActive)
       
  3942         sm_blockUserInput = true;
       
  3943 }
       
  3944 
       
  3945 void QSessionManager::cancel()
       
  3946 {
       
  3947     sm_cancel = true;
       
  3948 }
       
  3949 
       
  3950 #endif //QT_NO_SESSIONMANAGER
       
  3951 
       
  3952 
       
  3953 PtrRegisterTouchWindow QApplicationPrivate::RegisterTouchWindow = 0;
       
  3954 PtrGetTouchInputInfo QApplicationPrivate::GetTouchInputInfo = 0;
       
  3955 PtrCloseTouchInputHandle QApplicationPrivate::CloseTouchInputHandle = 0;
       
  3956 
       
  3957 void QApplicationPrivate::initializeMultitouch_sys()
       
  3958 {
       
  3959     QLibrary library(QLatin1String("user32"));
       
  3960     // MinGW (g++ 3.4.5) accepts only C casts.
       
  3961     RegisterTouchWindow = (PtrRegisterTouchWindow)(library.resolve("RegisterTouchWindow"));
       
  3962     GetTouchInputInfo = (PtrGetTouchInputInfo)(library.resolve("GetTouchInputInfo"));
       
  3963     CloseTouchInputHandle = (PtrCloseTouchInputHandle)(library.resolve("CloseTouchInputHandle"));
       
  3964 
       
  3965     touchInputIDToTouchPointID.clear();
       
  3966 }
       
  3967 
       
  3968 void QApplicationPrivate::cleanupMultitouch_sys()
       
  3969 {
       
  3970     touchInputIDToTouchPointID.clear();
       
  3971 }
       
  3972 
       
  3973 bool QApplicationPrivate::translateTouchEvent(const MSG &msg)
       
  3974 {
       
  3975     QWidget *widgetForHwnd = QWidget::find(msg.hwnd);
       
  3976     if (!widgetForHwnd)
       
  3977         return false;
       
  3978 
       
  3979     QRect screenGeometry = QApplication::desktop()->screenGeometry(widgetForHwnd);
       
  3980 
       
  3981     QList<QTouchEvent::TouchPoint> touchPoints;
       
  3982 
       
  3983     QVector<TOUCHINPUT> winTouchInputs(msg.wParam);
       
  3984     memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * winTouchInputs.count());
       
  3985     Qt::TouchPointStates allStates = 0;
       
  3986     QApplicationPrivate::GetTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT));
       
  3987     for (int i = 0; i < winTouchInputs.count(); ++i) {
       
  3988         const TOUCHINPUT &touchInput = winTouchInputs.at(i);
       
  3989 
       
  3990         int touchPointID = touchInputIDToTouchPointID.value(touchInput.dwID, -1);
       
  3991         if (touchPointID == -1) {
       
  3992             touchPointID = touchInputIDToTouchPointID.count();
       
  3993             touchInputIDToTouchPointID.insert(touchInput.dwID, touchPointID);
       
  3994         }
       
  3995 
       
  3996         QTouchEvent::TouchPoint touchPoint(touchPointID);
       
  3997 
       
  3998         // update state
       
  3999         QPointF screenPos(qreal(touchInput.x) / qreal(100.), qreal(touchInput.y) / qreal(100.));
       
  4000         QRectF screenRect;
       
  4001         if (touchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA)
       
  4002             screenRect.setSize(QSizeF(qreal(touchInput.cxContact) / qreal(100.),
       
  4003                                       qreal(touchInput.cyContact) / qreal(100.)));
       
  4004         screenRect.moveCenter(screenPos);
       
  4005 
       
  4006         Qt::TouchPointStates state;
       
  4007         if (touchInput.dwFlags & TOUCHEVENTF_DOWN) {
       
  4008             state = Qt::TouchPointPressed;
       
  4009         } else if (touchInput.dwFlags & TOUCHEVENTF_UP) {
       
  4010             state = Qt::TouchPointReleased;
       
  4011         } else {
       
  4012             state = (screenPos == touchPoint.screenPos()
       
  4013                      ? Qt::TouchPointStationary
       
  4014                      : Qt::TouchPointMoved);
       
  4015         }
       
  4016         if (touchInput.dwFlags & TOUCHEVENTF_PRIMARY)
       
  4017             state |= Qt::TouchPointPrimary;
       
  4018         touchPoint.setState(state);
       
  4019         touchPoint.setScreenRect(screenRect);
       
  4020         touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(),
       
  4021                                             screenPos.y() / screenGeometry.height()));
       
  4022 
       
  4023         allStates |= state;
       
  4024 
       
  4025         touchPoints.append(touchPoint);
       
  4026     }
       
  4027     QApplicationPrivate::CloseTouchInputHandle((HANDLE) msg.lParam);
       
  4028 
       
  4029     if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) {
       
  4030         // all touch points released, forget the ids we've seen, they may not be reused
       
  4031         touchInputIDToTouchPointID.clear();
       
  4032     }
       
  4033 
       
  4034     translateRawTouchEvent(widgetForHwnd, QTouchEvent::TouchScreen, touchPoints);
       
  4035     return true;
       
  4036 }
       
  4037 
       
  4038 QT_END_NAMESPACE