mirror of
https://github.com/glfw/glfw.git
synced 2025-10-03 21:30:57 +00:00
Add minimal wintab32 support
This commit is contained in:
parent
2fbb560eb7
commit
79ac263771
@ -1510,6 +1510,57 @@ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);
|
|||||||
*/
|
*/
|
||||||
typedef void (* GLFWjoystickfun)(int,int);
|
typedef void (* GLFWjoystickfun)(int,int);
|
||||||
|
|
||||||
|
/*! @brief The function signature for pen tablet data callbacks.
|
||||||
|
*
|
||||||
|
* This is the function signature for pen tablet data callback functions.
|
||||||
|
*
|
||||||
|
* @param[in] x pen position relative to the screen.
|
||||||
|
* @param[in] y pen position relative to the screen.
|
||||||
|
* @param[in] z pen position relative to the tablet.
|
||||||
|
* @param[in] pen pressure from 0.0 to 1.0.
|
||||||
|
* @param[in] pen pitch in degree.
|
||||||
|
* @param[in] pen yaw in degree.
|
||||||
|
* @param[in] pen roll in degree.
|
||||||
|
*
|
||||||
|
* @sa @ref pen_tablet_data
|
||||||
|
* @sa @ref glfwSetPenTabletDataCallback
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
typedef void (* GLFWpentabletdatafun)(double,double,double,double,double,double,double);
|
||||||
|
|
||||||
|
/*! @brief The function signature for pen tablet cursor callbacks.
|
||||||
|
*
|
||||||
|
* This is the function signature for pen tablet cursor callback functions.
|
||||||
|
*
|
||||||
|
* @param[in] pen cursor identifier.
|
||||||
|
*
|
||||||
|
* @sa @ref pen_tablet_cursor
|
||||||
|
* @sa @ref glfwSetPenTabletCursorCallback
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
typedef void (* GLFWpentabletcursorfun)(unsigned int);
|
||||||
|
|
||||||
|
/*! @brief The function signature for pen tablet proximity callbacks.
|
||||||
|
*
|
||||||
|
* This is the function signature for pen tablet proximity callback functions.
|
||||||
|
*
|
||||||
|
* @param[in] pen proximity state.
|
||||||
|
*
|
||||||
|
* @sa @ref pen_tablet_proximity
|
||||||
|
* @sa @ref glfwSetPenTabletProximityCallback
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
typedef void (* GLFWpentabletproximityfun)(int);
|
||||||
|
|
||||||
/*! @brief Video mode type.
|
/*! @brief Video mode type.
|
||||||
*
|
*
|
||||||
* This describes a single video mode.
|
* This describes a single video mode.
|
||||||
@ -4963,6 +5014,72 @@ GLFWAPI const char* glfwGetGamepadName(int jid);
|
|||||||
*/
|
*/
|
||||||
GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
|
GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
|
||||||
|
|
||||||
|
/*! @brief Sets the pen tablet data callback.
|
||||||
|
*
|
||||||
|
* This function sets the pen tablet data callback, or removes the
|
||||||
|
* currently set callback. This is called when the pen tablet data is updated.
|
||||||
|
*
|
||||||
|
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
|
||||||
|
* callback.
|
||||||
|
* @return The previously set callback, or `NULL` if no callback was set or the
|
||||||
|
* library had not been [initialized](@ref intro_init).
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref pen_tablet_event
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
GLFWAPI GLFWpentabletdatafun glfwSetPenTabletDataCallback(GLFWpentabletdatafun cbfun);
|
||||||
|
|
||||||
|
/*! @brief Sets the pen tablet cursor callback.
|
||||||
|
*
|
||||||
|
* This function sets the pen tablet cursor callback, or removes the
|
||||||
|
* currently set callback. This is called when the pen tablet cursor has changed.
|
||||||
|
*
|
||||||
|
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
|
||||||
|
* callback.
|
||||||
|
* @return The previously set callback, or `NULL` if no callback was set or the
|
||||||
|
* library had not been [initialized](@ref intro_init).
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref pen_tablet_event
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
GLFWAPI GLFWpentabletcursorfun glfwSetPenTabletCursorCallback(GLFWpentabletcursorfun cbfun);
|
||||||
|
|
||||||
|
/*! @brief Sets the pen tablet proximity callback.
|
||||||
|
*
|
||||||
|
* This function sets the pen tablet proximity callback, or removes the
|
||||||
|
* currently set callback. This is called when the pen tablet proximity has changed.
|
||||||
|
*
|
||||||
|
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
|
||||||
|
* callback.
|
||||||
|
* @return The previously set callback, or `NULL` if no callback was set or the
|
||||||
|
* library had not been [initialized](@ref intro_init).
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||||
|
*
|
||||||
|
* @thread_safety This function must only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref pen_tablet_event
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
GLFWAPI GLFWpentabletproximityfun glfwSetPenTabletProximityCallback(GLFWpentabletproximityfun cbfun);
|
||||||
|
|
||||||
/*! @brief Sets the clipboard to the specified string.
|
/*! @brief Sets the clipboard to the specified string.
|
||||||
*
|
*
|
||||||
* This function sets the system clipboard to the specified, UTF-8 encoded
|
* This function sets the system clipboard to the specified, UTF-8 encoded
|
||||||
|
44
src/input.c
44
src/input.c
@ -401,6 +401,29 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
|
|||||||
js->hats[hat] = value;
|
js->hats[hat] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notifies shared code of the new value of the pen tablet data
|
||||||
|
//
|
||||||
|
void _glfwInputPenTabletData(double x, double y, double z, double pressure, double pitch, double yaw, double roll)
|
||||||
|
{
|
||||||
|
if (_glfw.callbacks.pentabletdata)
|
||||||
|
_glfw.callbacks.pentabletdata(x, y, z, pressure, pitch, yaw, roll);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notifies shared code of the new value of the pen tablet cursor
|
||||||
|
//
|
||||||
|
void _glfwInputPenTabletCursor(unsigned int cursor)
|
||||||
|
{
|
||||||
|
if (_glfw.callbacks.pentabletcursor)
|
||||||
|
_glfw.callbacks.pentabletcursor(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notifies shared code of the new value of the pen tablet proximity
|
||||||
|
//
|
||||||
|
void _glfwInputPenTabletProximity(int proximity)
|
||||||
|
{
|
||||||
|
if (_glfw.callbacks.pentabletproximity)
|
||||||
|
_glfw.callbacks.pentabletproximity(proximity);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
@ -1294,6 +1317,27 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWpentabletdatafun glfwSetPenTabletDataCallback(GLFWpentabletdatafun cbfun)
|
||||||
|
{
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
_GLFW_SWAP_POINTERS(_glfw.callbacks.pentabletdata, cbfun);
|
||||||
|
return cbfun;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWpentabletcursorfun glfwSetPenTabletCursorCallback(GLFWpentabletcursorfun cbfun)
|
||||||
|
{
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
_GLFW_SWAP_POINTERS(_glfw.callbacks.pentabletcursor, cbfun);
|
||||||
|
return cbfun;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWpentabletproximityfun glfwSetPenTabletProximityCallback(GLFWpentabletproximityfun cbfun)
|
||||||
|
{
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
_GLFW_SWAP_POINTERS(_glfw.callbacks.pentabletproximity, cbfun);
|
||||||
|
return cbfun;
|
||||||
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
||||||
{
|
{
|
||||||
assert(string != NULL);
|
assert(string != NULL);
|
||||||
|
@ -567,6 +567,9 @@ struct _GLFWlibrary
|
|||||||
struct {
|
struct {
|
||||||
GLFWmonitorfun monitor;
|
GLFWmonitorfun monitor;
|
||||||
GLFWjoystickfun joystick;
|
GLFWjoystickfun joystick;
|
||||||
|
GLFWpentabletdatafun pentabletdata;
|
||||||
|
GLFWpentabletcursorfun pentabletcursor;
|
||||||
|
GLFWpentabletproximityfun pentabletproximity;
|
||||||
} callbacks;
|
} callbacks;
|
||||||
|
|
||||||
// This is defined in the window API's platform.h
|
// This is defined in the window API's platform.h
|
||||||
@ -728,6 +731,10 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value);
|
|||||||
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement);
|
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement);
|
||||||
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
|
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
|
||||||
|
|
||||||
|
void _glfwInputPenTabletData(double x, double y, double z, double pressure, double pitch, double yaw, double roll);
|
||||||
|
void _glfwInputPenTabletCursor(unsigned int cursor);
|
||||||
|
void _glfwInputPenTabletProximity(int proximity);
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
void _glfwInputError(int code, const char* format, ...)
|
void _glfwInputError(int code, const char* format, ...)
|
||||||
__attribute__((format(printf, 2, 3)));
|
__attribute__((format(printf, 2, 3)));
|
||||||
|
@ -159,6 +159,21 @@ static GLFWbool loadLibraries(void)
|
|||||||
GetProcAddress(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
|
GetProcAddress(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfw.win32.wintab32.instance = LoadLibraryA("Wintab32.dll");
|
||||||
|
if (_glfw.win32.wintab32.instance)
|
||||||
|
{
|
||||||
|
_glfw.win32.wintab32.WTInfoA = (PFN_WTInfoA)
|
||||||
|
GetProcAddress(_glfw.win32.wintab32.instance, "WTInfoA");
|
||||||
|
_glfw.win32.wintab32.WTOpenA = (PFN_WTOpenA)
|
||||||
|
GetProcAddress(_glfw.win32.wintab32.instance, "WTOpenA");
|
||||||
|
_glfw.win32.wintab32.WTQueueSizeSet = (PFN_WTQueueSizeSet)
|
||||||
|
GetProcAddress(_glfw.win32.wintab32.instance, "WTQueueSizeSet");
|
||||||
|
_glfw.win32.wintab32.WTClose = (PFN_WTClose)
|
||||||
|
GetProcAddress(_glfw.win32.wintab32.instance, "WTClose");
|
||||||
|
_glfw.win32.wintab32.WTPacket = (PFN_WTPacket)
|
||||||
|
GetProcAddress(_glfw.win32.wintab32.instance, "WTPacket");
|
||||||
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +201,9 @@ static void freeLibraries(void)
|
|||||||
|
|
||||||
if (_glfw.win32.ntdll.instance)
|
if (_glfw.win32.ntdll.instance)
|
||||||
FreeLibrary(_glfw.win32.ntdll.instance);
|
FreeLibrary(_glfw.win32.ntdll.instance);
|
||||||
|
|
||||||
|
if (_glfw.win32.wintab32.instance)
|
||||||
|
FreeLibrary(_glfw.win32.wintab32.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create key code translation tables
|
// Create key code translation tables
|
||||||
@ -327,6 +345,46 @@ static void createKeyTables(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Init wintab context see https://developer-docs.wacom.com/display/DevDocs/Windows+Wintab+Documentation
|
||||||
|
//
|
||||||
|
static void initWintabContext(HWND hwnd)
|
||||||
|
{
|
||||||
|
if (_glfw.win32.wintab32.instance) {
|
||||||
|
LOGCONTEXTA context = {0};
|
||||||
|
|
||||||
|
_glfw.win32.wintab32.WTInfoA(4, 0, &context);
|
||||||
|
context.lcPktData = 0x0080 | 0x0100 | 0x0200 | 0x0040 | 0x0400 | 0x1000 | 0x0008 | 0x0020; // X Y Z BUTTONS NPRESSURE ORIENTATION CHANGED CURSOR
|
||||||
|
context.lcPktMode = 0;
|
||||||
|
context.lcMoveMask = context.lcPktData;
|
||||||
|
context.lcBtnUpMask = context.lcBtnDnMask;
|
||||||
|
context.lcOptions |= 0x0004; // CXO MESSAGES
|
||||||
|
context.lcOutOrgX = context.lcInOrgX;
|
||||||
|
context.lcOutOrgY = context.lcInOrgY;
|
||||||
|
context.lcOutExtX = context.lcInExtX;
|
||||||
|
context.lcOutExtY = -context.lcInExtY;
|
||||||
|
|
||||||
|
// open wintab context
|
||||||
|
_glfw.win32.wintab32.context = _glfw.win32.wintab32.WTOpenA(hwnd, &context, TRUE);
|
||||||
|
if (_glfw.win32.wintab32.context) {
|
||||||
|
_glfw.win32.wintab32.WTQueueSizeSet(_glfw.win32.wintab32.context, 256);
|
||||||
|
_glfw.win32.wintab32.WTInfoA(4, 0, &_glfw.win32.wintab32.contextInfo);
|
||||||
|
_glfw.win32.wintab32.WTInfoA(100, 15, &_glfw.win32.wintab32.pressureInfo);
|
||||||
|
_glfw.win32.wintab32.WTInfoA(100, 17, &_glfw.win32.wintab32.orientationInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_glfw.win32.wintab32.context = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Terminate wintab context
|
||||||
|
//
|
||||||
|
static void terminateWintabContext(void)
|
||||||
|
{
|
||||||
|
if (_glfw.win32.wintab32.instance && _glfw.win32.wintab32.context)
|
||||||
|
_glfw.win32.wintab32.WTClose(_glfw.win32.wintab32.context);
|
||||||
|
}
|
||||||
|
|
||||||
// Creates a dummy window for behind-the-scenes work
|
// Creates a dummy window for behind-the-scenes work
|
||||||
//
|
//
|
||||||
static HWND createHelperWindow(void)
|
static HWND createHelperWindow(void)
|
||||||
@ -577,6 +635,7 @@ int _glfwPlatformInit(void)
|
|||||||
|
|
||||||
_glfwInitTimerWin32();
|
_glfwInitTimerWin32();
|
||||||
_glfwInitJoysticksWin32();
|
_glfwInitJoysticksWin32();
|
||||||
|
initWintabContext(_glfw.win32.helperWindowHandle);
|
||||||
|
|
||||||
_glfwPollMonitorsWin32();
|
_glfwPollMonitorsWin32();
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@ -604,6 +663,7 @@ void _glfwPlatformTerminate(void)
|
|||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
|
|
||||||
_glfwTerminateJoysticksWin32();
|
_glfwTerminateJoysticksWin32();
|
||||||
|
terminateWintabContext();
|
||||||
|
|
||||||
freeLibraries();
|
freeLibraries();
|
||||||
}
|
}
|
||||||
|
@ -258,6 +258,78 @@ typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,
|
|||||||
typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
|
typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
|
||||||
#define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_
|
#define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_
|
||||||
|
|
||||||
|
// wintab.dll function pointer typedefs
|
||||||
|
#define WT_PACKET 0x7FF0
|
||||||
|
#define WT_PROXIMITY 0x7FF5
|
||||||
|
DECLARE_HANDLE(HCTX);
|
||||||
|
|
||||||
|
typedef struct tagAXIS {
|
||||||
|
LONG min;
|
||||||
|
LONG max;
|
||||||
|
UINT units;
|
||||||
|
DWORD resolution;
|
||||||
|
} AXIS;
|
||||||
|
|
||||||
|
typedef struct tagORIENTATION {
|
||||||
|
int azimuth;
|
||||||
|
int altitude;
|
||||||
|
int twist;
|
||||||
|
} ORIENTATION;
|
||||||
|
|
||||||
|
typedef struct tagPACKET {
|
||||||
|
DWORD changed;
|
||||||
|
UINT cursor;
|
||||||
|
DWORD buttons;
|
||||||
|
DWORD x;
|
||||||
|
DWORD y;
|
||||||
|
DWORD z;
|
||||||
|
UINT normalPressure;
|
||||||
|
ORIENTATION orientation;
|
||||||
|
} PACKET;
|
||||||
|
|
||||||
|
typedef struct LOGCONTEXTA {
|
||||||
|
char lcName[40];
|
||||||
|
UINT lcOptions;
|
||||||
|
UINT lcStatus;
|
||||||
|
UINT lcLocks;
|
||||||
|
UINT lcMsgBase;
|
||||||
|
UINT lcDevice;
|
||||||
|
UINT lcPktRate;
|
||||||
|
DWORD lcPktData;
|
||||||
|
DWORD lcPktMode;
|
||||||
|
DWORD lcMoveMask;
|
||||||
|
DWORD lcBtnDnMask;
|
||||||
|
DWORD lcBtnUpMask;
|
||||||
|
LONG lcInOrgX;
|
||||||
|
LONG lcInOrgY;
|
||||||
|
LONG lcInOrgZ;
|
||||||
|
LONG lcInExtX;
|
||||||
|
LONG lcInExtY;
|
||||||
|
LONG lcInExtZ;
|
||||||
|
LONG lcOutOrgX;
|
||||||
|
LONG lcOutOrgY;
|
||||||
|
LONG lcOutOrgZ;
|
||||||
|
LONG lcOutExtX;
|
||||||
|
LONG lcOutExtY;
|
||||||
|
LONG lcOutExtZ;
|
||||||
|
DWORD lcSensX;
|
||||||
|
DWORD lcSensY;
|
||||||
|
DWORD lcSensZ;
|
||||||
|
BOOL lcSysMode;
|
||||||
|
int lcSysOrgX;
|
||||||
|
int lcSysOrgY;
|
||||||
|
int lcSysExtX;
|
||||||
|
int lcSysExtY;
|
||||||
|
DWORD lcSysSensX;
|
||||||
|
DWORD lcSysSensY;
|
||||||
|
} LOGCONTEXTA, *PLOGCONTEXTA, NEAR *NPLOGCONTEXTA, FAR *LPLOGCONTEXTA;
|
||||||
|
|
||||||
|
typedef UINT (WINAPI * PFN_WTInfoA)(UINT,UINT,LPVOID);
|
||||||
|
typedef HCTX (WINAPI * PFN_WTOpenA)(HWND,LPLOGCONTEXTA,BOOL);
|
||||||
|
typedef BOOL (WINAPI * PFN_WTQueueSizeSet)(HCTX,int);
|
||||||
|
typedef BOOL (WINAPI * PFN_WTClose)(HCTX);
|
||||||
|
typedef BOOL (WINAPI * PFN_WTPacket)(HCTX,UINT,LPVOID);
|
||||||
|
|
||||||
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
|
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
typedef struct VkWin32SurfaceCreateInfoKHR
|
typedef struct VkWin32SurfaceCreateInfoKHR
|
||||||
@ -383,6 +455,19 @@ typedef struct _GLFWlibraryWin32
|
|||||||
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
|
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
|
||||||
} ntdll;
|
} ntdll;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
HINSTANCE instance;
|
||||||
|
PFN_WTInfoA WTInfoA;
|
||||||
|
PFN_WTOpenA WTOpenA;
|
||||||
|
PFN_WTQueueSizeSet WTQueueSizeSet;
|
||||||
|
PFN_WTClose WTClose;
|
||||||
|
PFN_WTPacket WTPacket;
|
||||||
|
HCTX context;
|
||||||
|
LOGCONTEXTA contextInfo;
|
||||||
|
AXIS pressureInfo;
|
||||||
|
AXIS orientationInfo[3];
|
||||||
|
} wintab32;
|
||||||
|
|
||||||
} _GLFWlibraryWin32;
|
} _GLFWlibraryWin32;
|
||||||
|
|
||||||
// Win32-specific per-monitor data
|
// Win32-specific per-monitor data
|
||||||
|
@ -616,6 +616,48 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WT_PROXIMITY:
|
||||||
|
{
|
||||||
|
_glfwInputPenTabletProximity(lParam != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
case WT_PACKET:
|
||||||
|
if (_glfw.win32.wintab32.instance)
|
||||||
|
{
|
||||||
|
#define FIX2DOUBLE(x) ((double)(HIWORD(x))+((double)LOWORD(x)/65536))
|
||||||
|
PACKET packet;
|
||||||
|
LOGCONTEXTA contextInfo = _glfw.win32.wintab32.contextInfo;
|
||||||
|
AXIS pressureInfo = _glfw.win32.wintab32.pressureInfo;
|
||||||
|
AXIS altInfo = _glfw.win32.wintab32.orientationInfo[1];
|
||||||
|
AXIS aziInfo = _glfw.win32.wintab32.orientationInfo[0];
|
||||||
|
AXIS rollInfo = _glfw.win32.wintab32.orientationInfo[2];
|
||||||
|
|
||||||
|
while (_glfw.win32.wintab32.WTPacket(_glfw.win32.wintab32.context, (UINT)wParam, &packet)) {
|
||||||
|
|
||||||
|
double x, y, z, pressure, pitch=0, yaw=0, roll=0;
|
||||||
|
|
||||||
|
x = ((double)(packet.x - contextInfo.lcInOrgX) / contextInfo.lcInExtX) * contextInfo.lcSysExtX + contextInfo.lcSysOrgX;
|
||||||
|
y = ((double)(packet.y - contextInfo.lcInOrgY) / contextInfo.lcInExtY) * contextInfo.lcSysExtY + contextInfo.lcSysOrgY;
|
||||||
|
z = ((double)(packet.z - contextInfo.lcOutOrgZ) / contextInfo.lcOutExtZ);
|
||||||
|
pressure = (double)(packet.normalPressure - pressureInfo.min) / (pressureInfo.max - pressureInfo.min);
|
||||||
|
if (aziInfo.resolution && altInfo.resolution) {
|
||||||
|
double alt = (double)(packet.orientation.altitude - altInfo.min) / (altInfo.max - altInfo.min);
|
||||||
|
double azi = (double)(packet.orientation.azimuth - aziInfo.min) / (aziInfo.max - aziInfo.min);
|
||||||
|
pitch = (0.5 - alt) * 180.0;
|
||||||
|
yaw = azi * 360.0;
|
||||||
|
}
|
||||||
|
if (rollInfo.resolution) { // roll seems to be mostly unsupported so this is untested
|
||||||
|
roll = (double)(packet.orientation.twist - rollInfo.min) / (rollInfo.max - rollInfo.min) * 360.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet.changed & 0x0020) { // CURSOR changed
|
||||||
|
_glfwInputPenTabletCursor(packet.cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwInputPenTabletData(x, y, z, pressure, pitch, yaw, roll);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||||
|
@ -42,6 +42,10 @@
|
|||||||
|
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
// Event index
|
// Event index
|
||||||
static unsigned int counter = 0;
|
static unsigned int counter = 0;
|
||||||
|
|
||||||
@ -493,6 +497,24 @@ static void joystick_callback(int jid, int event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void penTabletData_callback(double x, double y, double z, double pressure, double pitch, double yaw, double roll)
|
||||||
|
{
|
||||||
|
printf("%08x at %0.3f: pen: %f %f %f %f %f %f %f\n",
|
||||||
|
counter++, glfwGetTime(), x, y, z, pressure, pitch, yaw, roll);
|
||||||
|
}
|
||||||
|
|
||||||
|
void penTabletCursor_callback(unsigned int cursor)
|
||||||
|
{
|
||||||
|
printf("%08x at %0.3f: pen cursor: %d\n",
|
||||||
|
counter++, glfwGetTime(), cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void penTabletProximity_callback(int proximity)
|
||||||
|
{
|
||||||
|
printf("%08x at %0.3f: pen proximity: %d\n",
|
||||||
|
counter++, glfwGetTime(), proximity);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
Slot* slots;
|
Slot* slots;
|
||||||
@ -510,6 +532,9 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
glfwSetMonitorCallback(monitor_callback);
|
glfwSetMonitorCallback(monitor_callback);
|
||||||
glfwSetJoystickCallback(joystick_callback);
|
glfwSetJoystickCallback(joystick_callback);
|
||||||
|
glfwSetPenTabletDataCallback(penTabletData_callback);
|
||||||
|
glfwSetPenTabletCursorCallback(penTabletCursor_callback);
|
||||||
|
glfwSetPenTabletProximityCallback(penTabletProximity_callback);
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "hfn:")) != -1)
|
while ((ch = getopt(argc, argv, "hfn:")) != -1)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user