From 036d70cdb81c9a428363e6f6252e9b94104ab6e1 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 17 Apr 2012 21:11:31 +0200 Subject: [PATCH] Add dynamic loading of Win32 touch API --- src/win32_init.c | 16 ++++++++++++++++ src/win32_platform.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/win32_window.c | 19 +++++++++++++------ tests/events.c | 15 ++++++++++++--- 4 files changed, 85 insertions(+), 9 deletions(-) mode change 100644 => 100755 src/win32_platform.h diff --git a/src/win32_init.c b/src/win32_init.c index cd749b40a..da3e14172 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -89,6 +89,22 @@ static GLFWbool initLibraries(void) GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware"); _glfw.win32.user32.ChangeWindowMessageFilterEx = (CHANGEWINDOWMESSAGEFILTEREX_T) GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx"); + _glfw.win32.user32.GetTouchInputInfo = (GETTOUCHINPUTINFO_T) + GetProcAddress(_glfw.win32.user32.instance, "GetTouchInputInfo"); + _glfw.win32.user32.CloseTouchInputHandle = (CLOSETOUCHINPUTHANDLE_T) + GetProcAddress(_glfw.win32.user32.instance, "CloseTouchInputHandle"); + _glfw.win32.user32.RegisterTouchWindow = (REGISTERTOUCHWINDOW_T) + GetProcAddress(_glfw.win32.user32.instance, "RegisterTouchWindow"); + _glfw.win32.user32.UnregisterTouchWindow = (UNREGISTERTOUCHWINDOW_T) + GetProcAddress(_glfw.win32.user32.instance, "UnregisterTouchWindow"); + + if (_glfw.win32.user32.GetTouchInputInfo && + _glfw.win32.user32.CloseTouchInputHandle && + _glfw.win32.user32.RegisterTouchWindow && + _glfw.win32.user32.UnregisterTouchWindow) + { + _glfw.win32.touch.available = GLFW_TRUE; + } _glfw.win32.dwmapi.instance = LoadLibraryW(L"dwmapi.dll"); if (_glfw.win32.dwmapi.instance) diff --git a/src/win32_platform.h b/src/win32_platform.h old mode 100644 new mode 100755 index 0068fbe20..d64c21771 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -99,6 +99,34 @@ typedef struct tagCHANGEFILTERSTRUCT #endif #endif /*Windows 7*/ +#if WINVER < 0x0601 + +#define WM_TOUCH 0x0240 + +DECLARE_HANDLE(HTOUCHINPUT); + +typedef struct tagTOUCHINPUT +{ + LONG x; + LONG y; + HANDLE hSource; + DWORD dwID; + DWORD dwFlags; + DWORD dwMask; + DWORD dwTime; + ULONG_PTR dwExtraInfo; + DWORD cxContact; + DWORD cyContext; +} TOUCHINPUT, *PTOUCHINPUT; + +#define TOUCH_COORD_TO_PIXEL(x) ((x) / 100) + +#define TOUCHEVENTF_MOVE 0x0001 +#define TOUCHEVENTF_DOWN 0x0002 +#define TOUCHEVENTF_UP 0x0004 + +#endif /*WINVER < 0x0601*/ + // winmm.dll function pointer typedefs typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T)(UINT,LPJOYCAPS,UINT); typedef MMRESULT (WINAPI * JOYGETPOS_T)(UINT,LPJOYINFO); @@ -112,8 +140,16 @@ typedef DWORD (WINAPI * TIMEGETTIME_T)(void); // user32.dll function pointer typedefs typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void); typedef BOOL (WINAPI * CHANGEWINDOWMESSAGEFILTEREX_T)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT); +typedef BOOL (WINAPI * GETTOUCHINPUTINFO_T)(HTOUCHINPUT,UINT,PTOUCHINPUT,int); +typedef BOOL (WINAPI * CLOSETOUCHINPUTHANDLE_T)(HTOUCHINPUT); +typedef BOOL (WINAPI * REGISTERTOUCHWINDOW_T)(HWND,LONG); +typedef BOOL (WINAPI * UNREGISTERTOUCHWINDOW_T)(HWND); #define _glfw_SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware #define _glfw_ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx +#define _glfw_GetTouchInputInfo _glfw.win32.user32.GetTouchInputInfo +#define _glfw_CloseTouchInputHandle _glfw.win32.user32.CloseTouchInputHandle +#define _glfw_RegisterTouchWindow _glfw.win32.user32.RegisterTouchWindow +#define _glfw_UnregisterTouchWindow _glfw.win32.user32.UnregisterTouchWindow // dwmapi.dll function pointer typedefs typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*); @@ -186,8 +222,16 @@ typedef struct _GLFWlibraryWin32 HINSTANCE instance; SETPROCESSDPIAWARE_T SetProcessDPIAware; CHANGEWINDOWMESSAGEFILTEREX_T ChangeWindowMessageFilterEx; + GETTOUCHINPUTINFO_T GetTouchInputInfo; + CLOSETOUCHINPUTHANDLE_T CloseTouchInputHandle; + REGISTERTOUCHWINDOW_T RegisterTouchWindow; + UNREGISTERTOUCHWINDOW_T UnregisterTouchWindow; } user32; + struct { + GLFWbool available; + } touch; + // dwmapi.dll struct { HINSTANCE instance; diff --git a/src/win32_window.c b/src/win32_window.c index e44d82679..26b67229a 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -589,12 +589,16 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, TOUCHINPUT* inputs; UINT count = LOWORD(wParam); + if (!_glfw.win32.touch.available) + return 0; + inputs = (TOUCHINPUT*) malloc(sizeof(TOUCHINPUT) * count); - if (GetTouchInputInfo((HTOUCHINPUT) lParam, - count, inputs, sizeof(TOUCHINPUT))) + if (_glfw_GetTouchInputInfo((HTOUCHINPUT) lParam, + count, inputs, sizeof(TOUCHINPUT))) { - int i, width, height; + UINT i; + int width, height; _glfwPlatformGetWindowSize(window, &width, &height); @@ -626,7 +630,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, } } - CloseTouchInputHandle((HTOUCHINPUT) lParam); + _glfw_CloseTouchInputHandle((HTOUCHINPUT) lParam); } free(inputs); @@ -1189,10 +1193,13 @@ void _glfwPlatformPostEmptyEvent(void) void _glfwPlatformSetTouchInput(_GLFWwindow* window, int enabled) { + if (!_glfw.win32.touch.available) + return; + if (enabled) - RegisterTouchWindow(window->win32.handle, 0); + _glfw_RegisterTouchWindow(window->win32.handle, 0); else - UnregisterTouchWindow(window->win32.handle); + _glfw_UnregisterTouchWindow(window->win32.handle); } void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) diff --git a/tests/events.c b/tests/events.c index 94e35a370..e63606bcf 100644 --- a/tests/events.c +++ b/tests/events.c @@ -438,13 +438,21 @@ static void monitor_callback(GLFWmonitor* monitor, int event) } } -static void touch_callback(GLFWwindow* window, int touch, int action, double x, double y) +static void touch_callback(GLFWwindow* window, int touch, int action) { - printf("%08x at %0.3f: Touch %i %s at %0.3f %0.3f\n", + printf("%08x at %0.3f: Touch %i %s\n", + counter++, + glfwGetTime(), + touch, + get_action_name(action)); +} + +static void touch_pos_callback(GLFWwindow* window, int touch, double x, double y) +{ + printf("%08x at %0.3f: Touch %i position: %0.3f %0.3f\n", counter++, glfwGetTime(), touch, - get_action_name(action), x, y); } @@ -562,6 +570,7 @@ int main(int argc, char** argv) glfwSetCharModsCallback(slots[i].window, char_mods_callback); glfwSetDropCallback(slots[i].window, drop_callback); glfwSetTouchCallback(slots[i].window, touch_callback); + glfwSetTouchPosCallback(slots[i].window, touch_pos_callback); glfwMakeContextCurrent(slots[i].window); gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);