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