From aa1ce3c06e3da5c0adc316ba81a6a6dbe4edef4f Mon Sep 17 00:00:00 2001 From: Torkel Date: Wed, 22 Jul 2020 14:01:48 +0900 Subject: [PATCH] touch --- README.md | 2 + include/GLFW/glfw3.h | 94 ++++++++++++++++++++++++++++++++++++++------ src/cocoa_window.m | 11 ++++++ src/input.c | 42 +++++++++++++++++++- src/internal.h | 6 +++ src/null_window.c | 9 +++++ src/win32_init.c | 17 ++++++++ src/win32_platform.h | 44 +++++++++++++++++++++ src/win32_window.c | 81 +++++++++++++++++++++++++++++++++++++- src/wl_window.c | 11 ++++++ src/x11_window.c | 11 ++++++ tests/events.c | 24 +++++++++++ 12 files changed, 337 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 7488e6d09..b5b7ddda4 100644 --- a/README.md +++ b/README.md @@ -269,6 +269,7 @@ skills. - Bailey Cosier - Noel Cower - Jason Daly + - Torkel Danielsson - Jarrod Davis - Olivier Delannoy - Paul R. Deppe @@ -316,6 +317,7 @@ skills. - Yuri Kunde Schlesner - Rokas Kupstys - Konstantin Käfer + - Quinten Lansu - Eric Larson - Francis Lecavalier - Robin Leffmann diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 7d9dee02b..238f6e732 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -317,18 +317,18 @@ extern "C" { */ #define GLFW_FALSE 0 -/*! @name Key and button actions +/*! @name Key, button and touch actions * @{ */ -/*! @brief The key or mouse button was released. +/*! @brief The key or mouse button was released, or the touch ended. * - * The key or mouse button was released. + * The key or mouse button was released, or the touch ended. * * @ingroup input */ #define GLFW_RELEASE 0 -/*! @brief The key or mouse button was pressed. +/*! @brief The key or mouse button was pressed, or the touch started. * - * The key or mouse button was pressed. + * The key or mouse button was pressed, or the touch started. * * @ingroup input */ @@ -340,6 +340,13 @@ extern "C" { * @ingroup input */ #define GLFW_REPEAT 2 +/*! @brief The touch was moved. + * + * The touch was moved. + * + * @ingroup input + */ +#define GLFW_MOVE 3 /*! @} */ /*! @defgroup hat_state Joystick hat states @@ -1098,6 +1105,7 @@ extern "C" { #define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 #define GLFW_LOCK_KEY_MODS 0x00033004 #define GLFW_RAW_MOUSE_MOTION 0x00033005 +#define GLFW_TOUCH 0x00033006 #define GLFW_CURSOR_NORMAL 0x00034001 #define GLFW_CURSOR_HIDDEN 0x00034002 @@ -1726,6 +1734,26 @@ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); */ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char*[]); +/*! @brief The function pointer type for touch callbacks. + * + * This is the function pointer type for touch callbacks. + * A touch callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, int touch, int action, double xpos, double ypos) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] touch The touch that triggered the event. + * @param[in] action One of @ref GLFW_PRESS, @ref GLFW_MOVE or @ref GLFW_RELEASE. + * @param[in] xpos The new x-coordinate of the touch. + * @param[in] ypos The new y-coordinate of the touch. + * + * @sa @ref glfwSetTouchCallback + * + * @ingroup input + */ +typedef void (* GLFWtouchfun)(GLFWwindow*,int,int,double,double); + /*! @brief The function pointer type for monitor configuration callbacks. * * This is the function pointer type for monitor configuration callbacks. @@ -4191,13 +4219,13 @@ GLFWAPI void glfwPostEmptyEvent(void); * * This function returns the value of an input option for the specified window. * The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, - * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or - * @ref GLFW_RAW_MOUSE_MOTION. + * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS, + * @ref GLFW_RAW_MOUSE_MOTION or @ref GLFW_TOUCH. * * @param[in] window The window to query. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, - * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or - * `GLFW_RAW_MOUSE_MOTION`. + * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS`, + * `GLFW_RAW_MOUSE_MOTION` or `GLFW_TOUCH`. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_INVALID_ENUM. @@ -4216,8 +4244,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * * This function sets an input mode option for the specified window. The mode * must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, - * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or - * @ref GLFW_RAW_MOUSE_MOTION. + * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS, + * @ref GLFW_RAW_MOUSE_MOTION or @ref GLFW_TOUCH. * * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor * modes: @@ -4255,10 +4283,15 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); * attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref * glfwRawMouseMotionSupported to check for support. * + * If the mode is `GLFW_TOUCH`, the value must be either `GLFW_TRUE` to enable + * touch input, or `GLFW_FALSE` to disable it. If touch input is not supported, + * attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref + * glfwTouchInputSupported to check for support. + * * @param[in] window The window whose input mode to set. * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, - * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or - * `GLFW_RAW_MOUSE_MOTION`. + * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS`, + * `GLFW_RAW_MOUSE_MOTION` or `GLFW_TOUCH`. * @param[in] value The new value of the specified input mode. * * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref @@ -4304,6 +4337,26 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); */ GLFWAPI int glfwRawMouseMotionSupported(void); +/*! @brief Returns whether touch input is supported. + * + * This function returns whether touch input is supported on the current + * system. This status does not change after GLFW has been initialized so you + * only need to check this once. If you attempt to enable touch input on + * a system that does not support it, @ref GLFW_PLATFORM_ERROR will be emitted. + * + * @return `GLFW_TRUE` if touch input is supported on the current machine, + * or `GLFW_FALSE` otherwise. + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @sa @ref glfwSetInputMode + * + * @ingroup input + */ +GLFWAPI int glfwTouchInputSupported(void); + /*! @brief Returns the layout-specific name of the specified printable key. * * This function returns the name of the specified printable key, encoded as @@ -4989,6 +5042,21 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun ca */ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun callback); +/*! @brief Sets the touch callback. + * + * This function sets the touch callback, which is called when a touch is + * started, ended or moved. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new touch callback, or `NULL` to remove the currently + * set callback. + * @return The previously set callback, or `NULL` if no callback was set or an + * error occurred. + * + * @ingroup input + */ +GLFWAPI GLFWtouchfun glfwSetTouchCallback(GLFWwindow* window, GLFWtouchfun callback); + /*! @brief Returns whether the specified joystick is present. * * This function returns whether the specified joystick is present. diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 81b22e2f9..9c41b9b96 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1403,6 +1403,17 @@ GLFWbool _glfwPlatformRawMouseMotionSupported(void) return GLFW_FALSE; } +void _glfwPlatformSetTouchInput(_GLFWwindow *window, GLFWbool enabled) +{ + _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, + "Cocoa: Touch input not yet implemented"); +} + +GLFWbool _glfwPlatformTouchInputSupported(void) +{ + return GLFW_FALSE; +} + void _glfwPlatformPollEvents(void) { @autoreleasepool { diff --git a/src/input.c b/src/input.c index 226f835dc..23e51ee8d 100644 --- a/src/input.c +++ b/src/input.c @@ -36,7 +36,7 @@ #include // Internal key state used for sticky keys -#define _GLFW_STICK 3 +#define _GLFW_STICK 4 // Internal constants for gamepad mapping source types #define _GLFW_JOYSTICK_AXIS 1 @@ -381,6 +381,14 @@ void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths) window->callbacks.drop((GLFWwindow*) window, count, paths); } +// Notifies shared code of touch events +// +void _glfwInputTouch(_GLFWwindow* window, int touch, int action, double xpos, double ypos) +{ + if (window->callbacks.touch) + window->callbacks.touch((GLFWwindow*) window, touch, action, xpos, ypos); +} + // Notifies shared code of a joystick connection or disconnection // void _glfwInputJoystick(_GLFWjoystick* js, int event) @@ -501,6 +509,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) return window->stickyKeys; case GLFW_STICKY_MOUSE_BUTTONS: return window->stickyMouseButtons; + case GLFW_TOUCH: + return window->touchInput; case GLFW_LOCK_KEY_MODS: return window->lockKeyMods; case GLFW_RAW_MOUSE_MOTION: @@ -600,6 +610,22 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) window->rawMouseMotion = value; _glfwPlatformSetRawMouseMotion(window, value); } + else if (mode == GLFW_TOUCH) + { + if (!_glfwPlatformTouchInputSupported()) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Touch input is not supported on this system"); + return; + } + + value = value ? GLFW_TRUE : GLFW_FALSE; + if (window->touchInput == value) + return; + + window->touchInput = value; + _glfwPlatformSetTouchInput(window, value); + } else _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); } @@ -610,6 +636,12 @@ GLFWAPI int glfwRawMouseMotionSupported(void) return _glfwPlatformRawMouseMotionSupported(); } +GLFWAPI int glfwTouchInputSupported(void) +{ + _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); + return _glfwPlatformTouchInputSupported(); +} + GLFWAPI const char* glfwGetKeyName(int key, int scancode) { _GLFW_REQUIRE_INIT_OR_RETURN(NULL); @@ -1359,6 +1391,14 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state) return GLFW_TRUE; } +GLFWAPI GLFWtouchfun glfwSetTouchCallback(GLFWwindow* handle, GLFWtouchfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP_POINTERS(window->callbacks.touch, cbfun); + return cbfun; +} + GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string) { assert(string != NULL); diff --git a/src/internal.h b/src/internal.h index 48053cdee..7f0ee228b 100644 --- a/src/internal.h +++ b/src/internal.h @@ -394,6 +394,7 @@ struct _GLFWwindow GLFWbool stickyKeys; GLFWbool stickyMouseButtons; + GLFWbool touchInput; GLFWbool lockKeyMods; int cursorMode; char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1]; @@ -422,6 +423,7 @@ struct _GLFWwindow GLFWcharfun character; GLFWcharmodsfun charmods; GLFWdropfun drop; + GLFWtouchfun touch; } callbacks; // This is defined in the window API's platform.h @@ -611,6 +613,8 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos); void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode); void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled); GLFWbool _glfwPlatformRawMouseMotionSupported(void); +void _glfwPlatformSetTouchInput(_GLFWwindow* window, int enabled); +GLFWbool _glfwPlatformTouchInputSupported(void); int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot); int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape); @@ -739,6 +743,8 @@ void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset); void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods); void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos); void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered); +void _glfwInputTouch(_GLFWwindow* window, int touch, int action, double xpos, double ypos); + void _glfwInputDrop(_GLFWwindow* window, int count, const char** names); void _glfwInputJoystick(_GLFWjoystick* js, int event); void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value); diff --git a/src/null_window.c b/src/null_window.c index 3e4466410..1aa6a3abb 100644 --- a/src/null_window.c +++ b/src/null_window.c @@ -400,6 +400,15 @@ GLFWbool _glfwPlatformRawMouseMotionSupported(void) return GLFW_TRUE; } +void _glfwPlatformSetTouchInput(_GLFWwindow *window, GLFWbool enabled) +{ +} + +GLFWbool _glfwPlatformTouchInputSupported(void) +{ + return GLFW_TRUE; +} + void _glfwPlatformShowWindow(_GLFWwindow* window) { window->null.visible = GLFW_TRUE; diff --git a/src/win32_init.c b/src/win32_init.c index f6995e512..c7805eac0 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -107,6 +107,23 @@ static GLFWbool loadLibraries(void) GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create"); } + _glfw.win32.user32.GetTouchInputInfo_ = (PFN_GetTouchInputInfo) + GetProcAddress(_glfw.win32.user32.instance, "GetTouchInputInfo"); + _glfw.win32.user32.CloseTouchInputHandle_ = (PFN_CloseTouchInputHandle) + GetProcAddress(_glfw.win32.user32.instance, "CloseTouchInputHandle"); + _glfw.win32.user32.RegisterTouchWindow_ = (PFN_RegisterTouchWindow) + GetProcAddress(_glfw.win32.user32.instance, "RegisterTouchWindow"); + _glfw.win32.user32.UnregisterTouchWindow_ = (PFN_UnregisterTouchWindow) + 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; + } + { int i; const char* names[] = diff --git a/src/win32_platform.h b/src/win32_platform.h index 4f5205147..f76408a82 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -215,6 +215,34 @@ typedef enum #define DIDFT_OPTIONAL 0x80000000 #endif +#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 DWORD (WINAPI * PFN_timeGetTime)(void); #define timeGetTime _glfw.win32.winmm.GetTime @@ -236,12 +264,20 @@ typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND); typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE); typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND); typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT); +typedef BOOL (WINAPI * PFN_GetTouchInputInfo)(HTOUCHINPUT,UINT,PTOUCHINPUT,int); +typedef BOOL (WINAPI * PFN_CloseTouchInputHandle)(HTOUCHINPUT); +typedef BOOL (WINAPI * PFN_RegisterTouchWindow)(HWND,LONG); +typedef BOOL (WINAPI * PFN_UnregisterTouchWindow)(HWND); #define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_ #define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_ #define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_ #define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_ #define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_ #define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_ +#define GetTouchInputInfo _glfw.win32.user32.GetTouchInputInfo_ +#define CloseTouchInputHandle _glfw.win32.user32.CloseTouchInputHandle_ +#define RegisterTouchWindow _glfw.win32.user32.RegisterTouchWindow_ +#define UnregisterTouchWindow _glfw.win32.user32.UnregisterTouchWindow_ // dwmapi.dll function pointer typedefs typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*); @@ -366,8 +402,16 @@ typedef struct _GLFWlibraryWin32 PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_; PFN_GetDpiForWindow GetDpiForWindow_; PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_; + PFN_GetTouchInputInfo GetTouchInputInfo_; + PFN_CloseTouchInputHandle CloseTouchInputHandle_; + PFN_RegisterTouchWindow RegisterTouchWindow_; + PFN_UnregisterTouchWindow UnregisterTouchWindow_; } user32; + struct { + GLFWbool available; + } touch; + struct { HINSTANCE instance; PFN_DwmIsCompositionEnabled IsCompositionEnabled; diff --git a/src/win32_window.c b/src/win32_window.c index 8cb505004..7163c6712 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -773,6 +773,13 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, { int i, button, action; + if (window->touchInput) + { + // Skip emulated button events when touch input is enabled + if ((GetMessageExtraInfo() & 0xffffff00) == 0xff515700) + break; + } + if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) button = GLFW_MOUSE_BUTTON_LEFT; else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP) @@ -856,7 +863,9 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, window->win32.lastCursorPosX = x; window->win32.lastCursorPosY = y; - return 0; + // NOTE: WM_MOUSEMOVE messages must be passed on to DefWindowProc + // for WM_TOUCH messages to be emitted + break; } case WM_INPUT: @@ -1067,6 +1076,60 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, return 0; } + case WM_TOUCH: + { + 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))) + { + UINT i; + int width, height, xpos, ypos; + + _glfwPlatformGetWindowSize(window, &width, &height); + _glfwPlatformGetWindowPos(window, &xpos, &ypos); + + for (i = 0; i < count; i++) + { + int action; + POINT pos; + + pos.x = TOUCH_COORD_TO_PIXEL(inputs[i].x) - xpos; + pos.y = TOUCH_COORD_TO_PIXEL(inputs[i].y) - ypos; + + // Discard any points that lie outside of the client area + if (pos.x < 0 || pos.x >= width || + pos.y < 0 || pos.y >= height) + { + continue; + } + + if (inputs[i].dwFlags & TOUCHEVENTF_DOWN) + action = GLFW_PRESS; + else if (inputs[i].dwFlags & TOUCHEVENTF_UP) + action = GLFW_RELEASE; + else + action = GLFW_MOVE; + + _glfwInputTouch(window, + (int) inputs[i].dwID, action, + inputs[i].x / 100.0 - xpos, + inputs[i].y / 100.0 - ypos); + } + + CloseTouchInputHandle((HTOUCHINPUT) lParam); + } + + free(inputs); + break; + } + case WM_PAINT: { _glfwInputWindowDamage(window); @@ -1940,6 +2003,22 @@ GLFWbool _glfwPlatformRawMouseMotionSupported(void) return GLFW_TRUE; } +void _glfwPlatformSetTouchInput(_GLFWwindow* window, int enabled) +{ + if (!_glfw.win32.touch.available) + return; + + if (enabled) + RegisterTouchWindow(window->win32.handle, 0); + else + UnregisterTouchWindow(window->win32.handle); +} + +GLFWbool _glfwPlatformTouchInputSupported(void) +{ + return _glfw.win32.touch.available; +} + void _glfwPlatformPollEvents(void) { MSG msg; diff --git a/src/wl_window.c b/src/wl_window.c index 7b315d70f..c427f6101 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1163,6 +1163,17 @@ GLFWbool _glfwPlatformRawMouseMotionSupported(void) return GLFW_TRUE; } +void _glfwPlatformSetTouchInput(_GLFWwindow *window, GLFWbool enabled) +{ + _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, + "Wayland: Touch input not yet implemented"); +} + +GLFWbool _glfwPlatformTouchInputSupported(void) +{ + return GLFW_FALSE; +} + void _glfwPlatformPollEvents(void) { handleEvents(0); diff --git a/src/x11_window.c b/src/x11_window.c index 4cd32940d..5c9b01ef1 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -2771,6 +2771,17 @@ GLFWbool _glfwPlatformRawMouseMotionSupported(void) return _glfw.x11.xi.available; } +void _glfwPlatformSetTouchInput(_GLFWwindow *window, GLFWbool enabled) +{ + _glfwInputError(GLFW_FEATURE_UNIMPLEMENTED, + "Cocoa: Touch input not yet implemented"); +} + +GLFWbool _glfwPlatformTouchInputSupported(void) +{ + return GLFW_FALSE; +} + void _glfwPlatformPollEvents(void) { _GLFWwindow* window; diff --git a/tests/events.c b/tests/events.c index 86a63df28..10d2d8906 100644 --- a/tests/events.c +++ b/tests/events.c @@ -51,6 +51,7 @@ typedef struct GLFWwindow* window; int number; int closeable; + int touch; } Slot; static void usage(void) @@ -204,6 +205,8 @@ static const char* get_action_name(int action) return "released"; case GLFW_REPEAT: return "repeated"; + case GLFW_MOVE: + return "moved"; } return "caused unknown action"; @@ -424,6 +427,15 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, switch (key) { + case GLFW_KEY_T: + { + slot->touch = !slot->touch; + glfwSetInputMode(window, GLFW_TOUCH, slot->touch); + + printf("(( touch %s ))\n", slot->touch ? "enabled" : "disabled"); + break; + } + case GLFW_KEY_C: { slot->closeable = !slot->closeable; @@ -492,6 +504,16 @@ static void monitor_callback(GLFWmonitor* monitor, int event) } } +static void touch_callback(GLFWwindow* window, int touch, int action, double x, double y) +{ + printf("%08x at %0.3f: Touch %i %s at position %0.3f %0.3f\n", + counter++, + glfwGetTime(), + touch, + get_action_name(action), + x, y); +} + static void joystick_callback(int jid, int event) { if (event == GLFW_CONNECTED) @@ -594,6 +616,7 @@ int main(int argc, char** argv) char title[128]; slots[i].closeable = GLFW_TRUE; + slots[i].touch = GLFW_FALSE; slots[i].number = i + 1; snprintf(title, sizeof(title), "Event Linter (Window %i)", slots[i].number); @@ -638,6 +661,7 @@ int main(int argc, char** argv) glfwSetKeyCallback(slots[i].window, key_callback); glfwSetCharCallback(slots[i].window, char_callback); glfwSetDropCallback(slots[i].window, drop_callback); + glfwSetTouchCallback(slots[i].window, touch_callback); glfwMakeContextCurrent(slots[i].window); gladLoadGL(glfwGetProcAddress);