Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef WinGesture_h__ |
michael@0 | 7 | #define WinGesture_h__ |
michael@0 | 8 | |
michael@0 | 9 | /* |
michael@0 | 10 | * nsWinGesture - Touch input handling for tablet displays. |
michael@0 | 11 | */ |
michael@0 | 12 | |
michael@0 | 13 | #include "nsdefs.h" |
michael@0 | 14 | #include <winuser.h> |
michael@0 | 15 | #include <tpcshrd.h> |
michael@0 | 16 | #include "nsPoint.h" |
michael@0 | 17 | #include "mozilla/EventForwards.h" |
michael@0 | 18 | #include "mozilla/TouchEvents.h" |
michael@0 | 19 | |
michael@0 | 20 | // Desktop builds target apis for 502. Win8 Metro builds target 602. |
michael@0 | 21 | #if WINVER < 0x0602 |
michael@0 | 22 | |
michael@0 | 23 | DECLARE_HANDLE(HGESTUREINFO); |
michael@0 | 24 | |
michael@0 | 25 | /* |
michael@0 | 26 | * Gesture flags - GESTUREINFO.dwFlags |
michael@0 | 27 | */ |
michael@0 | 28 | #define GF_BEGIN 0x00000001 |
michael@0 | 29 | #define GF_INERTIA 0x00000002 |
michael@0 | 30 | #define GF_END 0x00000004 |
michael@0 | 31 | |
michael@0 | 32 | /* |
michael@0 | 33 | * Gesture configuration structure |
michael@0 | 34 | * - Used in SetGestureConfig and GetGestureConfig |
michael@0 | 35 | * - Note that any setting not included in either GESTURECONFIG.dwWant or |
michael@0 | 36 | * GESTURECONFIG.dwBlock will use the parent window's preferences or |
michael@0 | 37 | * system defaults. |
michael@0 | 38 | */ |
michael@0 | 39 | typedef struct tagGESTURECONFIG { |
michael@0 | 40 | DWORD dwID; // gesture ID |
michael@0 | 41 | DWORD dwWant; // settings related to gesture ID that are to be turned on |
michael@0 | 42 | DWORD dwBlock; // settings related to gesture ID that are to be turned off |
michael@0 | 43 | } GESTURECONFIG, *PGESTURECONFIG; |
michael@0 | 44 | |
michael@0 | 45 | /* |
michael@0 | 46 | * Gesture information structure |
michael@0 | 47 | * - Pass the HGESTUREINFO received in the WM_GESTURE message lParam into the |
michael@0 | 48 | * GetGestureInfo function to retrieve this information. |
michael@0 | 49 | * - If cbExtraArgs is non-zero, pass the HGESTUREINFO received in the WM_GESTURE |
michael@0 | 50 | * message lParam into the GetGestureExtraArgs function to retrieve extended |
michael@0 | 51 | * argument information. |
michael@0 | 52 | */ |
michael@0 | 53 | typedef struct tagGESTUREINFO { |
michael@0 | 54 | UINT cbSize; // size, in bytes, of this structure (including variable length Args field) |
michael@0 | 55 | DWORD dwFlags; // see GF_* flags |
michael@0 | 56 | DWORD dwID; // gesture ID, see GID_* defines |
michael@0 | 57 | HWND hwndTarget; // handle to window targeted by this gesture |
michael@0 | 58 | POINTS ptsLocation; // current location of this gesture |
michael@0 | 59 | DWORD dwInstanceID; // internally used |
michael@0 | 60 | DWORD dwSequenceID; // internally used |
michael@0 | 61 | ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES |
michael@0 | 62 | UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture |
michael@0 | 63 | } GESTUREINFO, *PGESTUREINFO; |
michael@0 | 64 | typedef GESTUREINFO const * PCGESTUREINFO; |
michael@0 | 65 | |
michael@0 | 66 | /* |
michael@0 | 67 | * Gesture notification structure |
michael@0 | 68 | * - The WM_GESTURENOTIFY message lParam contains a pointer to this structure. |
michael@0 | 69 | * - The WM_GESTURENOTIFY message notifies a window that gesture recognition is |
michael@0 | 70 | * in progress and a gesture will be generated if one is recognized under the |
michael@0 | 71 | * current gesture settings. |
michael@0 | 72 | */ |
michael@0 | 73 | typedef struct tagGESTURENOTIFYSTRUCT { |
michael@0 | 74 | UINT cbSize; // size, in bytes, of this structure |
michael@0 | 75 | DWORD dwFlags; // unused |
michael@0 | 76 | HWND hwndTarget; // handle to window targeted by the gesture |
michael@0 | 77 | POINTS ptsLocation; // starting location |
michael@0 | 78 | DWORD dwInstanceID; // internally used |
michael@0 | 79 | } GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT; |
michael@0 | 80 | |
michael@0 | 81 | |
michael@0 | 82 | /* |
michael@0 | 83 | * Gesture argument helpers |
michael@0 | 84 | * - Angle should be a double in the range of -2pi to +2pi |
michael@0 | 85 | * - Argument should be an unsigned 16-bit value |
michael@0 | 86 | */ |
michael@0 | 87 | #define GID_ROTATE_ANGLE_TO_ARGUMENT(_arg_) ((USHORT)((((_arg_) + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0)) |
michael@0 | 88 | #define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_) ((((double)(_arg_) / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265) |
michael@0 | 89 | |
michael@0 | 90 | /* |
michael@0 | 91 | * Gesture configuration flags |
michael@0 | 92 | */ |
michael@0 | 93 | #define GC_ALLGESTURES 0x00000001 |
michael@0 | 94 | |
michael@0 | 95 | #define GC_ZOOM 0x00000001 |
michael@0 | 96 | |
michael@0 | 97 | #define GC_PAN 0x00000001 |
michael@0 | 98 | #define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002 |
michael@0 | 99 | #define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004 |
michael@0 | 100 | #define GC_PAN_WITH_GUTTER 0x00000008 |
michael@0 | 101 | #define GC_PAN_WITH_INERTIA 0x00000010 |
michael@0 | 102 | |
michael@0 | 103 | #define GC_ROTATE 0x00000001 |
michael@0 | 104 | |
michael@0 | 105 | #define GC_TWOFINGERTAP 0x00000001 |
michael@0 | 106 | |
michael@0 | 107 | #define GC_PRESSANDTAP 0x00000001 |
michael@0 | 108 | |
michael@0 | 109 | /* |
michael@0 | 110 | * Gesture IDs |
michael@0 | 111 | */ |
michael@0 | 112 | #define GID_BEGIN 1 |
michael@0 | 113 | #define GID_END 2 |
michael@0 | 114 | #define GID_ZOOM 3 |
michael@0 | 115 | #define GID_PAN 4 |
michael@0 | 116 | #define GID_ROTATE 5 |
michael@0 | 117 | #define GID_TWOFINGERTAP 6 |
michael@0 | 118 | #define GID_PRESSANDTAP 7 |
michael@0 | 119 | |
michael@0 | 120 | // Maximum number of gestures that can be included |
michael@0 | 121 | // in a single call to SetGestureConfig / GetGestureConfig |
michael@0 | 122 | #define GESTURECONFIGMAXCOUNT 256 |
michael@0 | 123 | |
michael@0 | 124 | // If specified, GetGestureConfig returns consolidated configuration |
michael@0 | 125 | // for the specified window and it's parent window chain |
michael@0 | 126 | #define GCF_INCLUDE_ANCESTORS 0x00000001 |
michael@0 | 127 | |
michael@0 | 128 | // Window events we need to respond to or receive |
michael@0 | 129 | #define WM_GESTURE 0x0119 |
michael@0 | 130 | #define WM_GESTURENOTIFY 0x011A |
michael@0 | 131 | |
michael@0 | 132 | typedef struct _TOUCHINPUT { |
michael@0 | 133 | LONG x; |
michael@0 | 134 | LONG y; |
michael@0 | 135 | HANDLE hSource; |
michael@0 | 136 | DWORD dwID; |
michael@0 | 137 | DWORD dwFlags; |
michael@0 | 138 | DWORD dwMask; |
michael@0 | 139 | DWORD dwTime; |
michael@0 | 140 | ULONG_PTR dwExtraInfo; |
michael@0 | 141 | DWORD cxContact; |
michael@0 | 142 | DWORD cyContact; |
michael@0 | 143 | } TOUCHINPUT, *PTOUCHINPUT; |
michael@0 | 144 | |
michael@0 | 145 | typedef HANDLE HTOUCHINPUT; |
michael@0 | 146 | |
michael@0 | 147 | #define WM_TOUCH 0x0240 |
michael@0 | 148 | |
michael@0 | 149 | #define TOUCHEVENTF_MOVE 0x0001 |
michael@0 | 150 | #define TOUCHEVENTF_DOWN 0x0002 |
michael@0 | 151 | #define TOUCHEVENTF_UP 0x0004 |
michael@0 | 152 | #define TOUCHEVENTF_INRANGE 0x0008 |
michael@0 | 153 | #define TOUCHEVENTF_PRIMARY 0x0010 |
michael@0 | 154 | #define TOUCHEVENTF_NOCOALESCE 0x0020 |
michael@0 | 155 | #define TOUCHEVENTF_PEN 0x0040 |
michael@0 | 156 | #define TOUCHEVENTF_PALM 0x0080 |
michael@0 | 157 | |
michael@0 | 158 | #define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001 |
michael@0 | 159 | #define TOUCHINPUTMASKF_EXTRAINFO 0x0002 |
michael@0 | 160 | #define TOUCHINPUTMASKF_CONTACTAREA 0x0004 |
michael@0 | 161 | |
michael@0 | 162 | #define TOUCH_COORD_TO_PIXEL(C) (C/100) |
michael@0 | 163 | |
michael@0 | 164 | #define TWF_FINETOUCH 0x0001 |
michael@0 | 165 | #define TWF_WANTPALM 0x0002 |
michael@0 | 166 | |
michael@0 | 167 | #endif // WINVER < 0x0602 |
michael@0 | 168 | |
michael@0 | 169 | // WM_TABLET_QUERYSYSTEMGESTURESTATUS return values |
michael@0 | 170 | #define TABLET_ROTATE_GESTURE_ENABLE 0x02000000 |
michael@0 | 171 | |
michael@0 | 172 | class nsPointWin : public nsIntPoint |
michael@0 | 173 | { |
michael@0 | 174 | public: |
michael@0 | 175 | nsPointWin& operator=(const POINTS& aPoint) { |
michael@0 | 176 | x = aPoint.x; y = aPoint.y; |
michael@0 | 177 | return *this; |
michael@0 | 178 | } |
michael@0 | 179 | nsPointWin& operator=(const POINT& aPoint) { |
michael@0 | 180 | x = aPoint.x; y = aPoint.y; |
michael@0 | 181 | return *this; |
michael@0 | 182 | } |
michael@0 | 183 | nsPointWin& operator=(int val) { |
michael@0 | 184 | x = y = val; |
michael@0 | 185 | return *this; |
michael@0 | 186 | } |
michael@0 | 187 | void ScreenToClient(HWND hWnd) { |
michael@0 | 188 | POINT tmp; |
michael@0 | 189 | tmp.x = x; tmp.y = y; |
michael@0 | 190 | ::ScreenToClient(hWnd, &tmp); |
michael@0 | 191 | *this = tmp; |
michael@0 | 192 | } |
michael@0 | 193 | }; |
michael@0 | 194 | |
michael@0 | 195 | class nsWinGesture |
michael@0 | 196 | { |
michael@0 | 197 | public: |
michael@0 | 198 | nsWinGesture(); |
michael@0 | 199 | |
michael@0 | 200 | public: |
michael@0 | 201 | bool SetWinGestureSupport(HWND hWnd, mozilla::WidgetGestureNotifyEvent::ePanDirection aDirection); |
michael@0 | 202 | bool ShutdownWinGestureSupport(); |
michael@0 | 203 | bool RegisterTouchWindow(HWND hWnd); |
michael@0 | 204 | bool UnregisterTouchWindow(HWND hWnd); |
michael@0 | 205 | bool GetTouchInputInfo(HTOUCHINPUT hTouchInput, uint32_t cInputs, PTOUCHINPUT pInputs); |
michael@0 | 206 | bool CloseTouchInputHandle(HTOUCHINPUT hTouchInput); |
michael@0 | 207 | bool IsAvailable(); |
michael@0 | 208 | |
michael@0 | 209 | // Simple gesture process |
michael@0 | 210 | bool ProcessGestureMessage(HWND hWnd, WPARAM wParam, LPARAM lParam, mozilla::WidgetSimpleGestureEvent& evt); |
michael@0 | 211 | |
michael@0 | 212 | // Pan processing |
michael@0 | 213 | bool IsPanEvent(LPARAM lParam); |
michael@0 | 214 | bool ProcessPanMessage(HWND hWnd, WPARAM wParam, LPARAM lParam); |
michael@0 | 215 | bool PanDeltaToPixelScroll(mozilla::WidgetWheelEvent& aWheelEvent); |
michael@0 | 216 | void UpdatePanFeedbackX(HWND hWnd, int32_t scrollOverflow, bool& endFeedback); |
michael@0 | 217 | void UpdatePanFeedbackY(HWND hWnd, int32_t scrollOverflow, bool& endFeedback); |
michael@0 | 218 | void PanFeedbackFinalize(HWND hWnd, bool endFeedback); |
michael@0 | 219 | |
michael@0 | 220 | public: |
michael@0 | 221 | // Helpers |
michael@0 | 222 | bool GetGestureInfo(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo); |
michael@0 | 223 | bool CloseGestureInfoHandle(HGESTUREINFO hGestureInfo); |
michael@0 | 224 | bool GetGestureExtraArgs(HGESTUREINFO hGestureInfo, UINT cbExtraArgs, PBYTE pExtraArgs); |
michael@0 | 225 | bool SetGestureConfig(HWND hWnd, UINT cIDs, PGESTURECONFIG pGestureConfig); |
michael@0 | 226 | bool GetGestureConfig(HWND hWnd, DWORD dwFlags, PUINT pcIDs, PGESTURECONFIG pGestureConfig); |
michael@0 | 227 | bool BeginPanningFeedback(HWND hWnd); |
michael@0 | 228 | bool EndPanningFeedback(HWND hWnd); |
michael@0 | 229 | bool UpdatePanningFeedback(HWND hWnd, LONG offsetX, LONG offsetY, BOOL fInInertia); |
michael@0 | 230 | |
michael@0 | 231 | protected: |
michael@0 | 232 | |
michael@0 | 233 | private: |
michael@0 | 234 | // Function prototypes |
michael@0 | 235 | typedef BOOL (WINAPI * GetGestureInfoPtr)(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo); |
michael@0 | 236 | typedef BOOL (WINAPI * CloseGestureInfoHandlePtr)(HGESTUREINFO hGestureInfo); |
michael@0 | 237 | typedef BOOL (WINAPI * GetGestureExtraArgsPtr)(HGESTUREINFO hGestureInfo, UINT cbExtraArgs, PBYTE pExtraArgs); |
michael@0 | 238 | typedef BOOL (WINAPI * SetGestureConfigPtr)(HWND hwnd, DWORD dwReserved, UINT cIDs, PGESTURECONFIG pGestureConfig, UINT cbSize); |
michael@0 | 239 | typedef BOOL (WINAPI * GetGestureConfigPtr)(HWND hwnd, DWORD dwReserved, DWORD dwFlags, PUINT pcIDs, PGESTURECONFIG pGestureConfig, UINT cbSize); |
michael@0 | 240 | typedef BOOL (WINAPI * BeginPanningFeedbackPtr)(HWND hWnd); |
michael@0 | 241 | typedef BOOL (WINAPI * EndPanningFeedbackPtr)(HWND hWnd, BOOL fAnimateBack); |
michael@0 | 242 | typedef BOOL (WINAPI * UpdatePanningFeedbackPtr)(HWND hWnd, LONG offsetX, LONG offsetY, BOOL fInInertia); |
michael@0 | 243 | typedef BOOL (WINAPI * RegisterTouchWindowPtr)(HWND hWnd, ULONG flags); |
michael@0 | 244 | typedef BOOL (WINAPI * UnregisterTouchWindowPtr)(HWND hWnd); |
michael@0 | 245 | typedef BOOL (WINAPI * GetTouchInputInfoPtr)(HTOUCHINPUT hTouchInput, uint32_t cInputs, PTOUCHINPUT pInputs, int32_t cbSize); |
michael@0 | 246 | typedef BOOL (WINAPI * CloseTouchInputHandlePtr)(HTOUCHINPUT hTouchInput); |
michael@0 | 247 | |
michael@0 | 248 | // Static function pointers |
michael@0 | 249 | static GetGestureInfoPtr getGestureInfo; |
michael@0 | 250 | static CloseGestureInfoHandlePtr closeGestureInfoHandle; |
michael@0 | 251 | static GetGestureExtraArgsPtr getGestureExtraArgs; |
michael@0 | 252 | static SetGestureConfigPtr setGestureConfig; |
michael@0 | 253 | static GetGestureConfigPtr getGestureConfig; |
michael@0 | 254 | static BeginPanningFeedbackPtr beginPanningFeedback; |
michael@0 | 255 | static EndPanningFeedbackPtr endPanningFeedback; |
michael@0 | 256 | static UpdatePanningFeedbackPtr updatePanningFeedback; |
michael@0 | 257 | static RegisterTouchWindowPtr registerTouchWindow; |
michael@0 | 258 | static UnregisterTouchWindowPtr unregisterTouchWindow; |
michael@0 | 259 | static GetTouchInputInfoPtr getTouchInputInfo; |
michael@0 | 260 | static CloseTouchInputHandlePtr closeTouchInputHandle; |
michael@0 | 261 | |
michael@0 | 262 | // Delay load info |
michael@0 | 263 | bool InitLibrary(); |
michael@0 | 264 | |
michael@0 | 265 | static HMODULE sLibraryHandle; |
michael@0 | 266 | static const wchar_t kGestureLibraryName[]; |
michael@0 | 267 | |
michael@0 | 268 | // Pan and feedback state |
michael@0 | 269 | nsPointWin mPanIntermediate; |
michael@0 | 270 | nsPointWin mPanRefPoint; |
michael@0 | 271 | nsPointWin mPixelScrollDelta; |
michael@0 | 272 | bool mPanActive; |
michael@0 | 273 | bool mFeedbackActive; |
michael@0 | 274 | bool mXAxisFeedback; |
michael@0 | 275 | bool mYAxisFeedback; |
michael@0 | 276 | bool mPanInertiaActive; |
michael@0 | 277 | nsPointWin mPixelScrollOverflow; |
michael@0 | 278 | |
michael@0 | 279 | // Zoom state |
michael@0 | 280 | double mZoomIntermediate; |
michael@0 | 281 | |
michael@0 | 282 | // Rotate state |
michael@0 | 283 | double mRotateIntermediate; |
michael@0 | 284 | }; |
michael@0 | 285 | |
michael@0 | 286 | #endif /* WinGesture_h__ */ |
michael@0 | 287 | |
michael@0 | 288 |