Skip to content

Commit

Permalink
Support Windows touch (Windows7 and later)
Browse files Browse the repository at this point in the history
Thanks to: glfw#1736
  • Loading branch information
xfangfang committed Mar 27, 2023
1 parent 9137ab5 commit c0ddac1
Show file tree
Hide file tree
Showing 19 changed files with 362 additions and 11 deletions.
86 changes: 77 additions & 9 deletions include/GLFW/glfw3.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,18 +320,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
*/
Expand All @@ -343,6 +343,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
Expand Down Expand Up @@ -1149,6 +1156,7 @@ extern "C" {
#define GLFW_LOCK_KEY_MODS 0x00033004
#define GLFW_RAW_MOUSE_MOTION 0x00033005
#define GLFW_IME 0x00033006
#define GLFW_TOUCH 0x00033007

#define GLFW_CURSOR_NORMAL 0x00034001
#define GLFW_CURSOR_HIDDEN 0x00034002
Expand Down Expand Up @@ -2000,6 +2008,26 @@ typedef void (* GLFWpreeditcandidatefun)(GLFWwindow* window,
*/
typedef void (* GLFWdropfun)(GLFWwindow* window, int path_count, const char* paths[]);

/*! @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.
Expand Down Expand Up @@ -4625,12 +4653,12 @@ 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,
* @ref GLFW_RAW_MOUSE_MOTION or @ref GLFW_IME.
* @ref GLFW_RAW_MOUSE_MOTION, @ref GLFW_IME 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`, `GLFW_RAW_MOUSE_MOTION`,
* or `GLFW_IME`.
* `GLFW_IME`, or `GLFW_TOUCH`..
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_INVALID_ENUM.
Expand All @@ -4650,7 +4678,7 @@ 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,
* @ref GLFW_RAW_MOUSE_MOTION or @ref GLFW_IME.
* @ref GLFW_RAW_MOUSE_MOTION, @ref GLFW_IME or @ref GLFW_TOUCH.
*
* If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
* modes:
Expand Down Expand Up @@ -4693,10 +4721,15 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* If the mode is `GLFW_IME`, the value must be either `GLFW_TRUE` to turn on
* IME, or `GLFW_FALSE` to turn off it.
*
* 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`,
* `GLFW_RAW_MOUSE_MOTION` or `GLFW_IME`.
* `GLFW_RAW_MOUSE_MOTION`, `GLFW_IME` or `GLFW_TOUCH`.
* @param[in] value The new value of the specified input mode.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
Expand Down Expand Up @@ -4742,6 +4775,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
Expand Down Expand Up @@ -5638,6 +5691,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.
Expand Down
2 changes: 2 additions & 0 deletions src/cocoa_init.m
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,8 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
_glfwResetPreeditTextCocoa,
_glfwSetIMEStatusCocoa,
_glfwGetIMEStatusCocoa,
_glfwSetTouchInputCocoa,
_glfwTouchInputSupportedCocoa,
_glfwInitJoysticksCocoa,
_glfwTerminateJoysticksCocoa,
_glfwPollJoystickCocoa,
Expand Down
3 changes: 3 additions & 0 deletions src/cocoa_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ void _glfwSetWindowMousePassthroughCocoa(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetRawMouseMotionCocoa(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedCocoa(void);

void _glfwSetTouchInputCocoa(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwTouchInputSupportedCocoa(void);

void _glfwPollEventsCocoa(void);
void _glfwWaitEventsCocoa(void);
void _glfwWaitEventsTimeoutCocoa(double timeout);
Expand Down
11 changes: 11 additions & 0 deletions src/cocoa_window.m
Original file line number Diff line number Diff line change
Expand Up @@ -1635,6 +1635,17 @@ GLFWbool _glfwRawMouseMotionSupportedCocoa(void)
return GLFW_FALSE;
}

void _glfwSetTouchInputCocoa(_GLFWwindow *window, GLFWbool enabled)
{
_glfwInputError(GLFW_FEATURE_UNIMPLEMENTED,
"Cocoa: Touch input not yet implemented");
}

GLFWbool _glfwTouchInputSupportedCocoa(void)
{
return GLFW_FALSE;
}

void _glfwPollEventsCocoa(void)
{
@autoreleasepool {
Expand Down
44 changes: 43 additions & 1 deletion src/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#include <string.h>

// 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
Expand Down Expand Up @@ -455,6 +455,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)
Expand Down Expand Up @@ -615,6 +623,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:
Expand Down Expand Up @@ -734,6 +744,24 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
_glfw.platform.setIMEStatus(window, value ? GLFW_TRUE : GLFW_FALSE);
return;
}

case GLFW_TOUCH:
{
if (!_glfw.platform.touchInputSupported())
{
_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;
_glfw.platform.setTouchInput(window, value);
return;
}
}

_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
Expand All @@ -745,6 +773,12 @@ GLFWAPI int glfwRawMouseMotionSupported(void)
return _glfw.platform.rawMouseMotionSupported();
}

GLFWAPI int glfwTouchInputSupported(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
return _glfw.platform.touchInputSupported();
}

GLFWAPI const char* glfwGetKeyName(int key, int scancode)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
Expand Down Expand Up @@ -1582,6 +1616,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(GLFWtouchfun, window->callbacks.touch, cbfun);
return cbfun;
}

GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
{
assert(string != NULL);
Expand Down
6 changes: 6 additions & 0 deletions src/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ struct _GLFWwindow

GLFWbool stickyKeys;
GLFWbool stickyMouseButtons;
GLFWbool touchInput;
GLFWbool lockKeyMods;
int cursorMode;
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
Expand Down Expand Up @@ -612,6 +613,7 @@ struct _GLFWwindow
GLFWimestatusfun imestatus;
GLFWpreeditcandidatefun preeditCandidate;
GLFWdropfun drop;
GLFWtouchfun touch;
} callbacks;

// This is defined in platform.h
Expand Down Expand Up @@ -734,6 +736,8 @@ struct _GLFWplatform
void (*resetPreeditText)(_GLFWwindow*);
void (*setIMEStatus)(_GLFWwindow*,int);
int (*getIMEStatus)(_GLFWwindow*);
void (*setTouchInput)(_GLFWwindow*,int);
GLFWbool (*touchInputSupported)(void);
GLFWbool (*initJoysticks)(void);
void (*terminateJoysticks)(void);
GLFWbool (*pollJoystick)(_GLFWjoystick*,int);
Expand Down Expand Up @@ -973,6 +977,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);
Expand Down
2 changes: 2 additions & 0 deletions src/null_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
_glfwResetPreeditTextNull,
_glfwSetIMEStatusNull,
_glfwGetIMEStatusNull,
_glfwSetTouchInputNull,
_glfwTouchInputSupportedNull,
_glfwInitJoysticksNull,
_glfwTerminateJoysticksNull,
_glfwPollJoystickNull,
Expand Down
3 changes: 3 additions & 0 deletions src/null_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ void _glfwResetPreeditTextNull(_GLFWwindow* window);
void _glfwSetIMEStatusNull(_GLFWwindow* window, int active);
int _glfwGetIMEStatusNull(_GLFWwindow* window);

void _glfwSetTouchInputNull(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwTouchInputSupportedNull(void);

EGLenum _glfwGetEGLPlatformNull(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void);
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window);
Expand Down
9 changes: 9 additions & 0 deletions src/null_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,15 @@ void _glfwShowWindowNull(_GLFWwindow* window)
window->null.visible = GLFW_TRUE;
}

void _glfwSetTouchInputNull(_GLFWwindow *window, GLFWbool enabled)
{
}

GLFWbool _glfwTouchInputSupportedNull(void)
{
return GLFW_TRUE;
}

void _glfwRequestWindowAttentionNull(_GLFWwindow* window)
{
}
Expand Down
19 changes: 19 additions & 0 deletions src/win32_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,23 @@ static GLFWbool loadLibraries(void)
_glfwPlatformGetModuleSymbol(_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[] =
Expand Down Expand Up @@ -653,6 +670,8 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
_glfwResetPreeditTextWin32,
_glfwSetIMEStatusWin32,
_glfwGetIMEStatusWin32,
_glfwSetTouchInputWin32,
_glfwTouchInputSupportedWin32,
_glfwInitJoysticksWin32,
_glfwTerminateJoysticksWin32,
_glfwPollJoystickWin32,
Expand Down

0 comments on commit c0ddac1

Please sign in to comment.