1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup GHOST
22  * Declaration of GHOST_WindowWin32 class.
23  */
24 
25 #pragma once
26 
27 #ifndef WIN32
28 #  error WIN32 only!
29 #endif  // WIN32
30 
31 #include "GHOST_TaskbarWin32.h"
32 #include "GHOST_Window.h"
33 #ifdef WITH_INPUT_IME
34 #  include "GHOST_ImeWin32.h"
35 #endif
36 
37 #include <vector>
38 
39 #include <wintab.h>
40 #define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
41 #define PACKETMODE PK_BUTTONS
42 #include <pktdef.h>
43 
44 class GHOST_SystemWin32;
45 class GHOST_DropTargetWin32;
46 
47 // typedefs for WinTab functions to allow dynamic loading
48 typedef UINT(API *GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
49 typedef HCTX(API *GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
50 typedef BOOL(API *GHOST_WIN32_WTClose)(HCTX);
51 typedef BOOL(API *GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
52 typedef BOOL(API *GHOST_WIN32_WTEnable)(HCTX, BOOL);
53 typedef BOOL(API *GHOST_WIN32_WTOverlap)(HCTX, BOOL);
54 
55 // typedef to user32 functions to disable gestures on windows
56 typedef BOOL(API *GHOST_WIN32_RegisterTouchWindow)(HWND hwnd, ULONG ulFlags);
57 
58 // typedefs for user32 functions to allow dynamic loading of Windows 10 DPI scaling functions
59 typedef UINT(API *GHOST_WIN32_GetDpiForWindow)(HWND);
60 #ifndef USER_DEFAULT_SCREEN_DPI
61 #  define USER_DEFAULT_SCREEN_DPI 96
62 #endif  // USER_DEFAULT_SCREEN_DPI
63 
64 // typedefs for user32 functions to allow pointer functions
65 enum tagPOINTER_INPUT_TYPE {
66   PT_POINTER = 1,  // Generic pointer
67   PT_TOUCH = 2,    // Touch
68   PT_PEN = 3,      // Pen
69   PT_MOUSE = 4,    // Mouse
70 #if (WINVER >= 0x0603)
71   PT_TOUCHPAD = 5,  // Touchpad
72 #endif              /* WINVER >= 0x0603 */
73 };
74 
75 typedef enum tagPOINTER_BUTTON_CHANGE_TYPE {
76   POINTER_CHANGE_NONE,
77   POINTER_CHANGE_FIRSTBUTTON_DOWN,
78   POINTER_CHANGE_FIRSTBUTTON_UP,
79   POINTER_CHANGE_SECONDBUTTON_DOWN,
80   POINTER_CHANGE_SECONDBUTTON_UP,
81   POINTER_CHANGE_THIRDBUTTON_DOWN,
82   POINTER_CHANGE_THIRDBUTTON_UP,
83   POINTER_CHANGE_FOURTHBUTTON_DOWN,
84   POINTER_CHANGE_FOURTHBUTTON_UP,
85   POINTER_CHANGE_FIFTHBUTTON_DOWN,
86   POINTER_CHANGE_FIFTHBUTTON_UP,
87 } POINTER_BUTTON_CHANGE_TYPE;
88 
89 typedef DWORD POINTER_INPUT_TYPE;
90 typedef UINT32 POINTER_FLAGS;
91 
92 #define POINTER_FLAG_NONE 0x00000000
93 #define POINTER_FLAG_NEW 0x00000001
94 #define POINTER_FLAG_INRANGE 0x00000002
95 #define POINTER_FLAG_INCONTACT 0x00000004
96 #define POINTER_FLAG_FIRSTBUTTON 0x00000010
97 #define POINTER_FLAG_SECONDBUTTON 0x00000020
98 #define POINTER_FLAG_THIRDBUTTON 0x00000040
99 #define POINTER_FLAG_FOURTHBUTTON 0x00000080
100 #define POINTER_FLAG_FIFTHBUTTON 0x00000100
101 #define POINTER_FLAG_PRIMARY 0x00002000
102 #define POINTER_FLAG_CONFIDENCE 0x000004000
103 #define POINTER_FLAG_CANCELED 0x000008000
104 #define POINTER_FLAG_DOWN 0x00010000
105 #define POINTER_FLAG_UPDATE 0x00020000
106 #define POINTER_FLAG_UP 0x00040000
107 #define POINTER_FLAG_WHEEL 0x00080000
108 #define POINTER_FLAG_HWHEEL 0x00100000
109 #define POINTER_FLAG_CAPTURECHANGED 0x00200000
110 #define POINTER_FLAG_HASTRANSFORM 0x00400000
111 
112 typedef struct tagPOINTER_INFO {
113   POINTER_INPUT_TYPE pointerType;
114   UINT32 pointerId;
115   UINT32 frameId;
116   POINTER_FLAGS pointerFlags;
117   HANDLE sourceDevice;
118   HWND hwndTarget;
119   POINT ptPixelLocation;
120   POINT ptHimetricLocation;
121   POINT ptPixelLocationRaw;
122   POINT ptHimetricLocationRaw;
123   DWORD dwTime;
124   UINT32 historyCount;
125   INT32 InputData;
126   DWORD dwKeyStates;
127   UINT64 PerformanceCount;
128   POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
129 } POINTER_INFO;
130 
131 typedef UINT32 PEN_FLAGS;
132 #define PEN_FLAG_NONE 0x00000000      // Default
133 #define PEN_FLAG_BARREL 0x00000001    // The barrel button is pressed
134 #define PEN_FLAG_INVERTED 0x00000002  // The pen is inverted
135 #define PEN_FLAG_ERASER 0x00000004    // The eraser button is pressed
136 
137 typedef UINT32 PEN_MASK;
138 #define PEN_MASK_NONE 0x00000000      // Default - none of the optional fields are valid
139 #define PEN_MASK_PRESSURE 0x00000001  // The pressure field is valid
140 #define PEN_MASK_ROTATION 0x00000002  // The rotation field is valid
141 #define PEN_MASK_TILT_X 0x00000004    // The tiltX field is valid
142 #define PEN_MASK_TILT_Y 0x00000008    // The tiltY field is valid
143 
144 typedef struct tagPOINTER_PEN_INFO {
145   POINTER_INFO pointerInfo;
146   PEN_FLAGS penFlags;
147   PEN_MASK penMask;
148   UINT32 pressure;
149   UINT32 rotation;
150   INT32 tiltX;
151   INT32 tiltY;
152 } POINTER_PEN_INFO;
153 
154 /*
155  * Flags that appear in pointer input message parameters
156  */
157 #define POINTER_MESSAGE_FLAG_NEW 0x00000001           // New pointer
158 #define POINTER_MESSAGE_FLAG_INRANGE 0x00000002       // Pointer has not departed
159 #define POINTER_MESSAGE_FLAG_INCONTACT 0x00000004     // Pointer is in contact
160 #define POINTER_MESSAGE_FLAG_FIRSTBUTTON 0x00000010   // Primary action
161 #define POINTER_MESSAGE_FLAG_SECONDBUTTON 0x00000020  // Secondary action
162 #define POINTER_MESSAGE_FLAG_THIRDBUTTON 0x00000040   // Third button
163 #define POINTER_MESSAGE_FLAG_FOURTHBUTTON 0x00000080  // Fourth button
164 #define POINTER_MESSAGE_FLAG_FIFTHBUTTON 0x00000100   // Fifth button
165 #define POINTER_MESSAGE_FLAG_PRIMARY 0x00002000       // Pointer is primary
166 #define POINTER_MESSAGE_FLAG_CONFIDENCE \
167   0x00004000  // Pointer is considered unlikely to be accidental
168 #define POINTER_MESSAGE_FLAG_CANCELED 0x00008000  // Pointer is departing in an abnormal manner
169 
170 typedef UINT32 TOUCH_FLAGS;
171 #define TOUCH_FLAG_NONE 0x00000000  // Default
172 
173 typedef UINT32 TOUCH_MASK;
174 #define TOUCH_MASK_NONE 0x00000000         // Default - none of the optional fields are valid
175 #define TOUCH_MASK_CONTACTAREA 0x00000001  // The rcContact field is valid
176 #define TOUCH_MASK_ORIENTATION 0x00000002  // The orientation field is valid
177 #define TOUCH_MASK_PRESSURE 0x00000004     // The pressure field is valid
178 
179 typedef struct tagPOINTER_TOUCH_INFO {
180   POINTER_INFO pointerInfo;
181   TOUCH_FLAGS touchFlags;
182   TOUCH_MASK touchMask;
183   RECT rcContact;
184   RECT rcContactRaw;
185   UINT32 orientation;
186   UINT32 pressure;
187 } POINTER_TOUCH_INFO;
188 
189 /*
190  * Macros to retrieve information from pointer input message parameters
191  */
192 #define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
193 #define IS_POINTER_FLAG_SET_WPARAM(wParam, flag) (((DWORD)HIWORD(wParam) & (flag)) == (flag))
194 #define IS_POINTER_NEW_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_NEW)
195 #define IS_POINTER_INRANGE_WPARAM(wParam) \
196   IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INRANGE)
197 #define IS_POINTER_INCONTACT_WPARAM(wParam) \
198   IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INCONTACT)
199 #define IS_POINTER_FIRSTBUTTON_WPARAM(wParam) \
200   IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIRSTBUTTON)
201 #define IS_POINTER_SECONDBUTTON_WPARAM(wParam) \
202   IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_SECONDBUTTON)
203 #define IS_POINTER_THIRDBUTTON_WPARAM(wParam) \
204   IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_THIRDBUTTON)
205 #define IS_POINTER_FOURTHBUTTON_WPARAM(wParam) \
206   IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FOURTHBUTTON)
207 #define IS_POINTER_FIFTHBUTTON_WPARAM(wParam) \
208   IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIFTHBUTTON)
209 #define IS_POINTER_PRIMARY_WPARAM(wParam) \
210   IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_PRIMARY)
211 #define HAS_POINTER_CONFIDENCE_WPARAM(wParam) \
212   IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CONFIDENCE)
213 #define IS_POINTER_CANCELED_WPARAM(wParam) \
214   IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CANCELED)
215 
216 typedef BOOL(WINAPI *GHOST_WIN32_GetPointerInfoHistory)(UINT32 pointerId,
217                                                         UINT32 *entriesCount,
218                                                         POINTER_INFO *pointerInfo);
219 typedef BOOL(WINAPI *GHOST_WIN32_GetPointerPenInfoHistory)(UINT32 pointerId,
220                                                            UINT32 *entriesCount,
221                                                            POINTER_PEN_INFO *penInfo);
222 typedef BOOL(WINAPI *GHOST_WIN32_GetPointerTouchInfoHistory)(UINT32 pointerId,
223                                                              UINT32 *entriesCount,
224                                                              POINTER_TOUCH_INFO *touchInfo);
225 
226 struct GHOST_PointerInfoWin32 {
227   GHOST_TInt32 pointerId;
228   GHOST_TInt32 isPrimary;
229   GHOST_TButtonMask buttonMask;
230   POINT pixelLocation;
231   GHOST_TUns64 time;
232 
233   GHOST_TabletData tabletData;
234 };
235 
236 typedef enum {
237   MousePressed,
238   MouseReleased,
239   OperatorGrab,
240   OperatorUngrab
241 } GHOST_MouseCaptureEventWin32;
242 
243 /**
244  * GHOST window on M$ Windows OSs.
245  */
246 class GHOST_WindowWin32 : public GHOST_Window {
247  public:
248   /**
249    * Constructor.
250    * Creates a new window and opens it.
251    * To check if the window was created properly, use the getValid() method.
252    * \param title     The text shown in the title bar of the window.
253    * \param left      The coordinate of the left edge of the window.
254    * \param top       The coordinate of the top edge of the window.
255    * \param width     The width the window.
256    * \param height    The height the window.
257    * \param state     The state the window is initially opened with.
258    * \param type      The type of drawing context installed in this window.
259    * \param wantStereoVisual   Stereo visual for quad buffered stereo.
260    * \param parentWindowHwnd
261    */
262   GHOST_WindowWin32(GHOST_SystemWin32 *system,
263                     const char *title,
264                     GHOST_TInt32 left,
265                     GHOST_TInt32 top,
266                     GHOST_TUns32 width,
267                     GHOST_TUns32 height,
268                     GHOST_TWindowState state,
269                     GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
270                     bool wantStereoVisual = false,
271                     bool alphaBackground = false,
272                     GHOST_WindowWin32 *parentWindow = 0,
273                     bool is_debug = false,
274                     bool dialog = false);
275 
276   /**
277    * Destructor.
278    * Closes the window and disposes resources allocated.
279    */
280   ~GHOST_WindowWin32();
281 
282   /**
283    * Returns indication as to whether the window is valid.
284    * \return The validity of the window.
285    */
286   bool getValid() const;
287 
288   /**
289    * Access to the handle of the window.
290    * \return The handle of the window.
291    */
292   HWND getHWND() const;
293 
294   /**
295    * Sets the title displayed in the title bar.
296    * \param title The title to display in the title bar.
297    */
298   void setTitle(const char *title);
299 
300   /**
301    * Returns the title displayed in the title bar.
302    * \return The title displayed in the title bar.
303    */
304   std::string getTitle() const;
305 
306   /**
307    * Returns the window rectangle dimensions.
308    * The dimensions are given in screen coordinates that are
309    * relative to the upper-left corner of the screen.
310    * \param bounds The bounding rectangle of the window.
311    */
312   void getWindowBounds(GHOST_Rect &bounds) const;
313 
314   /**
315    * Returns the client rectangle dimensions.
316    * The left and top members of the rectangle are always zero.
317    * \param bounds The bounding rectangle of the client area of the window.
318    */
319   void getClientBounds(GHOST_Rect &bounds) const;
320 
321   /**
322    * Resizes client rectangle width.
323    * \param width The new width of the client area of the window.
324    */
325   GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
326 
327   /**
328    * Resizes client rectangle height.
329    * \param height The new height of the client area of the window.
330    */
331   GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
332 
333   /**
334    * Resizes client rectangle.
335    * \param width     The new width of the client area of the window.
336    * \param height    The new height of the client area of the window.
337    */
338   GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
339 
340   /**
341    * Returns the state of the window (normal, minimized, maximized).
342    * \return The state of the window.
343    */
344   GHOST_TWindowState getState() const;
345 
346   /**
347    * Converts a point in screen coordinates to client rectangle coordinates
348    * \param inX   The x-coordinate on the screen.
349    * \param inY   The y-coordinate on the screen.
350    * \param outX  The x-coordinate in the client rectangle.
351    * \param outY  The y-coordinate in the client rectangle.
352    */
353   void screenToClient(GHOST_TInt32 inX,
354                       GHOST_TInt32 inY,
355                       GHOST_TInt32 &outX,
356                       GHOST_TInt32 &outY) const;
357 
358   /**
359    * Converts a point in screen coordinates to client rectangle coordinates
360    * \param inX   The x-coordinate in the client rectangle.
361    * \param inY   The y-coordinate in the client rectangle.
362    * \param outX  The x-coordinate on the screen.
363    * \param outY  The y-coordinate on the screen.
364    */
365   void clientToScreen(GHOST_TInt32 inX,
366                       GHOST_TInt32 inY,
367                       GHOST_TInt32 &outX,
368                       GHOST_TInt32 &outY) const;
369 
370   /**
371    * Sets the state of the window (normal, minimized, maximized).
372    * \param state The state of the window.
373    * \return Indication of success.
374    */
375   GHOST_TSuccess setState(GHOST_TWindowState state);
376 
377   /**
378    * Sets the order of the window (bottom, top).
379    * \param order The order of the window.
380    * \return Indication of success.
381    */
382   GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
383 
384   /**
385    * Invalidates the contents of this window.
386    */
387   GHOST_TSuccess invalidate();
388 
389   /**
390    * Sets the progress bar value displayed in the window/application icon
391    * \param progress The progress %
392    */
393   GHOST_TSuccess setProgressBar(float progress);
394 
395   /**
396    * Hides the progress bar in the icon
397    */
398   GHOST_TSuccess endProgressBar();
399 
400   /**
401    * Register a mouse capture state (should be called
402    * for any real button press, controls mouse
403    * capturing).
404    *
405    * \param event Whether mouse was pressed and released, or an operator grabbed or ungrabbed the
406    * mouse
407    */
408   void updateMouseCapture(GHOST_MouseCaptureEventWin32 event);
409 
410   /**
411    * Inform the window that it has lost mouse capture,
412    * called in response to native window system messages.
413    */
414   void lostMouseCapture();
415 
416   bool isDialog() const;
417 
418   /**
419    * Loads the windows equivalent of a standard GHOST cursor.
420    * \param visible       Flag for cursor visibility.
421    * \param cursorShape   The cursor shape.
422    */
423   HCURSOR getStandardCursor(GHOST_TStandardCursor shape) const;
424   void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const;
425 
getTabletData()426   const GHOST_TabletData &getTabletData()
427   {
428     return m_tabletData;
429   }
430 
431   void setTabletData(GHOST_TabletData *tabletData);
432   bool useTabletAPI(GHOST_TTabletAPI api) const;
433 
434   /**
435    * Translate WM_POINTER events into GHOST_PointerInfoWin32 structs.
436    * \param outPointerInfo   Storage to return resulting GHOST_PointerInfoWin32 structs
437    * \param wParam           WPARAM of the event
438    * \param lParam           LPARAM of the event
439    */
440   GHOST_TSuccess getPointerInfo(std::vector<GHOST_PointerInfoWin32> &outPointerInfo,
441                                 WPARAM wParam,
442                                 LPARAM lParam);
443 
444   void processWin32TabletActivateEvent(WORD state);
445   void processWin32TabletInitEvent();
446   void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
447   void bringTabletContextToFront();
448 
beginFullScreen()449   GHOST_TSuccess beginFullScreen() const
450   {
451     return GHOST_kFailure;
452   }
453 
endFullScreen()454   GHOST_TSuccess endFullScreen() const
455   {
456     return GHOST_kFailure;
457   }
458 
459   GHOST_TUns16 getDPIHint() override;
460 
461   /**
462    * Get whether there are currently any mouse buttons pressed
463    * \return    True if there are any currently pressed mouse buttons
464    */
465   bool getMousePressed() const;
466 
467   /** Whether a tablet stylus is being tracked */
468   bool m_tabletInRange;
469 
470   /** if the window currently resizing */
471   bool m_inLiveResize;
472 
473 #ifdef WITH_INPUT_IME
getImeInput()474   GHOST_ImeWin32 *getImeInput()
475   {
476     return &m_imeInput;
477   }
478 
479   void beginIME(GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed);
480 
481   void endIME();
482 #endif /* WITH_INPUT_IME */
483 
484  private:
485   /**
486    * \param type  The type of rendering context create.
487    * \return Indication of success.
488    */
489   GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
490 
491   /**
492    * Sets the cursor visibility on the window using
493    * native window system calls.
494    */
495   GHOST_TSuccess setWindowCursorVisibility(bool visible);
496 
497   /**
498    * Sets the cursor grab on the window using native window system calls.
499    * Using registerMouseClickEvent.
500    * \param mode  GHOST_TGrabCursorMode.
501    */
502   GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
503 
504   /**
505    * Sets the cursor shape on the window using
506    * native window system calls.
507    */
508   GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
509   GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor shape);
510 
511   /**
512    * Sets the cursor shape on the window using
513    * native window system calls.
514    */
515   GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap,
516                                             GHOST_TUns8 *mask,
517                                             int sizex,
518                                             int sizey,
519                                             int hotX,
520                                             int hotY,
521                                             bool canInvertColor);
522 
523   /** Pointer to system */
524   GHOST_SystemWin32 *m_system;
525   /** Pointer to COM IDropTarget implementor */
526   GHOST_DropTargetWin32 *m_dropTarget;
527   /** Window handle. */
528   HWND m_hWnd;
529   /** Device context handle. */
530   HDC m_hDC;
531 
532   /** Flag for if window has captured the mouse */
533   bool m_hasMouseCaptured;
534   /** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab()
535    * Multiple grabs must be released with a single ungrab */
536   bool m_hasGrabMouse;
537   /** Count of number of pressed buttons */
538   int m_nPressedButtons;
539   /** HCURSOR structure of the custom cursor */
540   HCURSOR m_customCursor;
541   /** request GL context aith alpha channel */
542   bool m_wantAlphaBackground;
543 
544   /** ITaskbarList3 structure for progress bar*/
545   ITaskbarList3 *m_Bar;
546 
547   static const wchar_t *s_windowClassName;
548   static const int s_maxTitleLength;
549 
550   /** Tablet data for GHOST */
551   GHOST_TabletData m_tabletData;
552 
553   /* Wintab API */
554   struct {
555     /** WinTab dll handle */
556     HMODULE handle;
557 
558     /** API functions */
559     GHOST_WIN32_WTInfo info;
560     GHOST_WIN32_WTOpen open;
561     GHOST_WIN32_WTClose close;
562     GHOST_WIN32_WTPacket packet;
563     GHOST_WIN32_WTEnable enable;
564     GHOST_WIN32_WTOverlap overlap;
565 
566     /** Stores the Tablet context if detected Tablet features using WinTab.dll */
567     HCTX tablet;
568     LONG maxPressure;
569     LONG maxAzimuth, maxAltitude;
570   } m_wintab;
571 
572   GHOST_TWindowState m_normal_state;
573 
574   /** user32 dll handle*/
575   HMODULE m_user32;
576   GHOST_WIN32_GetPointerInfoHistory m_fpGetPointerInfoHistory;
577   GHOST_WIN32_GetPointerPenInfoHistory m_fpGetPointerPenInfoHistory;
578   GHOST_WIN32_GetPointerTouchInfoHistory m_fpGetPointerTouchInfoHistory;
579 
580   HWND m_parentWindowHwnd;
581 
582 #ifdef WITH_INPUT_IME
583   /** Handle input method editors event */
584   GHOST_ImeWin32 m_imeInput;
585 #endif
586   bool m_debug_context;
587 };
588