/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef WinGesture_h__ #define WinGesture_h__ /* * nsWinGesture - Touch input handling for tablet displays. */ #include "nsdefs.h" #include #include #include "nsPoint.h" #include "nsGUIEvent.h" // Desktop builds target apis for 502. Win8 Metro builds target 602. #if WINVER < 0x0602 DECLARE_HANDLE(HGESTUREINFO); /* * Gesture flags - GESTUREINFO.dwFlags */ #define GF_BEGIN 0x00000001 #define GF_INERTIA 0x00000002 #define GF_END 0x00000004 /* * Gesture configuration structure * - Used in SetGestureConfig and GetGestureConfig * - Note that any setting not included in either GESTURECONFIG.dwWant or * GESTURECONFIG.dwBlock will use the parent window's preferences or * system defaults. */ typedef struct tagGESTURECONFIG { DWORD dwID; // gesture ID DWORD dwWant; // settings related to gesture ID that are to be turned on DWORD dwBlock; // settings related to gesture ID that are to be turned off } GESTURECONFIG, *PGESTURECONFIG; /* * Gesture information structure * - Pass the HGESTUREINFO received in the WM_GESTURE message lParam into the * GetGestureInfo function to retrieve this information. * - If cbExtraArgs is non-zero, pass the HGESTUREINFO received in the WM_GESTURE * message lParam into the GetGestureExtraArgs function to retrieve extended * argument information. */ typedef struct tagGESTUREINFO { UINT cbSize; // size, in bytes, of this structure (including variable length Args field) DWORD dwFlags; // see GF_* flags DWORD dwID; // gesture ID, see GID_* defines HWND hwndTarget; // handle to window targeted by this gesture POINTS ptsLocation; // current location of this gesture DWORD dwInstanceID; // internally used DWORD dwSequenceID; // internally used ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture } GESTUREINFO, *PGESTUREINFO; typedef GESTUREINFO const * PCGESTUREINFO; /* * Gesture notification structure * - The WM_GESTURENOTIFY message lParam contains a pointer to this structure. * - The WM_GESTURENOTIFY message notifies a window that gesture recognition is * in progress and a gesture will be generated if one is recognized under the * current gesture settings. */ typedef struct tagGESTURENOTIFYSTRUCT { UINT cbSize; // size, in bytes, of this structure DWORD dwFlags; // unused HWND hwndTarget; // handle to window targeted by the gesture POINTS ptsLocation; // starting location DWORD dwInstanceID; // internally used } GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT; /* * Gesture argument helpers * - Angle should be a double in the range of -2pi to +2pi * - Argument should be an unsigned 16-bit value */ #define GID_ROTATE_ANGLE_TO_ARGUMENT(_arg_) ((USHORT)((((_arg_) + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0)) #define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_) ((((double)(_arg_) / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265) /* * Gesture configuration flags */ #define GC_ALLGESTURES 0x00000001 #define GC_ZOOM 0x00000001 #define GC_PAN 0x00000001 #define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002 #define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004 #define GC_PAN_WITH_GUTTER 0x00000008 #define GC_PAN_WITH_INERTIA 0x00000010 #define GC_ROTATE 0x00000001 #define GC_TWOFINGERTAP 0x00000001 #define GC_PRESSANDTAP 0x00000001 /* * Gesture IDs */ #define GID_BEGIN 1 #define GID_END 2 #define GID_ZOOM 3 #define GID_PAN 4 #define GID_ROTATE 5 #define GID_TWOFINGERTAP 6 #define GID_PRESSANDTAP 7 // Maximum number of gestures that can be included // in a single call to SetGestureConfig / GetGestureConfig #define GESTURECONFIGMAXCOUNT 256 // If specified, GetGestureConfig returns consolidated configuration // for the specified window and it's parent window chain #define GCF_INCLUDE_ANCESTORS 0x00000001 // Window events we need to respond to or receive #define WM_GESTURE 0x0119 #define WM_GESTURENOTIFY 0x011A typedef struct _TOUCHINPUT { LONG x; LONG y; HANDLE hSource; DWORD dwID; DWORD dwFlags; DWORD dwMask; DWORD dwTime; ULONG_PTR dwExtraInfo; DWORD cxContact; DWORD cyContact; } TOUCHINPUT, *PTOUCHINPUT; typedef HANDLE HTOUCHINPUT; #define WM_TOUCH 0x0240 #define TOUCHEVENTF_MOVE 0x0001 #define TOUCHEVENTF_DOWN 0x0002 #define TOUCHEVENTF_UP 0x0004 #define TOUCHEVENTF_INRANGE 0x0008 #define TOUCHEVENTF_PRIMARY 0x0010 #define TOUCHEVENTF_NOCOALESCE 0x0020 #define TOUCHEVENTF_PEN 0x0040 #define TOUCHEVENTF_PALM 0x0080 #define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001 #define TOUCHINPUTMASKF_EXTRAINFO 0x0002 #define TOUCHINPUTMASKF_CONTACTAREA 0x0004 #define TOUCH_COORD_TO_PIXEL(C) (C/100) #define TWF_FINETOUCH 0x0001 #define TWF_WANTPALM 0x0002 #endif // WINVER < 0x0602 // WM_TABLET_QUERYSYSTEMGESTURESTATUS return values #define TABLET_ROTATE_GESTURE_ENABLE 0x02000000 class nsPointWin : public nsIntPoint { public: nsPointWin& operator=(const POINTS& aPoint) { x = aPoint.x; y = aPoint.y; return *this; } nsPointWin& operator=(const POINT& aPoint) { x = aPoint.x; y = aPoint.y; return *this; } nsPointWin& operator=(int val) { x = y = val; return *this; } void ScreenToClient(HWND hWnd) { POINT tmp; tmp.x = x; tmp.y = y; ::ScreenToClient(hWnd, &tmp); *this = tmp; } }; class nsWinGesture { public: nsWinGesture(); public: bool SetWinGestureSupport(HWND hWnd, nsGestureNotifyEvent::ePanDirection aDirection); bool ShutdownWinGestureSupport(); bool RegisterTouchWindow(HWND hWnd); bool UnregisterTouchWindow(HWND hWnd); bool GetTouchInputInfo(HTOUCHINPUT hTouchInput, PRUint32 cInputs, PTOUCHINPUT pInputs); bool CloseTouchInputHandle(HTOUCHINPUT hTouchInput); bool IsAvailable(); // Simple gesture process bool ProcessGestureMessage(HWND hWnd, WPARAM wParam, LPARAM lParam, nsSimpleGestureEvent& evt); // Pan processing bool IsPanEvent(LPARAM lParam); bool ProcessPanMessage(HWND hWnd, WPARAM wParam, LPARAM lParam); bool PanDeltaToPixelScroll(mozilla::widget::WheelEvent& aWheelEvent); void UpdatePanFeedbackX(HWND hWnd, PRInt32 scrollOverflow, bool& endFeedback); void UpdatePanFeedbackY(HWND hWnd, PRInt32 scrollOverflow, bool& endFeedback); void PanFeedbackFinalize(HWND hWnd, bool endFeedback); public: // Helpers bool GetGestureInfo(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo); bool CloseGestureInfoHandle(HGESTUREINFO hGestureInfo); bool GetGestureExtraArgs(HGESTUREINFO hGestureInfo, UINT cbExtraArgs, PBYTE pExtraArgs); bool SetGestureConfig(HWND hWnd, UINT cIDs, PGESTURECONFIG pGestureConfig); bool GetGestureConfig(HWND hWnd, DWORD dwFlags, PUINT pcIDs, PGESTURECONFIG pGestureConfig); bool BeginPanningFeedback(HWND hWnd); bool EndPanningFeedback(HWND hWnd); bool UpdatePanningFeedback(HWND hWnd, LONG offsetX, LONG offsetY, BOOL fInInertia); protected: private: // Function prototypes typedef BOOL (WINAPI * GetGestureInfoPtr)(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo); typedef BOOL (WINAPI * CloseGestureInfoHandlePtr)(HGESTUREINFO hGestureInfo); typedef BOOL (WINAPI * GetGestureExtraArgsPtr)(HGESTUREINFO hGestureInfo, UINT cbExtraArgs, PBYTE pExtraArgs); typedef BOOL (WINAPI * SetGestureConfigPtr)(HWND hwnd, DWORD dwReserved, UINT cIDs, PGESTURECONFIG pGestureConfig, UINT cbSize); typedef BOOL (WINAPI * GetGestureConfigPtr)(HWND hwnd, DWORD dwReserved, DWORD dwFlags, PUINT pcIDs, PGESTURECONFIG pGestureConfig, UINT cbSize); typedef BOOL (WINAPI * BeginPanningFeedbackPtr)(HWND hWnd); typedef BOOL (WINAPI * EndPanningFeedbackPtr)(HWND hWnd, BOOL fAnimateBack); typedef BOOL (WINAPI * UpdatePanningFeedbackPtr)(HWND hWnd, LONG offsetX, LONG offsetY, BOOL fInInertia); typedef BOOL (WINAPI * RegisterTouchWindowPtr)(HWND hWnd, ULONG flags); typedef BOOL (WINAPI * UnregisterTouchWindowPtr)(HWND hWnd); typedef BOOL (WINAPI * GetTouchInputInfoPtr)(HTOUCHINPUT hTouchInput, PRUint32 cInputs, PTOUCHINPUT pInputs, PRInt32 cbSize); typedef BOOL (WINAPI * CloseTouchInputHandlePtr)(HTOUCHINPUT hTouchInput); // Static function pointers static GetGestureInfoPtr getGestureInfo; static CloseGestureInfoHandlePtr closeGestureInfoHandle; static GetGestureExtraArgsPtr getGestureExtraArgs; static SetGestureConfigPtr setGestureConfig; static GetGestureConfigPtr getGestureConfig; static BeginPanningFeedbackPtr beginPanningFeedback; static EndPanningFeedbackPtr endPanningFeedback; static UpdatePanningFeedbackPtr updatePanningFeedback; static RegisterTouchWindowPtr registerTouchWindow; static UnregisterTouchWindowPtr unregisterTouchWindow; static GetTouchInputInfoPtr getTouchInputInfo; static CloseTouchInputHandlePtr closeTouchInputHandle; // Delay load info bool InitLibrary(); static HMODULE sLibraryHandle; static const PRUnichar kGestureLibraryName[]; // Pan and feedback state nsPointWin mPanIntermediate; nsPointWin mPanRefPoint; nsPointWin mPixelScrollDelta; bool mPanActive; bool mFeedbackActive; bool mXAxisFeedback; bool mYAxisFeedback; bool mPanInertiaActive; nsPointWin mPixelScrollOverflow; // Zoom state double mZoomIntermediate; // Rotate state double mRotateIntermediate; }; #endif /* WinGesture_h__ */