mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-22 07:11:43 +08:00
pen: Rework public API.
This changes the API in various ways, and updates the backends for this. Overall, this is a massive simplification of the API, as most future backends can't support the previously-offered API. This also removes the testautomation pen code (not only did these interfaces change completely, it also did something no other test did: mock the internal API), and replaces testpen.c with a different implementation (the existing code was fine, it was just easier to start from scratch than update it).
This commit is contained in:
@@ -212,12 +212,6 @@
|
||||
<ClCompile Include="..\..\..\test\testautomation_main.c" />
|
||||
<ClCompile Include="..\..\..\test\testautomation_math.c" />
|
||||
<ClCompile Include="..\..\..\test\testautomation_mouse.c" />
|
||||
<ClCompile Include="..\..\..\test\testautomation_pen.c">
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)\..\..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)\..\..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)\..\..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)\..\..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\test\testautomation_pixels.c" />
|
||||
<ClCompile Include="..\..\..\test\testautomation_platform.c" />
|
||||
<ClCompile Include="..\..\..\test\testautomation_properties.c" />
|
||||
|
||||
@@ -1274,7 +1274,6 @@
|
||||
4537749212091504002F0F45 /* testshape.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testshape.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
453774A4120915E3002F0F45 /* testshape.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testshape.c; sourceTree = "<group>"; };
|
||||
66E88E8A203B778F0004D44E /* testyuv_cvt.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testyuv_cvt.c; sourceTree = "<group>"; };
|
||||
A1A859442BC72FC20045DD6C /* testautomation_pen.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_pen.c; sourceTree = "<group>"; };
|
||||
A1A859482BC72FC20045DD6C /* testautomation_properties.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_properties.c; sourceTree = "<group>"; };
|
||||
A1A859492BC72FC20045DD6C /* testautomation_subsystems.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_subsystems.c; sourceTree = "<group>"; };
|
||||
A1A8594A2BC72FC20045DD6C /* testautomation_log.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_log.c; sourceTree = "<group>"; };
|
||||
@@ -1804,7 +1803,6 @@
|
||||
F35E56B62983130A00A43A5F /* testautomation_main.c */,
|
||||
F35E56BA2983130B00A43A5F /* testautomation_math.c */,
|
||||
F35E56CD2983130F00A43A5F /* testautomation_mouse.c */,
|
||||
A1A859442BC72FC20045DD6C /* testautomation_pen.c */,
|
||||
F35E56C02983130C00A43A5F /* testautomation_pixels.c */,
|
||||
F35E56C32983130D00A43A5F /* testautomation_platform.c */,
|
||||
A1A859482BC72FC20045DD6C /* testautomation_properties.c */,
|
||||
|
||||
+104
-49
@@ -151,8 +151,6 @@ typedef enum SDL_EventType
|
||||
in an event watcher, the window handle is still valid and can still be used to retrieve any userdata
|
||||
associated with the window. Otherwise, the handle has already been destroyed and all resources
|
||||
associated with it are invalid */
|
||||
SDL_EVENT_WINDOW_PEN_ENTER, /**< Window has gained focus of the pressure-sensitive pen with ID "data1" */
|
||||
SDL_EVENT_WINDOW_PEN_LEAVE, /**< Window has lost focus of the pressure-sensitive pen with ID "data1" */
|
||||
SDL_EVENT_WINDOW_HDR_STATE_CHANGED, /**< Window HDR properties have changed */
|
||||
SDL_EVENT_WINDOW_FIRST = SDL_EVENT_WINDOW_SHOWN,
|
||||
SDL_EVENT_WINDOW_LAST = SDL_EVENT_WINDOW_HDR_STATE_CHANGED,
|
||||
@@ -227,11 +225,14 @@ typedef enum SDL_EventType
|
||||
SDL_EVENT_SENSOR_UPDATE = 0x1200, /**< A sensor was updated */
|
||||
|
||||
/* Pressure-sensitive pen events */
|
||||
SDL_EVENT_PEN_DOWN = 0x1300, /**< Pressure-sensitive pen touched drawing surface */
|
||||
SDL_EVENT_PEN_PROXIMITY_IN = 0x1300, /**< Pressure-sensitive pen has become available */
|
||||
SDL_EVENT_PEN_PROXIMITY_OUT, /**< Pressure-sensitive pen has become unavailable */
|
||||
SDL_EVENT_PEN_DOWN, /**< Pressure-sensitive pen touched drawing surface */
|
||||
SDL_EVENT_PEN_UP, /**< Pressure-sensitive pen stopped touching drawing surface */
|
||||
SDL_EVENT_PEN_MOTION, /**< Pressure-sensitive pen moved, or angle/pressure changed */
|
||||
SDL_EVENT_PEN_BUTTON_DOWN, /**< Pressure-sensitive pen button pressed */
|
||||
SDL_EVENT_PEN_BUTTON_UP, /**< Pressure-sensitive pen button released */
|
||||
SDL_EVENT_PEN_MOTION, /**< Pressure-sensitive pen is moving on the tablet */
|
||||
SDL_EVENT_PEN_AXIS, /**< Pressure-sensitive pen angle/pressure/etc changed */
|
||||
|
||||
/* Camera hotplug events */
|
||||
SDL_EVENT_CAMERA_DEVICE_ADDED = 0x1400, /**< A new camera device is available */
|
||||
@@ -426,7 +427,7 @@ typedef struct SDL_MouseMotionEvent
|
||||
Uint32 reserved;
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with mouse focus, if any */
|
||||
SDL_MouseID which; /**< The mouse instance id, SDL_TOUCH_MOUSEID, or SDL_PEN_MOUSEID */
|
||||
SDL_MouseID which; /**< The mouse instance id or SDL_TOUCH_MOUSEID */
|
||||
SDL_MouseButtonFlags state; /**< The current button state */
|
||||
float x; /**< X coordinate, relative to window */
|
||||
float y; /**< Y coordinate, relative to window */
|
||||
@@ -445,7 +446,7 @@ typedef struct SDL_MouseButtonEvent
|
||||
Uint32 reserved;
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with mouse focus, if any */
|
||||
SDL_MouseID which; /**< The mouse instance id, SDL_TOUCH_MOUSEID, or SDL_PEN_MOUSEID */
|
||||
SDL_MouseID which; /**< The mouse instance id, SDL_TOUCH_MOUSEID */
|
||||
Uint8 button; /**< The mouse button index */
|
||||
Uint8 state; /**< SDL_PRESSED or SDL_RELEASED */
|
||||
Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */
|
||||
@@ -465,7 +466,7 @@ typedef struct SDL_MouseWheelEvent
|
||||
Uint32 reserved;
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with mouse focus, if any */
|
||||
SDL_MouseID which; /**< The mouse instance id, SDL_TOUCH_MOUSEID, or SDL_PEN_MOUSEID */
|
||||
SDL_MouseID which; /**< The mouse instance id, SDL_TOUCH_MOUSEID */
|
||||
float x; /**< The amount scrolled horizontally, positive to the right and negative to the left */
|
||||
float y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */
|
||||
SDL_MouseWheelDirection direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */
|
||||
@@ -714,67 +715,119 @@ typedef struct SDL_TouchFingerEvent
|
||||
SDL_WindowID windowID; /**< The window underneath the finger, if any */
|
||||
} SDL_TouchFingerEvent;
|
||||
|
||||
|
||||
/**
|
||||
* Pressure-sensitive pen touched or stopped touching surface (event.ptip.*)
|
||||
* Pressure-sensitive pen proximity event structure (event.pmotion.*)
|
||||
*
|
||||
* When a pen becomes visible to the system (it is close enough to a tablet,
|
||||
* etc), SDL will send an SDL_EVENT_PEN_PROXIMITY_IN event with the new
|
||||
* pen's ID. This ID is valid until the pen leaves proximity again (has
|
||||
* been removed from the tablet's area, the tablet has been unplugged, etc).
|
||||
* If the same pen reenters proximity again, it will be given a new ID.
|
||||
*
|
||||
* Note that "proximity" means "close enough for the tablet to know the tool
|
||||
* is there." The pen touching and lifting off from the tablet while not
|
||||
* leaving the area are handled by SDL_EVENT_PEN_DOWN and SDL_EVENT_PEN_UP.
|
||||
*
|
||||
* \since This struct is available since SDL 3.0.0.
|
||||
*/
|
||||
typedef struct SDL_PenTipEvent
|
||||
typedef struct SDL_PenProximityEvent
|
||||
{
|
||||
SDL_EventType type; /**< SDL_EVENT_PEN_PROXIMITY_IN or SDL_EVENT_PEN_PROXIMITY_OUT */
|
||||
Uint32 reserved;
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with mouse focus, if any */
|
||||
SDL_PenID which; /**< The pen instance id */
|
||||
} SDL_PenProximityEvent;
|
||||
|
||||
/**
|
||||
* Pressure-sensitive pen motion event structure (event.pmotion.*)
|
||||
*
|
||||
* Depending on the hardware, you may get motion events when the
|
||||
* pen is not touching a tablet, for tracking a pen even when it
|
||||
* isn't drawing. You should listen for SDL_EVENT_PEN_DOWN and
|
||||
* SDL_EVENT_PEN_UP events, or check `pen_state & SDL_PEN_INPUT_DOWN`
|
||||
* to decide if a pen is "drawing" when dealing with pen motion.
|
||||
*
|
||||
* \since This struct is available since SDL 3.0.0.
|
||||
*/
|
||||
typedef struct SDL_PenMotionEvent
|
||||
{
|
||||
SDL_EventType type; /**< SDL_EVENT_PEN_MOTION */
|
||||
Uint32 reserved;
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with mouse focus, if any */
|
||||
SDL_PenID which; /**< The pen instance id */
|
||||
SDL_PenInputFlags pen_state; /**< Complete pen input state at time of event */
|
||||
float x; /**< X position of pen on tablet */
|
||||
float y; /**< Y position of pen on tablet */
|
||||
} SDL_PenMotionEvent;
|
||||
|
||||
/**
|
||||
* Pressure-sensitive pen touched event structure (event.ptouch.*)
|
||||
*
|
||||
* These events come when a pen touches a surface (a tablet, etc),
|
||||
* or lifts off from one.
|
||||
*
|
||||
* \since This struct is available since SDL 3.0.0.
|
||||
*/
|
||||
typedef struct SDL_PenTouchEvent
|
||||
{
|
||||
SDL_EventType type; /**< SDL_EVENT_PEN_DOWN or SDL_EVENT_PEN_UP */
|
||||
Uint32 reserved;
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with pen focus, if any */
|
||||
SDL_PenID which; /**< The pen instance id */
|
||||
Uint8 tip; /**< SDL_PEN_TIP_INK when using a regular pen tip, or SDL_PEN_TIP_ERASER if the pen is being used as an eraser (e.g., flipped to use the eraser tip) */
|
||||
Uint8 state; /**< SDL_PRESSED on SDL_EVENT_PEN_DOWN and SDL_RELEASED on SDL_EVENT_PEN_UP */
|
||||
Uint16 pen_state; /**< Pen button masks (where SDL_BUTTON(1) is the first button, SDL_BUTTON(2) is the second button etc.), SDL_PEN_DOWN_MASK is set if the pen is touching the surface, and SDL_PEN_ERASER_MASK is set if the pen is (used as) an eraser. */
|
||||
float x; /**< X coordinate, relative to window */
|
||||
float y; /**< Y coordinate, relative to window */
|
||||
float axes[SDL_PEN_NUM_AXES]; /**< Pen axes such as pressure and tilt (ordered as per SDL_PenAxis) */
|
||||
} SDL_PenTipEvent;
|
||||
|
||||
/**
|
||||
* Pressure-sensitive pen motion / pressure / angle event structure
|
||||
* (event.pmotion.*)
|
||||
*
|
||||
* \since This struct is available since SDL 3.0.0.
|
||||
*/
|
||||
typedef struct SDL_PenMotionEvent
|
||||
{
|
||||
SDL_EventType type; /**< SDL_EVENT_PEN_MOTION */
|
||||
Uint32 reserved;
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with pen focus, if any */
|
||||
SDL_PenID which; /**< The pen instance id */
|
||||
Uint8 padding1;
|
||||
Uint8 padding2;
|
||||
Uint16 pen_state; /**< Pen button masks (where SDL_BUTTON(1) is the first button, SDL_BUTTON(2) is the second button etc.), SDL_PEN_DOWN_MASK is set if the pen is touching the surface, and SDL_PEN_ERASER_MASK is set if the pen is (used as) an eraser. */
|
||||
float x; /**< X coordinate, relative to window */
|
||||
float y; /**< Y coordinate, relative to window */
|
||||
float axes[SDL_PEN_NUM_AXES]; /**< Pen axes such as pressure and tilt (ordered as per SDL_PenAxis) */
|
||||
} SDL_PenMotionEvent;
|
||||
SDL_PenInputFlags pen_state; /**< Complete pen input state at time of event */
|
||||
float x; /**< X position of pen on tablet */
|
||||
float y; /**< Y position of pen on tablet */
|
||||
Uint8 eraser; /**< Non-zero if eraser end is used (not all pens support this). */
|
||||
Uint8 state; /**< SDL_PRESSED (pen is touching) or SDL_RELEASED (pen is lifted off) */
|
||||
} SDL_PenTouchEvent;
|
||||
|
||||
/**
|
||||
* Pressure-sensitive pen button event structure (event.pbutton.*)
|
||||
*
|
||||
* This is for buttons on the pen itself that the user might click.
|
||||
* The pen itself pressing down to draw triggers a SDL_EVENT_PEN_DOWN
|
||||
* event instead.
|
||||
*
|
||||
* \since This struct is available since SDL 3.0.0.
|
||||
*/
|
||||
typedef struct SDL_PenButtonEvent
|
||||
{
|
||||
SDL_EventType type; /**< SDL_EVENT_PEN_BUTTON_DOWN or SDL_EVENT_PEN_BUTTON_UP */
|
||||
SDL_EventType type; /**< SDL_EVENT_PEN_BUTTON_DOWN or SDL_EVENT_PEN_BUTTON_UP */
|
||||
Uint32 reserved;
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with mouse focus, if any */
|
||||
SDL_PenID which; /**< The pen instance id */
|
||||
SDL_PenInputFlags pen_state; /**< Complete pen input state at time of event */
|
||||
float x; /**< X position of pen on tablet */
|
||||
float y; /**< Y position of pen on tablet */
|
||||
Uint8 button; /**< The pen button index (first button is 1). */
|
||||
Uint8 state; /**< SDL_PRESSED or SDL_RELEASED */
|
||||
} SDL_PenButtonEvent;
|
||||
|
||||
/**
|
||||
* Pressure-sensitive pen pressure / angle event structure
|
||||
* (event.paxis.*)
|
||||
*
|
||||
* You might get some of these events even if the pen isn't touching the tablet.
|
||||
*
|
||||
* \since This struct is available since SDL 3.0.0.
|
||||
*/
|
||||
typedef struct SDL_PenAxisEvent
|
||||
{
|
||||
SDL_EventType type; /**< SDL_EVENT_PEN_AXIS */
|
||||
Uint32 reserved;
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with pen focus, if any */
|
||||
SDL_PenID which; /**< The pen instance id */
|
||||
Uint8 button; /**< The pen button index (1 represents the pen tip for compatibility with mouse events) */
|
||||
Uint8 state; /**< SDL_PRESSED or SDL_RELEASED */
|
||||
Uint16 pen_state; /**< Pen button masks (where SDL_BUTTON(1) is the first button, SDL_BUTTON(2) is the second button etc.), SDL_PEN_DOWN_MASK is set if the pen is touching the surface, and SDL_PEN_ERASER_MASK is set if the pen is (used as) an eraser. */
|
||||
float x; /**< X coordinate, relative to window */
|
||||
float y; /**< Y coordinate, relative to window */
|
||||
float axes[SDL_PEN_NUM_AXES]; /**< Pen axes such as pressure and tilt (ordered as per SDL_PenAxis) */
|
||||
} SDL_PenButtonEvent;
|
||||
SDL_PenInputFlags pen_state; /**< Complete pen input state at time of event */
|
||||
float x; /**< X position of pen on tablet */
|
||||
float y; /**< Y position of pen on tablet */
|
||||
SDL_PenAxis axis; /**< Axis that has changed */
|
||||
float value; /**< New value of axis */
|
||||
} SDL_PenAxisEvent;
|
||||
|
||||
/**
|
||||
* An event used to drop text or request a file open by the system
|
||||
@@ -894,9 +947,11 @@ typedef union SDL_Event
|
||||
SDL_QuitEvent quit; /**< Quit request event data */
|
||||
SDL_UserEvent user; /**< Custom event data */
|
||||
SDL_TouchFingerEvent tfinger; /**< Touch finger event data */
|
||||
SDL_PenTipEvent ptip; /**< Pen tip touching or leaving drawing surface */
|
||||
SDL_PenMotionEvent pmotion; /**< Pen change in position, pressure, or angle */
|
||||
SDL_PenButtonEvent pbutton; /**< Pen button press */
|
||||
SDL_PenProximityEvent pproximity; /**< Pen proximity event data */
|
||||
SDL_PenTouchEvent ptouch; /**< Pen tip touching event data */
|
||||
SDL_PenMotionEvent pmotion; /**< Pen motion event data */
|
||||
SDL_PenButtonEvent pbutton; /**< Pen button event data */
|
||||
SDL_PenAxisEvent paxis; /**< Pen axis event data */
|
||||
SDL_DropEvent drop; /**< Drag and drop event data */
|
||||
SDL_ClipboardEvent clipboard; /**< Clipboard event data */
|
||||
|
||||
|
||||
+47
-221
@@ -22,56 +22,65 @@
|
||||
/**
|
||||
* # CategoryPen
|
||||
*
|
||||
* Include file for SDL pen event handling.
|
||||
* SDL pen event handling.
|
||||
*
|
||||
* This file describes operations for pressure-sensitive pen (stylus and/or
|
||||
* SDL provides an API for pressure-sensitive pen (stylus and/or
|
||||
* eraser) handling, e.g., for input and drawing tablets or suitably equipped
|
||||
* mobile / tablet devices.
|
||||
*
|
||||
* To get started with pens:
|
||||
* To get started with pens, simply handle SDL_EVENT_PEN_* events. When a pen
|
||||
* starts providing input, SDL will assign it a unique SDL_PenID, which will
|
||||
* remain for the life of the process, as long as the pen stays connected.
|
||||
*
|
||||
* - Listen to SDL_PenMotionEvent and SDL_PenButtonEvent
|
||||
* - To avoid treating pen events as mouse events, ignore SDL_MouseMotionEvent
|
||||
* and SDL_MouseButtonEvent whenever `which` == SDL_PEN_MOUSEID.
|
||||
*
|
||||
* We primarily identify pens by SDL_PenID. The implementation makes a best
|
||||
* effort to relate each SDL_PenID to the same physical device during a
|
||||
* session. Formerly valid SDL_PenID values remain valid even if a device
|
||||
* disappears.
|
||||
*
|
||||
* For identifying pens across sessions, the API provides the type SDL_GUID .
|
||||
* Pens may provide more than simple touch input; they might have other axes,
|
||||
* such as pressure, tilt, rotation, etc.
|
||||
*/
|
||||
|
||||
#ifndef SDL_pen_h_
|
||||
#define SDL_pen_h_
|
||||
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_guid.h>
|
||||
#include <SDL3/SDL_mouse.h>
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef Uint32 SDL_PenID; /**< SDL_PenIDs identify pens uniquely within a session */
|
||||
/**
|
||||
* SDL pen instance IDs.
|
||||
*
|
||||
* Zero is used to signify an invalid/null device.
|
||||
*
|
||||
* These show up in pen events when SDL sees input from them. They remain
|
||||
* consistent as long as SDL can recognize a tool to be the same pen; but if
|
||||
* a pen physically leaves the area and returns, it might get a new ID.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.0.0.
|
||||
*/
|
||||
typedef Uint32 SDL_PenID;
|
||||
|
||||
#define SDL_PEN_INVALID ((SDL_PenID)0) /**< Reserved invalid SDL_PenID is valid */
|
||||
|
||||
#define SDL_PEN_MOUSEID ((SDL_MouseID)-2) /**< Device ID for mouse events triggered by pen events */
|
||||
|
||||
#define SDL_PEN_INFO_UNKNOWN (-1) /**< Marks unknown information when querying the pen */
|
||||
|
||||
/**
|
||||
* Pen axis indices
|
||||
* Pen input flags, as reported by various pen events' `pen_state` field.
|
||||
*
|
||||
* Below are the valid indices to the "axis" array from SDL_PenMotionEvent and
|
||||
* SDL_PenButtonEvent. The axis indices form a contiguous range of ints from 0
|
||||
* to SDL_PEN_AXIS_LAST, inclusive. All "axis[]" entries are either normalised
|
||||
* to 0..1 or report a (positive or negative) angle in degrees, with 0.0
|
||||
* representing the centre. Not all pens/backends support all axes:
|
||||
* unsupported entries are always "0.0f".
|
||||
* \since This datatype is available since SDL 3.0.0.
|
||||
*/
|
||||
typedef Uint32 SDL_PenInputFlags;
|
||||
#define SDL_PEN_INPUT_DOWN (1u << 0) /**< & to see if pen is pressed down */
|
||||
#define SDL_PEN_INPUT_BUTTON_1 (1u << 1) /**< & to see if button 1 is pressed */
|
||||
#define SDL_PEN_INPUT_BUTTON_2 (1u << 2) /**< & to see if button 2 is pressed */
|
||||
#define SDL_PEN_INPUT_BUTTON_3 (1u << 3) /**< & to see if button 3 is pressed */
|
||||
#define SDL_PEN_INPUT_BUTTON_4 (1u << 4) /**< & to see if button 4 is pressed */
|
||||
#define SDL_PEN_INPUT_BUTTON_5 (1u << 5) /**< & to see if button 5 is pressed */
|
||||
#define SDL_PEN_INPUT_ERASER_TIP (1u << 30) /**< & to see if eraser tip is used */
|
||||
|
||||
/**
|
||||
* Pen axis indices.
|
||||
*
|
||||
* These are the valid values for the `axis` field in SDL_PenAxisEvent.
|
||||
* All axes are either normalised to 0..1 or report a (positive or negative) angle
|
||||
* in degrees, with 0.0 representing the centre. Not all pens/backends support all
|
||||
* axes: unsupported axes are always zero.
|
||||
*
|
||||
* To convert angles for tilt and rotation into vector representation, use
|
||||
* SDL_sinf on the XTILT, YTILT, or ROTATION component, for example:
|
||||
@@ -82,200 +91,17 @@ typedef Uint32 SDL_PenID; /**< SDL_PenIDs identify pens uniquely within a sessio
|
||||
*/
|
||||
typedef enum SDL_PenAxis
|
||||
{
|
||||
SDL_PEN_AXIS_PRESSURE = 0, /**< Pen pressure. Unidirectional: 0..1.0 */
|
||||
SDL_PEN_AXIS_XTILT, /**< Pen horizontal tilt angle. Bidirectional: -90.0..90.0 (left-to-right).
|
||||
The physical max/min tilt may be smaller than -90.0 / 90.0, cf. SDL_PenCapabilityInfo */
|
||||
SDL_PEN_AXIS_YTILT, /**< Pen vertical tilt angle. Bidirectional: -90.0..90.0 (top-to-down).
|
||||
The physical max/min tilt may be smaller than -90.0 / 90.0, cf. SDL_PenCapabilityInfo */
|
||||
SDL_PEN_AXIS_DISTANCE, /**< Pen distance to drawing surface. Unidirectional: 0.0..1.0 */
|
||||
SDL_PEN_AXIS_ROTATION, /**< Pen barrel rotation. Bidirectional: -180..179.9 (clockwise, 0 is facing up, -180.0 is facing down). */
|
||||
SDL_PEN_AXIS_SLIDER, /**< Pen finger wheel or slider (e.g., Airbrush Pen). Unidirectional: 0..1.0 */
|
||||
SDL_PEN_NUM_AXES, /**< Last valid axis index */
|
||||
SDL_PEN_AXIS_LAST = SDL_PEN_NUM_AXES - 1 /**< Last axis index plus 1 */
|
||||
SDL_PEN_AXIS_PRESSURE, /**< Pen pressure. Unidirectional: 0 to 1.0 */
|
||||
SDL_PEN_AXIS_XTILT, /**< Pen horizontal tilt angle. Bidirectional: -90.0 to 90.0 (left-to-right).
|
||||
The physical max/min tilt may be smaller than -90.0 / 90.0, check SDL_PenCapabilityInfo */
|
||||
SDL_PEN_AXIS_YTILT, /**< Pen vertical tilt angle. Bidirectional: -90.0 to 90.0 (top-to-down).
|
||||
The physical max/min tilt may be smaller than -90.0 / 90.0 check SDL_PenCapabilityInfo */
|
||||
SDL_PEN_AXIS_DISTANCE, /**< Pen distance to drawing surface. Unidirectional: 0.0 to 1.0 */
|
||||
SDL_PEN_AXIS_ROTATION, /**< Pen barrel rotation. Bidirectional: -180 to 179.9 (clockwise, 0 is facing up, -180.0 is facing down). */
|
||||
SDL_PEN_AXIS_SLIDER, /**< Pen finger wheel or slider (e.g., Airbrush Pen). Unidirectional: 0 to 1.0 */
|
||||
SDL_PEN_NUM_AXES /**< Total known pen axis types in this version of SDL. This number may grow in future releases! */
|
||||
} SDL_PenAxis;
|
||||
|
||||
/* Pen flags. These share a bitmask space with SDL_BUTTON_LEFT and friends. */
|
||||
#define SDL_PEN_FLAG_DOWN_BIT_INDEX 13 /* Bit for storing that pen is touching the surface */
|
||||
#define SDL_PEN_FLAG_INK_BIT_INDEX 14 /* Bit for storing has-non-eraser-capability status */
|
||||
#define SDL_PEN_FLAG_ERASER_BIT_INDEX 15 /* Bit for storing is-eraser or has-eraser-capability property */
|
||||
#define SDL_PEN_FLAG_AXIS_BIT_OFFSET 16 /* Bit for storing has-axis-0 property */
|
||||
|
||||
#define SDL_PEN_CAPABILITY(capbit) (1ul << (capbit))
|
||||
#define SDL_PEN_AXIS_CAPABILITY(axis) SDL_PEN_CAPABILITY((axis) + SDL_PEN_FLAG_AXIS_BIT_OFFSET)
|
||||
|
||||
/* Pen tips */
|
||||
#define SDL_PEN_TIP_INK SDL_PEN_FLAG_INK_BIT_INDEX /**< Regular pen tip (for drawing) touched the surface */
|
||||
#define SDL_PEN_TIP_ERASER SDL_PEN_FLAG_ERASER_BIT_INDEX /**< Eraser pen tip touched the surface */
|
||||
|
||||
/**
|
||||
* Pen capabilities reported by SDL_GetPenCapabilities.
|
||||
*
|
||||
* \since This datatype is available since SDL 3.0.0.
|
||||
*/
|
||||
typedef Uint32 SDL_PenCapabilityFlags;
|
||||
|
||||
#define SDL_PEN_DOWN_MASK SDL_PEN_CAPABILITY(SDL_PEN_FLAG_DOWN_BIT_INDEX) /**< Pen tip is currently touching the drawing surface. */
|
||||
#define SDL_PEN_INK_MASK SDL_PEN_CAPABILITY(SDL_PEN_FLAG_INK_BIT_INDEX) /**< Pen has a regular drawing tip (SDL_GetPenCapabilities). For events (SDL_PenButtonEvent, SDL_PenMotionEvent, SDL_GetPenStatus) this flag is mutually exclusive with SDL_PEN_ERASER_MASK . */
|
||||
#define SDL_PEN_ERASER_MASK SDL_PEN_CAPABILITY(SDL_PEN_FLAG_ERASER_BIT_INDEX) /**< Pen has an eraser tip (SDL_GetPenCapabilities) or is being used as eraser (SDL_PenButtonEvent , SDL_PenMotionEvent , SDL_GetPenStatus) */
|
||||
#define SDL_PEN_AXIS_PRESSURE_MASK SDL_PEN_AXIS_CAPABILITY(SDL_PEN_AXIS_PRESSURE) /**< Pen provides pressure information in axis SDL_PEN_AXIS_PRESSURE */
|
||||
#define SDL_PEN_AXIS_XTILT_MASK SDL_PEN_AXIS_CAPABILITY(SDL_PEN_AXIS_XTILT) /**< Pen provides horizontal tilt information in axis SDL_PEN_AXIS_XTILT */
|
||||
#define SDL_PEN_AXIS_YTILT_MASK SDL_PEN_AXIS_CAPABILITY(SDL_PEN_AXIS_YTILT) /**< Pen provides vertical tilt information in axis SDL_PEN_AXIS_YTILT */
|
||||
#define SDL_PEN_AXIS_DISTANCE_MASK SDL_PEN_AXIS_CAPABILITY(SDL_PEN_AXIS_DISTANCE) /**< Pen provides distance to drawing tablet in SDL_PEN_AXIS_DISTANCE */
|
||||
#define SDL_PEN_AXIS_ROTATION_MASK SDL_PEN_AXIS_CAPABILITY(SDL_PEN_AXIS_ROTATION) /**< Pen provides barrel rotation information in axis SDL_PEN_AXIS_ROTATION */
|
||||
#define SDL_PEN_AXIS_SLIDER_MASK SDL_PEN_AXIS_CAPABILITY(SDL_PEN_AXIS_SLIDER) /**< Pen provides slider / finger wheel or similar in axis SDL_PEN_AXIS_SLIDER */
|
||||
#define SDL_PEN_AXIS_BIDIRECTIONAL_MASKS (SDL_PEN_AXIS_XTILT_MASK | SDL_PEN_AXIS_YTILT_MASK)
|
||||
|
||||
/**
|
||||
* Pen types
|
||||
*
|
||||
* Some pens identify as a particular type of drawing device (e.g., an
|
||||
* airbrush or a pencil).
|
||||
*
|
||||
* \since This enum is available since SDL 3.0.0
|
||||
*/
|
||||
typedef enum SDL_PenSubtype
|
||||
{
|
||||
SDL_PEN_TYPE_UNKNOWN = 0,
|
||||
SDL_PEN_TYPE_ERASER = 1, /**< Eraser */
|
||||
SDL_PEN_TYPE_PEN, /**< Generic pen; this is the default. */
|
||||
SDL_PEN_TYPE_PENCIL, /**< Pencil */
|
||||
SDL_PEN_TYPE_BRUSH, /**< Brush-like device */
|
||||
SDL_PEN_TYPE_AIRBRUSH, /**< Airbrush device that "sprays" ink */
|
||||
SDL_PEN_TYPE_LAST = SDL_PEN_TYPE_AIRBRUSH /**< Last valid pen type */
|
||||
} SDL_PenSubtype;
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
/**
|
||||
* Retrieves all pens that are connected to the system.
|
||||
*
|
||||
* Yields an array of SDL_PenID values. These identify and track pens
|
||||
* throughout a session. To track pens across sessions (program restart), use
|
||||
* SDL_GUID .
|
||||
*
|
||||
* \param count the number of pens in the array (number of array elements
|
||||
* minus 1, i.e., not counting the terminator 0).
|
||||
* \returns a 0 terminated array of SDL_PenID values, or NULL on failure. The
|
||||
* array must be freed with SDL_free(). On a NULL return,
|
||||
* SDL_GetError() is set.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_PenID * SDLCALL SDL_GetPens(int *count);
|
||||
|
||||
/**
|
||||
* Retrieves the pen's current status.
|
||||
*
|
||||
* If the pen is detached (cf. SDL_PenConnected), this operation may return
|
||||
* default values.
|
||||
*
|
||||
* \param instance_id the pen to query.
|
||||
* \param x out-mode parameter for pen x coordinate. May be NULL.
|
||||
* \param y out-mode parameter for pen y coordinate. May be NULL.
|
||||
* \param axes out-mode parameter for axis information. May be null. The axes
|
||||
* are in the same order as SDL_PenAxis.
|
||||
* \param num_axes maximum number of axes to write to "axes".
|
||||
* \returns a bit mask with the current pen button states (SDL_BUTTON_LMASK
|
||||
* etc.), possibly SDL_PEN_DOWN_MASK, and exactly one of
|
||||
* SDL_PEN_INK_MASK or SDL_PEN_ERASER_MASK , or 0 on error (see
|
||||
* SDL_GetError()).
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC Uint32 SDLCALL SDL_GetPenStatus(SDL_PenID instance_id, float *x, float *y, float *axes, size_t num_axes);
|
||||
|
||||
/**
|
||||
* Retrieves an SDL_PenID for the given SDL_GUID.
|
||||
*
|
||||
* \param guid a pen GUID.
|
||||
* \returns a valid SDL_PenID, or SDL_PEN_INVALID if there is no matching
|
||||
* SDL_PenID.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_PenID SDLCALL SDL_GetPenFromGUID(SDL_GUID guid);
|
||||
|
||||
/**
|
||||
* Retrieves the SDL_GUID for a given SDL_PenID.
|
||||
*
|
||||
* \param instance_id the pen to query.
|
||||
* \returns the corresponding pen GUID; persistent across multiple sessions.
|
||||
* If "instance_id" is SDL_PEN_INVALID, returns an all-zeroes GUID.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_GUID SDLCALL SDL_GetPenGUID(SDL_PenID instance_id);
|
||||
|
||||
/**
|
||||
* Checks whether a pen is still attached.
|
||||
*
|
||||
* If a pen is detached, it will not show up for SDL_GetPens(). Other
|
||||
* operations will still be available but may return default values.
|
||||
*
|
||||
* \param instance_id a pen ID.
|
||||
* \returns SDL_TRUE if "instance_id" is valid and the corresponding pen is
|
||||
* attached, or SDL_FALSE otherwise.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_bool SDLCALL SDL_PenConnected(SDL_PenID instance_id);
|
||||
|
||||
/**
|
||||
* Retrieves a human-readable description for a SDL_PenID.
|
||||
*
|
||||
* \param instance_id the pen to query.
|
||||
* \returns a string that contains the name of the pen, intended for human
|
||||
* consumption. The string might or might not be localised, depending
|
||||
* on platform settings. It is not guaranteed to be unique; use
|
||||
* SDL_GetPenGUID() for (best-effort) unique identifiers. The pointer
|
||||
* is managed by the SDL pen subsystem and must not be deallocated.
|
||||
* The pointer remains valid until SDL is shut down. Returns NULL on
|
||||
* error (cf. SDL_GetError()).
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC const char * SDLCALL SDL_GetPenName(SDL_PenID instance_id);
|
||||
|
||||
/**
|
||||
* Pen capabilities, as reported by SDL_GetPenCapabilities()
|
||||
*
|
||||
* \since This struct is available since SDL 3.0.0.
|
||||
*/
|
||||
typedef struct SDL_PenCapabilityInfo
|
||||
{
|
||||
float max_tilt; /**< Physical maximum tilt angle, for XTILT and YTILT, or SDL_PEN_INFO_UNKNOWN . Pens cannot typically tilt all the way to 90 degrees, so this value is usually less than 90.0. */
|
||||
Uint32 wacom_id; /**< For Wacom devices: wacom tool type ID, otherwise 0 (useful e.g. with libwacom) */
|
||||
Sint8 num_buttons; /**< Number of pen buttons (not counting the pen tip), or SDL_PEN_INFO_UNKNOWN */
|
||||
} SDL_PenCapabilityInfo;
|
||||
|
||||
/**
|
||||
* Retrieves capability flags for a given SDL_PenID.
|
||||
*
|
||||
* \param instance_id the pen to query.
|
||||
* \param capabilities detail information about pen capabilities, such as the
|
||||
* number of buttons.
|
||||
* \returns a set of capability flags, cf. SDL_PEN_CAPABILITIES.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_PenCapabilityFlags SDLCALL SDL_GetPenCapabilities(SDL_PenID instance_id, SDL_PenCapabilityInfo *capabilities);
|
||||
|
||||
/**
|
||||
* Retrieves the pen type for a given SDL_PenID.
|
||||
*
|
||||
* \param instance_id the pen to query.
|
||||
* \returns the corresponding pen type (cf. SDL_PenSubtype) or 0 on error.
|
||||
* Note that the pen type does not dictate whether the pen tip is
|
||||
* SDL_PEN_TIP_INK or SDL_PEN_TIP_ERASER; to determine whether a pen
|
||||
* is being used for drawing or in eraser mode, check either the pen
|
||||
* tip on SDL_EVENT_PEN_DOWN, or the flag SDL_PEN_ERASER_MASK in the
|
||||
* pen state.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_PenSubtype SDLCALL SDL_GetPenType(SDL_PenID instance_id);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -355,13 +355,6 @@ SDL3_0.0.0 {
|
||||
SDL_GetNumberProperty;
|
||||
SDL_GetOriginalMemoryFunctions;
|
||||
SDL_GetPathInfo;
|
||||
SDL_GetPenCapabilities;
|
||||
SDL_GetPenFromGUID;
|
||||
SDL_GetPenGUID;
|
||||
SDL_GetPenName;
|
||||
SDL_GetPenStatus;
|
||||
SDL_GetPenType;
|
||||
SDL_GetPens;
|
||||
SDL_GetPerformanceCounter;
|
||||
SDL_GetPerformanceFrequency;
|
||||
SDL_GetPixelFormatDetails;
|
||||
@@ -611,7 +604,6 @@ SDL3_0.0.0 {
|
||||
SDL_PauseAudioStreamDevice;
|
||||
SDL_PauseHaptic;
|
||||
SDL_PeepEvents;
|
||||
SDL_PenConnected;
|
||||
SDL_PlayHapticRumble;
|
||||
SDL_PollEvent;
|
||||
SDL_PremultiplyAlpha;
|
||||
|
||||
@@ -380,13 +380,6 @@
|
||||
#define SDL_GetNumberProperty SDL_GetNumberProperty_REAL
|
||||
#define SDL_GetOriginalMemoryFunctions SDL_GetOriginalMemoryFunctions_REAL
|
||||
#define SDL_GetPathInfo SDL_GetPathInfo_REAL
|
||||
#define SDL_GetPenCapabilities SDL_GetPenCapabilities_REAL
|
||||
#define SDL_GetPenFromGUID SDL_GetPenFromGUID_REAL
|
||||
#define SDL_GetPenGUID SDL_GetPenGUID_REAL
|
||||
#define SDL_GetPenName SDL_GetPenName_REAL
|
||||
#define SDL_GetPenStatus SDL_GetPenStatus_REAL
|
||||
#define SDL_GetPenType SDL_GetPenType_REAL
|
||||
#define SDL_GetPens SDL_GetPens_REAL
|
||||
#define SDL_GetPerformanceCounter SDL_GetPerformanceCounter_REAL
|
||||
#define SDL_GetPerformanceFrequency SDL_GetPerformanceFrequency_REAL
|
||||
#define SDL_GetPixelFormatDetails SDL_GetPixelFormatDetails_REAL
|
||||
@@ -636,7 +629,6 @@
|
||||
#define SDL_PauseAudioStreamDevice SDL_PauseAudioStreamDevice_REAL
|
||||
#define SDL_PauseHaptic SDL_PauseHaptic_REAL
|
||||
#define SDL_PeepEvents SDL_PeepEvents_REAL
|
||||
#define SDL_PenConnected SDL_PenConnected_REAL
|
||||
#define SDL_PlayHapticRumble SDL_PlayHapticRumble_REAL
|
||||
#define SDL_PollEvent SDL_PollEvent_REAL
|
||||
#define SDL_PremultiplyAlpha SDL_PremultiplyAlpha_REAL
|
||||
|
||||
@@ -400,13 +400,6 @@ SDL_DYNAPI_PROC(int,SDL_GetNumVideoDrivers,(void),(),return)
|
||||
SDL_DYNAPI_PROC(Sint64,SDL_GetNumberProperty,(SDL_PropertiesID a, const char *b, Sint64 c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_GetOriginalMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetPathInfo,(const char *a, SDL_PathInfo *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_PenCapabilityFlags,SDL_GetPenCapabilities,(SDL_PenID a, SDL_PenCapabilityInfo *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_PenID,SDL_GetPenFromGUID,(SDL_GUID a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_GUID,SDL_GetPenGUID,(SDL_PenID a),(a),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_GetPenName,(SDL_PenID a),(a),return)
|
||||
SDL_DYNAPI_PROC(Uint32,SDL_GetPenStatus,(SDL_PenID a, float *b, float *c, float *d, size_t e),(a,b,c,d,e),return)
|
||||
SDL_DYNAPI_PROC(SDL_PenSubtype,SDL_GetPenType,(SDL_PenID a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_PenID*,SDL_GetPens,(int *a),(a),return)
|
||||
SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceCounter,(void),(),return)
|
||||
SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceFrequency,(void),(),return)
|
||||
SDL_DYNAPI_PROC(const SDL_PixelFormatDetails*,SDL_GetPixelFormatDetails,(SDL_PixelFormat a),(a),return)
|
||||
@@ -647,7 +640,6 @@ SDL_DYNAPI_PROC(int,SDL_PauseAudioDevice,(SDL_AudioDeviceID a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_PauseAudioStreamDevice,(SDL_AudioStream *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_PauseHaptic,(SDL_Haptic *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_PeepEvents,(SDL_Event *a, int b, SDL_EventAction c, Uint32 d, Uint32 e),(a,b,c,d,e),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_PenConnected,(SDL_PenID a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_PlayHapticRumble,(SDL_Haptic *a, float b, Uint32 c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_PollEvent,(SDL_Event *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_PremultiplyAlpha,(int a, int b, SDL_PixelFormat c, const void *d, int e, SDL_PixelFormat f, void *g, int h, SDL_bool i),(a,b,c,d,e,f,g,h,i),return)
|
||||
|
||||
@@ -153,17 +153,24 @@ SDL_EventCategory SDL_GetEventCategory(Uint32 type)
|
||||
case SDL_EVENT_SENSOR_UPDATE:
|
||||
return SDL_EVENTCATEGORY_SENSOR;
|
||||
|
||||
case SDL_EVENT_PEN_PROXIMITY_IN:
|
||||
case SDL_EVENT_PEN_PROXIMITY_OUT:
|
||||
return SDL_EVENTCATEGORY_PPROXIMITY;
|
||||
|
||||
case SDL_EVENT_PEN_DOWN:
|
||||
case SDL_EVENT_PEN_UP:
|
||||
return SDL_EVENTCATEGORY_PTIP;
|
||||
|
||||
case SDL_EVENT_PEN_MOTION:
|
||||
return SDL_EVENTCATEGORY_PMOTION;
|
||||
return SDL_EVENTCATEGORY_PTOUCH;
|
||||
|
||||
case SDL_EVENT_PEN_BUTTON_DOWN:
|
||||
case SDL_EVENT_PEN_BUTTON_UP:
|
||||
return SDL_EVENTCATEGORY_PBUTTON;
|
||||
|
||||
case SDL_EVENT_PEN_MOTION:
|
||||
return SDL_EVENTCATEGORY_PMOTION;
|
||||
|
||||
case SDL_EVENT_PEN_AXIS:
|
||||
return SDL_EVENTCATEGORY_PAXIS;
|
||||
|
||||
case SDL_EVENT_CAMERA_DEVICE_ADDED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_REMOVED:
|
||||
case SDL_EVENT_CAMERA_DEVICE_APPROVED:
|
||||
@@ -207,14 +214,20 @@ SDL_Window *SDL_GetWindowFromEvent(const SDL_Event *event)
|
||||
case SDL_EVENTCATEGORY_TFINGER:
|
||||
windowID = event->tfinger.windowID;
|
||||
break;
|
||||
case SDL_EVENTCATEGORY_PTIP:
|
||||
windowID = event->ptip.windowID;
|
||||
case SDL_EVENTCATEGORY_PPROXIMITY:
|
||||
windowID = event->pproximity.windowID;
|
||||
break;
|
||||
case SDL_EVENTCATEGORY_PTOUCH:
|
||||
windowID = event->ptouch.windowID;
|
||||
break;
|
||||
case SDL_EVENTCATEGORY_PBUTTON:
|
||||
windowID = event->pbutton.windowID;
|
||||
break;
|
||||
case SDL_EVENTCATEGORY_PMOTION:
|
||||
windowID = event->pmotion.windowID;
|
||||
break;
|
||||
case SDL_EVENTCATEGORY_PBUTTON:
|
||||
windowID = event->pbutton.windowID;
|
||||
case SDL_EVENTCATEGORY_PAXIS:
|
||||
windowID = event->paxis.windowID;
|
||||
break;
|
||||
case SDL_EVENTCATEGORY_DROP:
|
||||
windowID = event->drop.windowID;
|
||||
|
||||
@@ -54,9 +54,11 @@ typedef enum SDL_EventCategory
|
||||
SDL_EVENTCATEGORY_QUIT,
|
||||
SDL_EVENTCATEGORY_USER,
|
||||
SDL_EVENTCATEGORY_TFINGER,
|
||||
SDL_EVENTCATEGORY_PTIP,
|
||||
SDL_EVENTCATEGORY_PPROXIMITY,
|
||||
SDL_EVENTCATEGORY_PTOUCH,
|
||||
SDL_EVENTCATEGORY_PMOTION,
|
||||
SDL_EVENTCATEGORY_PBUTTON,
|
||||
SDL_EVENTCATEGORY_PAXIS,
|
||||
SDL_EVENTCATEGORY_DROP,
|
||||
SDL_EVENTCATEGORY_CLIPBOARD,
|
||||
} SDL_EventCategory;
|
||||
|
||||
+33
-32
@@ -378,6 +378,9 @@ static void SDLCALL SDL_EventLoggingChanged(void *userdata, const char *name, co
|
||||
|
||||
static void SDL_LogEvent(const SDL_Event *event)
|
||||
{
|
||||
static const char *pen_axisnames[] = { "PRESSURE", "XTILT", "YTILT", "DISTANCE", "ROTATION", "SLIDER" };
|
||||
SDL_COMPILE_TIME_ASSERT(pen_axisnames_array_matches, SDL_arraysize(pen_axisnames) == SDL_PEN_NUM_AXES);
|
||||
|
||||
char name[64];
|
||||
char details[128];
|
||||
|
||||
@@ -385,6 +388,7 @@ static void SDL_LogEvent(const SDL_Event *event)
|
||||
if ((SDL_EventLoggingVerbosity < 2) &&
|
||||
((event->type == SDL_EVENT_MOUSE_MOTION) ||
|
||||
(event->type == SDL_EVENT_FINGER_MOTION) ||
|
||||
(event->type == SDL_EVENT_PEN_AXIS) ||
|
||||
(event->type == SDL_EVENT_PEN_MOTION) ||
|
||||
(event->type == SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION) ||
|
||||
(event->type == SDL_EVENT_GAMEPAD_SENSOR_UPDATE) ||
|
||||
@@ -482,8 +486,6 @@ static void SDL_LogEvent(const SDL_Event *event)
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_RESTORED);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_MOUSE_ENTER);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_MOUSE_LEAVE);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_PEN_ENTER);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_PEN_LEAVE);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_FOCUS_GAINED);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_FOCUS_LOST);
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_CLOSE_REQUESTED);
|
||||
@@ -699,45 +701,44 @@ static void SDL_LogEvent(const SDL_Event *event)
|
||||
break;
|
||||
#undef PRINT_FINGER_EVENT
|
||||
|
||||
#define PRINT_PTIP_EVENT(event) \
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u tip=%u state=%s x=%g y=%g)", \
|
||||
(uint)event->ptip.timestamp, (uint)event->ptip.windowID, \
|
||||
(uint)event->ptip.which, (uint)event->ptip.tip, \
|
||||
event->ptip.state == SDL_PRESSED ? "down" : "up", \
|
||||
event->ptip.x, event->ptip.y)
|
||||
#define PRINT_PTOUCH_EVENT(event) \
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u pen_state=%u x=%g y=%g eraser=%s state=%s)", \
|
||||
(uint)event->ptouch.timestamp, (uint)event->ptouch.windowID, (uint)event->ptouch.which, (uint)event->ptouch.pen_state, event->ptouch.x, event->ptouch.y, \
|
||||
event->ptouch.eraser ? "yes" : "no", event->ptouch.state == SDL_PRESSED ? "down" : "up");
|
||||
SDL_EVENT_CASE(SDL_EVENT_PEN_DOWN)
|
||||
PRINT_PTIP_EVENT(event);
|
||||
PRINT_PTOUCH_EVENT(event);
|
||||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_PEN_UP)
|
||||
PRINT_PTIP_EVENT(event);
|
||||
PRINT_PTOUCH_EVENT(event);
|
||||
break;
|
||||
#undef PRINT_PTOUCH_EVENT
|
||||
|
||||
#define PRINT_PPROXIMITY_EVENT(event) \
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u)", \
|
||||
(uint)event->pproximity.timestamp, (uint)event->pproximity.windowID, (uint)event->pproximity.which);
|
||||
SDL_EVENT_CASE(SDL_EVENT_PEN_PROXIMITY_IN)
|
||||
PRINT_PPROXIMITY_EVENT(event);
|
||||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_PEN_PROXIMITY_OUT)
|
||||
PRINT_PPROXIMITY_EVENT(event);
|
||||
break;
|
||||
#undef PRINT_PPROXIMITY_EVENT
|
||||
|
||||
SDL_EVENT_CASE(SDL_EVENT_PEN_AXIS)
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u pen_state=%u x=%g y=%g axis=%s value=%g)",
|
||||
(uint)event->paxis.timestamp, (uint)event->paxis.windowID, (uint)event->paxis.which, (uint)event->paxis.pen_state, event->paxis.x, event->paxis.y,
|
||||
((event->paxis.axis >= 0) && (event->paxis.axis < SDL_arraysize(pen_axisnames))) ? pen_axisnames[event->paxis.axis] : "[UNKNOWN]", event->paxis.value);
|
||||
break;
|
||||
#undef PRINT_PTIP_EVENT
|
||||
|
||||
SDL_EVENT_CASE(SDL_EVENT_PEN_MOTION)
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u state=%08x x=%g y=%g [%g, %g, %g, %g, %g, %g])",
|
||||
(uint)event->pmotion.timestamp, (uint)event->pmotion.windowID,
|
||||
(uint)event->pmotion.which, (uint)event->pmotion.pen_state,
|
||||
event->pmotion.x, event->pmotion.y,
|
||||
event->pmotion.axes[SDL_PEN_AXIS_PRESSURE],
|
||||
event->pmotion.axes[SDL_PEN_AXIS_XTILT],
|
||||
event->pmotion.axes[SDL_PEN_AXIS_YTILT],
|
||||
event->pmotion.axes[SDL_PEN_AXIS_DISTANCE],
|
||||
event->pmotion.axes[SDL_PEN_AXIS_ROTATION],
|
||||
event->pmotion.axes[SDL_PEN_AXIS_SLIDER]);
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u pen_state=%u x=%g y=%g)",
|
||||
(uint)event->pmotion.timestamp, (uint)event->pmotion.windowID, (uint)event->pmotion.which, (uint)event->pmotion.pen_state, event->pmotion.x, event->pmotion.y);
|
||||
break;
|
||||
|
||||
#define PRINT_PBUTTON_EVENT(event) \
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u tip=%u state=%s x=%g y=%g axes=[%g, %g, %g, %g, %g, %g])", \
|
||||
(uint)event->pbutton.timestamp, (uint)event->pbutton.windowID, \
|
||||
(uint)event->pbutton.which, (uint)event->pbutton.button, \
|
||||
event->pbutton.state == SDL_PRESSED ? "pressed" : "released", \
|
||||
event->pbutton.x, event->pbutton.y, \
|
||||
event->pbutton.axes[SDL_PEN_AXIS_PRESSURE], \
|
||||
event->pbutton.axes[SDL_PEN_AXIS_XTILT], \
|
||||
event->pbutton.axes[SDL_PEN_AXIS_YTILT], \
|
||||
event->pbutton.axes[SDL_PEN_AXIS_DISTANCE], \
|
||||
event->pbutton.axes[SDL_PEN_AXIS_ROTATION], \
|
||||
event->pbutton.axes[SDL_PEN_AXIS_SLIDER])
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u pen_state=%u x=%g y=%g button=%u state=%s)", \
|
||||
(uint)event->pbutton.timestamp, (uint)event->pbutton.windowID, (uint)event->pbutton.which, (uint)event->pbutton.pen_state, event->pbutton.x, event->pbutton.y, \
|
||||
(uint)event->pbutton.button, event->pbutton.state == SDL_PRESSED ? "down" : "up");
|
||||
SDL_EVENT_CASE(SDL_EVENT_PEN_BUTTON_DOWN)
|
||||
PRINT_PBUTTON_EVENT(event);
|
||||
break;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "SDL_keyboard_c.h"
|
||||
#include "SDL_mouse_c.h"
|
||||
#include "SDL_touch_c.h"
|
||||
#include "SDL_pen_c.h"
|
||||
#include "SDL_windowevents_c.h"
|
||||
|
||||
/* Start and stop the event processing loop */
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "../video/SDL_sysvideo.h"
|
||||
#include "SDL_events_c.h"
|
||||
#include "SDL_mouse_c.h"
|
||||
#include "SDL_pen_c.h"
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
|
||||
#include "../core/windows/SDL_windows.h" // For GetDoubleClickTime()
|
||||
#endif
|
||||
@@ -254,6 +253,7 @@ int SDL_PreInitMouse(void)
|
||||
mouse->was_touch_mouse_events = SDL_FALSE; /* no touch to mouse movement event pending */
|
||||
|
||||
mouse->cursor_shown = SDL_TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -272,8 +272,6 @@ void SDL_PostInitMouse(void)
|
||||
SDL_DestroySurface(surface);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_PenInit();
|
||||
}
|
||||
|
||||
SDL_bool SDL_IsMouse(Uint16 vendor, Uint16 product)
|
||||
@@ -741,7 +739,7 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
|
||||
float xrel = 0.0f;
|
||||
float yrel = 0.0f;
|
||||
|
||||
if ((!mouse->relative_mode || mouse->warp_emulation_active) && mouseID != SDL_TOUCH_MOUSEID && mouseID != SDL_PEN_MOUSEID) {
|
||||
if ((!mouse->relative_mode || mouse->warp_emulation_active) && mouseID != SDL_TOUCH_MOUSEID) {
|
||||
/* We're not in relative mode, so all mouse events are global mouse events */
|
||||
mouseID = SDL_GLOBAL_MOUSE_ID;
|
||||
}
|
||||
@@ -935,7 +933,7 @@ static int SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_
|
||||
Uint32 buttonstate;
|
||||
SDL_MouseInputSource *source;
|
||||
|
||||
if (!mouse->relative_mode && mouseID != SDL_TOUCH_MOUSEID && mouseID != SDL_PEN_MOUSEID) {
|
||||
if (!mouse->relative_mode && mouseID != SDL_TOUCH_MOUSEID) {
|
||||
/* We're not in relative mode, so all mouse events are global mouse events */
|
||||
mouseID = SDL_GLOBAL_MOUSE_ID;
|
||||
}
|
||||
@@ -1101,7 +1099,6 @@ void SDL_QuitMouse(void)
|
||||
}
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
SDL_ShowCursor();
|
||||
SDL_PenQuit();
|
||||
|
||||
if (mouse->def_cursor) {
|
||||
SDL_SetDefaultCursor(NULL);
|
||||
|
||||
+404
-1008
File diff suppressed because it is too large
Load Diff
+49
-294
@@ -27,316 +27,71 @@
|
||||
#include "../../include/SDL3/SDL_pen.h"
|
||||
#include "SDL_mouse_c.h"
|
||||
|
||||
/* For testing alternate code paths: */
|
||||
#define SDL_PEN_DEBUG_NOID 0 /* Pretend that pen device does not supply ID / ID is some default value \
|
||||
affects: SDL_x11pen.c \
|
||||
SDL_waylandevents.c */
|
||||
#define SDL_PEN_DEBUG_NONWACOM 0 /* Pretend that no attached device is a Wacom device \
|
||||
affects: SDL_x11pen.c \
|
||||
SDL_waylandevents.c */
|
||||
#define SDL_PEN_DEBUG_UNKNOWN_WACOM 0 /* Pretend that any attached Wacom device is of an unknown make \
|
||||
affects: SDL_PenModifyFromWacomID() */
|
||||
#define SDL_PEN_DEBUG_NOSERIAL_WACOM 0 /* Pretend that any attached Wacom device has serial number 0 \
|
||||
affects: SDL_x11pen.c \
|
||||
SDL_waylandevents.c */
|
||||
typedef Uint32 SDL_PenCapabilityFlags;
|
||||
#define SDL_PEN_CAPABILITY_PRESSURE (1u << 0) /**< Provides pressure information on SDL_PEN_AXIS_PRESSURE. */
|
||||
#define SDL_PEN_CAPABILITY_XTILT (1u << 1) /**< Provides horizontal tilt information on SDL_PEN_AXIS_XTILT. */
|
||||
#define SDL_PEN_CAPABILITY_YTILT (1u << 2) /**< Provides vertical tilt information on SDL_PEN_AXIS_YTILT. */
|
||||
#define SDL_PEN_CAPABILITY_DISTANCE (1u << 3) /**< Provides distance to drawing tablet on SDL_PEN_AXIS_DISTANCE. */
|
||||
#define SDL_PEN_CAPABILITY_ROTATION (1u << 4) /**< Provides barrel rotation info on SDL_PEN_AXIS_ROTATION. */
|
||||
#define SDL_PEN_CAPABILITY_SLIDER (1u << 5) /**< Provides slider/finger wheel/etc on SDL_PEN_AXIS_SLIDER. */
|
||||
#define SDL_PEN_CAPABILITY_ERASER (1u << 6) /**< Pen also has an eraser tip. */
|
||||
|
||||
#define SDL_PEN_TYPE_NONE 0 /**< Pen type for non-pens (use to cancel pen registration) */
|
||||
|
||||
#define SDL_PEN_MAX_NAME 64
|
||||
|
||||
#define SDL_PEN_FLAG_ERROR (1ul << 28) /* Printed an internal API usage error about this pen (used to prevent spamming) */
|
||||
#define SDL_PEN_FLAG_NEW (1ul << 29) /* Pen was registered in most recent call to SDL_PenRegisterBegin() */
|
||||
#define SDL_PEN_FLAG_DETACHED (1ul << 30) /* Detached (not re-registered before last SDL_PenGCSweep()) */
|
||||
#define SDL_PEN_FLAG_STALE (1ul << 31) /* Not re-registered since last SDL_PenGCMark() */
|
||||
|
||||
typedef struct SDL_PenStatusInfo
|
||||
typedef enum SDL_PenSubtype
|
||||
{
|
||||
float x, y;
|
||||
float axes[SDL_PEN_NUM_AXES];
|
||||
Uint16 buttons; /* SDL_BUTTON(1) | SDL_BUTTON(2) | ... | SDL_PEN_DOWN_MASK */
|
||||
} SDL_PenStatusInfo;
|
||||
SDL_PEN_TYPE_UNKNOWN, /**< Unknown pen device */
|
||||
SDL_PEN_TYPE_ERASER, /**< Eraser */
|
||||
SDL_PEN_TYPE_PEN, /**< Generic pen; this is the default. */
|
||||
SDL_PEN_TYPE_PENCIL, /**< Pencil */
|
||||
SDL_PEN_TYPE_BRUSH, /**< Brush-like device */
|
||||
SDL_PEN_TYPE_AIRBRUSH /**< Airbrush device that "sprays" ink */
|
||||
} SDL_PenSubtype;
|
||||
|
||||
typedef struct
|
||||
typedef struct SDL_PenInfo
|
||||
{
|
||||
SDL_PenID id; /* id determines sort order unless SDL_PEN_FLAG_DETACHED is set */
|
||||
Uint32 flags; /* SDL_PEN_FLAG_* | SDK_PEN_DOWN_MASK | SDL_PEN_INK_MASK | SDL_PEN_ERASER_MASK | SDL_PEN_AXIS_* */
|
||||
SDL_Window *window; /* Current SDL window for this pen, or NULL */
|
||||
} SDL_PenHeader;
|
||||
SDL_PenCapabilityFlags capabilities; /**< bitflags of device capabilities */
|
||||
float max_tilt; /**< Physical maximum tilt angle, for XTILT and YTILT, or -1.0f if unknown. Pens cannot typically tilt all the way to 90 degrees, so this value is usually less than 90.0. */
|
||||
Uint32 wacom_id; /**< For Wacom devices: wacom tool type ID, otherwise 0 (useful e.g. with libwacom) */
|
||||
int num_buttons; /**< Number of pen buttons (not counting the pen tip), or -1 if unknown. */
|
||||
SDL_PenSubtype subtype; /**< type of pen device */
|
||||
} SDL_PenInfo;
|
||||
|
||||
/**
|
||||
* Internal (backend driver-independent) pen representation
|
||||
*
|
||||
* Implementation-specific backend drivers may read and write most of this structure, and
|
||||
* are expected to initialise parts of it when registering a new pen. They must not write
|
||||
* to the "header" section.
|
||||
*/
|
||||
typedef struct SDL_Pen
|
||||
{
|
||||
/* Backend driver MUST NOT not write to: */
|
||||
SDL_PenHeader header;
|
||||
// Backend calls this when a new pen device is hotplugged, plus once for each pen already connected at startup.
|
||||
// Note that name and info are copied but currently unused; this is placeholder for a potentially more robust API later.
|
||||
// Both are allowed to be NULL.
|
||||
extern SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, const SDL_PenInfo *info, void *handle);
|
||||
|
||||
SDL_PenStatusInfo last; /* Last reported status, normally read-only for backend */
|
||||
// Backend calls this when an existing pen device is disconnected during runtime. They must free their own stuff separately.
|
||||
extern void SDL_RemovePenDevice(Uint64 timestamp, SDL_PenID instance_id);
|
||||
|
||||
/* Backend: MUST initialise this block when pen is first registered: */
|
||||
SDL_GUID guid; /* GUID, MUST be set by backend.
|
||||
MUST be unique (no other pen ID with same GUID).
|
||||
SHOULD be persistent across sessions. */
|
||||
// Backend can call this to remove all pens, probably during shutdown, with a callback to let them free their own handle.
|
||||
extern void SDL_RemoveAllPenDevices(void (*callback)(SDL_PenID instance_id, void *handle, void *userdata), void *userdata);
|
||||
|
||||
/* Backend: SHOULD initialise this block when pen is first registered if it can
|
||||
Otherwise: Set to sane default values during SDL_PenModifyEnd() */
|
||||
SDL_PenCapabilityInfo info; /* Detail information about the pen (buttons, tilt) */
|
||||
SDL_PenSubtype type;
|
||||
Uint8 last_mouse_button; /* For mouse button emulation: last emulated button */
|
||||
char *name; /* Preallocated; set via SDL_strlcpy(pen->name, src, SDL_PEN_MAX_NAME) */
|
||||
/* We hand this exact pointer to client code, so it must not be modified after
|
||||
creation. */
|
||||
// Backend calls this when a pen's button changes, to generate events and update state.
|
||||
extern int SDL_SendPenTouch(Uint64 timestamp, SDL_PenID instance_id, const SDL_Window *window, Uint8 state, Uint8 eraser);
|
||||
|
||||
void *deviceinfo; /* implementation-specific information */
|
||||
} SDL_Pen;
|
||||
// Backend calls this when a pen moves on the tablet, to generate events and update state.
|
||||
extern int SDL_SendPenMotion(Uint64 timestamp, SDL_PenID instance_id, const SDL_Window *window, float x, float y);
|
||||
|
||||
/* ---- API for backend driver only ---- */
|
||||
// Backend calls this when a pen's axis changes, to generate events and update state.
|
||||
extern int SDL_SendPenAxis(Uint64 timestamp, SDL_PenID instance_id, const SDL_Window *window, SDL_PenAxis axis, float value);
|
||||
|
||||
/**
|
||||
* (Only for backend driver) Look up a pen by pen ID
|
||||
*
|
||||
* \param instance_id A Uint32 pen identifier (driver-dependent meaning). Must not be 0 = SDL_PEN_INVALID.
|
||||
* The same ID is exposed to clients as SDL_PenID.
|
||||
*
|
||||
* The pen pointer is only valid until the next call to SDL_PenModifyEnd() or SDL_PenGCSweep()
|
||||
*
|
||||
* \return pen, if it exists, or NULL
|
||||
*/
|
||||
extern SDL_Pen *SDL_GetPenPtr(Uint32 instance_id);
|
||||
// Backend calls this when a pen's button changes, to generate events and update state.
|
||||
extern int SDL_SendPenButton(Uint64 timestamp, SDL_PenID instance_id, const SDL_Window *window, Uint8 state, Uint8 button);
|
||||
|
||||
/**
|
||||
* (Only for backend driver) Start registering a new pen or updating an existing pen.
|
||||
*
|
||||
* Acquires the pen mutex, which is held until the next call to SDL_PenModifyEnd() .
|
||||
*
|
||||
* If the PenID already exists, returns the existing entry. Otherwise initialise fresh SDL_Pen.
|
||||
* For new pens, sets SDL_PEN_FLAG_NEW.
|
||||
*
|
||||
* Usage:
|
||||
* - SDL_PenModifyStart()
|
||||
* - update pen object, in any order:
|
||||
* - SDL_PenModifyAddCapabilities()
|
||||
* - pen->guid (MUST be set for new pens, e.g. via ::SDL_PenUpdateGUIDForGeneric and related operations)
|
||||
* - pen->info.num_buttons
|
||||
* - pen->info.max_tilt
|
||||
* - pen->type
|
||||
* - pen->name
|
||||
* - pen->deviceinfo (backend-specific)
|
||||
* - SDL_PenModifyEnd()
|
||||
*
|
||||
* For new pens, sets defaults for:
|
||||
* - num_buttons (SDL_PEN_INFO_UNKNOWN)
|
||||
* - max_tilt (SDL_PEN_INFO_UNKNOWN)
|
||||
* - pen_type (SDL_PEN_TYPE_PEN)
|
||||
* - Zeroes all other (non-header) fields
|
||||
*
|
||||
* \param instance_id Pen ID to allocate (must not be 0 = SDL_PEN_ID_INVALID)
|
||||
* \returns SDL_Pen pointer; only valid until the call to SDL_PenModifyEnd()
|
||||
*/
|
||||
extern SDL_Pen *SDL_PenModifyBegin(Uint32 instance_id);
|
||||
// Backend can optionally use this to find the SDL_PenID for the `handle` that was passed to SDL_AddPenDevice.
|
||||
extern SDL_PenID SDL_FindPenByHandle(void *handle);
|
||||
|
||||
/**
|
||||
* (Only for backend driver) Add capabilities to a pen (cf. SDL_PenModifyBegin()).
|
||||
*
|
||||
* Adds capabilities to a pen obtained via SDL_PenModifyBegin(). Can be called more than once.
|
||||
*
|
||||
* \param pen The pen to update
|
||||
* \param capabilities Capabilities flags, out of: SDL_PEN_AXIS_*, SDL_PEN_ERASER_MASK, SDL_PEN_INK_MASK
|
||||
* Setting SDL_PEN_ERASER_MASK will clear SDL_PEN_INK_MASK, and vice versa.
|
||||
*/
|
||||
extern void SDL_PenModifyAddCapabilities(SDL_Pen *pen, Uint32 capabilities);
|
||||
// Backend can optionally use this to find a SDL_PenID, selected by a callback examining all devices. Zero if not found.
|
||||
extern SDL_PenID SDL_FindPenByCallback(SDL_bool (*callback)(void *handle, void *userdata), void *userdata);
|
||||
|
||||
/**
|
||||
* Set up a pen structure for a Wacom device.
|
||||
*
|
||||
* Some backends (e.g., XInput2, Wayland) can only partially identify the capabilities of a given
|
||||
* pen but can identify Wacom pens and obtain their Wacom-specific device type identifiers.
|
||||
* This function partly automates device setup in those cases.
|
||||
*
|
||||
* This function does NOT set up the pen's GUID. Use ::SD_PenModifyGUIDForWacom instead.
|
||||
*
|
||||
* This function does NOT call SDL_PenModifyAddCapabilities() ifself, since some backends may
|
||||
* not have access to all pen axes (e.g., Xinput2).
|
||||
*
|
||||
* \param pen The pen to initialise
|
||||
* \param wacom_devicetype_id The Wacom-specific device type identifier
|
||||
* \param[out] axis_flags The set of physically supported axes for this pen, suitable for passing to
|
||||
* SDL_PenModifyAddCapabilities()
|
||||
*
|
||||
* \returns SDL_TRUE if the device ID could be identified, otherwise SDL_FALSE
|
||||
*/
|
||||
extern int SDL_PenModifyForWacomID(SDL_Pen *pen, Uint32 wacom_devicetype_id, Uint32 *axis_flags);
|
||||
// Backend can use this to map an axis to a capability bit.
|
||||
SDL_PenCapabilityFlags SDL_GetPenCapabilityFromAxis(SDL_PenAxis axis);
|
||||
|
||||
/**
|
||||
* Updates a GUID for a generic pen device.
|
||||
*
|
||||
* Assumes that the GUID has been pre-initialised (typically to 0).
|
||||
* Idempotent, and commutative with ::SDL_PenUpdateGUIDForWacom and ::SDL_PenUpdateGUIDForType
|
||||
*
|
||||
* \param[out] guid The GUID to update
|
||||
* \param upper Upper half of the device ID (assume lower entropy than "lower"; pass 0 if not available)
|
||||
* \param lower Lower half of the device ID (assume higher entropy than "upper")
|
||||
*/
|
||||
extern void SDL_PenUpdateGUIDForGeneric(SDL_GUID *guid, Uint32 upper, Uint32 lower);
|
||||
// Higher-level SDL video subsystem code calls this when starting up. Backends shouldn't.
|
||||
extern int SDL_InitPen(void);
|
||||
|
||||
/**
|
||||
* Updates a GUID based on a pen type
|
||||
*
|
||||
* Assumes that the GUID has been pre-initialised (typically to 0).
|
||||
* Idempotent, and commutative with ::SDL_PenUpdateGUIDForWacom and ::SDL_PenUpdateGUIDForGeneric
|
||||
*
|
||||
* \param[out] guid The GUID to update
|
||||
* \param pentype The pen type to insert
|
||||
*/
|
||||
extern void SDL_PenUpdateGUIDForType(SDL_GUID *guid, SDL_PenSubtype pentype);
|
||||
|
||||
/**
|
||||
* Updates a GUID for a Wacom pen device.
|
||||
*
|
||||
* Assumes that the GUID has been pre-initialised (typically to 0).
|
||||
* Idempotent, and commutative with ::SDL_PenUpdateGUIDForType and ::SDL_PenUpdateGUIDForGeneric
|
||||
*
|
||||
* This update is identical to the one written by ::SDL_PenModifyFromWacomID .
|
||||
*
|
||||
* \param[out] guid The GUID to update
|
||||
* \param wacom_devicetype_id The Wacom-specific device type identifier
|
||||
* \param wacom_serial_id The Wacom-specific serial number
|
||||
*/
|
||||
extern void SDL_PenUpdateGUIDForWacom(SDL_GUID *guid, Uint32 wacom_devicetype_id, Uint32 wacom_serial_id);
|
||||
|
||||
/**
|
||||
* (Only for backend driver) Finish updating a pen.
|
||||
*
|
||||
* Releases the pen mutex acquired by SDL_PenModifyBegin() .
|
||||
*
|
||||
* If pen->type == SDL_PEN_TYPE_NONE, removes the pen entirely (only
|
||||
* for new pens). This allows backends to start registering a
|
||||
* potential pen device and to abort if the device turns out to not be
|
||||
* a pen.
|
||||
*
|
||||
* For new pens, this call will also set the following:
|
||||
* - name (default name, if not yet set)
|
||||
*
|
||||
* \param pen The pen to register. That pointer is no longer valid after this call.
|
||||
* \param attach Whether the pen should be attached (SDL_TRUE) or detached (SDL_FALSE).
|
||||
*
|
||||
* If the pen is detached or removed, it is the caller's responsibility to free
|
||||
* and null "deviceinfo".
|
||||
*/
|
||||
extern void SDL_PenModifyEnd(SDL_Pen *pen, SDL_bool attach);
|
||||
|
||||
/**
|
||||
* (Only for backend driver) Mark all current pens for garbage collection.
|
||||
*
|
||||
* Must not be called while the pen mutex is held (by SDL_PenModifyBegin() ).
|
||||
*
|
||||
* SDL_PenGCMark() / SDL_PenGCSweep() provide a simple mechanism for
|
||||
* detaching all known pens that are not discoverable. This allows
|
||||
* backends to use the same code for pen discovery and for
|
||||
* hotplugging:
|
||||
*
|
||||
* - SDL_PenGCMark() and start backend-specific discovery
|
||||
* - for each discovered pen: SDL_PenModifyBegin() + SDL_PenModifyEnd() (this will retain existing state)
|
||||
* - SDL_PenGCSweep() (will now detach all pens that were not re-registered).
|
||||
*/
|
||||
extern void SDL_PenGCMark(void);
|
||||
|
||||
/**
|
||||
* (Only for backend driver) Detach pens that haven't been reported attached since the last call to SDL_PenGCMark().
|
||||
*
|
||||
* Must not be called while the pen mutex is held (by SDL_PenModifyBegin() ).
|
||||
*
|
||||
* See SDL_PenGCMark() for details.
|
||||
*
|
||||
* \param context Extra parameter to pass through to "free_deviceinfo"
|
||||
* \param free_deviceinfo Operation to call on any non-NULL "backend.deviceinfo".
|
||||
*
|
||||
* \sa SDL_PenGCMark()
|
||||
*/
|
||||
extern void SDL_PenGCSweep(void *context, void (*free_deviceinfo)(Uint32 instance_id, void *deviceinfo, void *context));
|
||||
|
||||
/**
|
||||
* (Only for backend driver) Send a pen motion event.
|
||||
*
|
||||
* Suppresses pen motion events that do not change the current pen state.
|
||||
* May also send a mouse motion event, if mouse emulation is enabled and the pen position has
|
||||
* changed sufficiently for the motion to be visible to mouse event listeners.
|
||||
*
|
||||
* \param timestamp Event timestamp in nanoseconds, or 0 to ask SDL to use SDL_GetTicksNS() .
|
||||
* While 0 is safe to report, your backends may be able to report more precise
|
||||
* timing information.
|
||||
* Keep in mind that you should never report timestamps that are greater than
|
||||
* SDL_GetTicksNS() . In particular, SDL_GetTicksNS() reports nanoseconds since the start
|
||||
* of the SDL session, and your backend may use a different starting point as "timestamp zero".
|
||||
* \param instance_id Pen
|
||||
* \param window_relative Coordinates are already window-relative
|
||||
* \param status Coordinates and axes (buttons are ignored)
|
||||
*
|
||||
* \returns SDL_TRUE if at least one event was sent
|
||||
*/
|
||||
extern int SDL_SendPenMotion(Uint64 timestamp, SDL_PenID instance_id, SDL_bool window_relative, const SDL_PenStatusInfo *status);
|
||||
|
||||
/**
|
||||
* (Only for backend driver) Send a pen button event
|
||||
*
|
||||
* \param timestamp Event timestamp in nanoseconds, or 0 to ask SDL to use SDL_GetTicksNS() .
|
||||
* See SDL_SendPenMotion() for a discussion about how to handle timestamps.
|
||||
* \param instance_id Pen
|
||||
* \param state SDL_PRESSED or SDL_RELEASED
|
||||
* \param button Button number: 1 (first physical button) etc.
|
||||
*
|
||||
* \returns SDL_TRUE if at least one event was sent
|
||||
*/
|
||||
extern int SDL_SendPenButton(Uint64 timestamp, SDL_PenID instance_id, Uint8 state, Uint8 button);
|
||||
|
||||
/**
|
||||
* (Only for backend driver) Send a pen tip event (touching or no longer touching the surface)
|
||||
*
|
||||
* Note: the backend should perform hit testing on window decoration elements to allow the pen
|
||||
* to e.g. resize/move the window, just as for mouse events, unless ::SDL_SendPenTipEvent is false.
|
||||
*
|
||||
* \param timestamp Event timestamp in nanoseconds, or 0 to ask SDL to use SDL_GetTicksNS() .
|
||||
* See SDL_SendPenMotion() for a discussion about how to handle timestamps.
|
||||
* \param instance_id Pen
|
||||
* \param state SDL_PRESSED (for PEN_DOWN) or SDL_RELEASED (for PEN_UP)
|
||||
*
|
||||
* \returns SDL_TRUE if at least one event was sent
|
||||
*/
|
||||
extern int SDL_SendPenTipEvent(Uint64 timestamp, SDL_PenID instance_id, Uint8 state);
|
||||
|
||||
/**
|
||||
* (Only for backend driver) Check if a PEN_DOWN event should perform hit box testing.
|
||||
*
|
||||
* \returns SDL_TRUE if and only if the backend should perform hit testing
|
||||
*/
|
||||
extern SDL_bool SDL_PenPerformHitTest(void);
|
||||
|
||||
/**
|
||||
* (Only for backend driver) Send a pen window event.
|
||||
*
|
||||
* Tracks when a pen has entered/left a window.
|
||||
* Don't call this when reporting new pens or removing known pens; those cases are handled automatically.
|
||||
*
|
||||
* \param timestamp Event timestamp in nanoseconds, or 0 to ask SDL to use SDL_GetTicksNS() .
|
||||
* See SDL_SendPenMotion() for a discussion about how to handle timestamps.
|
||||
* \param instance_id Pen
|
||||
* \param window Window to enter, or NULL to exit
|
||||
*/
|
||||
extern int SDL_SendPenWindowEvent(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window);
|
||||
|
||||
/**
|
||||
* Initialises the pen subsystem.
|
||||
*/
|
||||
extern void SDL_PenInit(void);
|
||||
|
||||
/**
|
||||
* De-initialises the pen subsystem.
|
||||
*/
|
||||
extern void SDL_PenQuit(void);
|
||||
// Higher-level SDL video subsystem code calls this when shutting down. Backends shouldn't.
|
||||
extern void SDL_QuitPen(void);
|
||||
|
||||
#endif /* SDL_pen_c_h_ */
|
||||
|
||||
|
||||
@@ -563,6 +563,7 @@ int SDL_VideoInit(const char *driver_name)
|
||||
SDL_bool init_keyboard = SDL_FALSE;
|
||||
SDL_bool init_mouse = SDL_FALSE;
|
||||
SDL_bool init_touch = SDL_FALSE;
|
||||
SDL_bool init_pen = SDL_FALSE;
|
||||
int i = 0;
|
||||
|
||||
/* Check to make sure we don't overwrite '_this' */
|
||||
@@ -589,6 +590,10 @@ int SDL_VideoInit(const char *driver_name)
|
||||
goto pre_driver_error;
|
||||
}
|
||||
init_touch = SDL_TRUE;
|
||||
if (SDL_InitPen() < 0) {
|
||||
goto pre_driver_error;
|
||||
}
|
||||
init_pen = SDL_TRUE;
|
||||
|
||||
/* Select the proper video driver */
|
||||
video = NULL;
|
||||
@@ -673,6 +678,9 @@ int SDL_VideoInit(const char *driver_name)
|
||||
|
||||
pre_driver_error:
|
||||
SDL_assert(_this == NULL);
|
||||
if (init_pen) {
|
||||
SDL_QuitPen();
|
||||
}
|
||||
if (init_touch) {
|
||||
SDL_QuitTouch();
|
||||
}
|
||||
@@ -4217,6 +4225,7 @@ void SDL_VideoQuit(void)
|
||||
}
|
||||
|
||||
/* Halt event processing before doing anything else */
|
||||
SDL_QuitPen();
|
||||
SDL_QuitTouch();
|
||||
SDL_QuitMouse();
|
||||
SDL_QuitKeyboard();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,41 +41,11 @@ enum SDL_WaylandAxisEvent
|
||||
|
||||
struct SDL_WaylandTabletSeat;
|
||||
|
||||
struct SDL_WaylandTabletObjectListNode
|
||||
typedef struct SDL_WaylandTabletInput
|
||||
{
|
||||
void *object;
|
||||
struct SDL_WaylandTabletObjectListNode *next;
|
||||
};
|
||||
|
||||
struct SDL_WaylandTabletInput
|
||||
{
|
||||
struct SDL_WaylandInput *sdlWaylandInput;
|
||||
struct SDL_WaylandInput *input;
|
||||
struct zwp_tablet_seat_v2 *seat;
|
||||
|
||||
struct SDL_WaylandTabletObjectListNode *tablets;
|
||||
struct SDL_WaylandTabletObjectListNode *tools;
|
||||
struct SDL_WaylandTabletObjectListNode *pads;
|
||||
|
||||
Uint32 id;
|
||||
Uint32 num_pens; /* next pen ID is num_pens+1 */
|
||||
struct SDL_WaylandCurrentPen
|
||||
{
|
||||
SDL_Pen *builder; /* pen that is being defined or receiving updates, if any */
|
||||
SDL_bool builder_guid_complete; /* have complete/precise GUID information */
|
||||
SDL_PenStatusInfo update_status; /* collects pen update information before sending event */
|
||||
Uint16 buttons_pressed; /* Mask of newly pressed buttons, plus SDL_PEN_DOWN_MASK for PEN_DOWN */
|
||||
Uint16 buttons_released; /* Mask of newly pressed buttons, plus SDL_PEN_DOWN_MASK for PEN_UP */
|
||||
Uint32 serial; /* Most recent serial event number observed, or 0 */
|
||||
SDL_WindowData *update_window; /* NULL while no event is in progress, otherwise the affected window */
|
||||
} current_pen;
|
||||
|
||||
SDL_WindowData *tool_focus;
|
||||
uint32_t tool_prox_serial;
|
||||
|
||||
/* Last motion end location (kept separate from sx_w, sy_w for the mouse pointer) */
|
||||
wl_fixed_t sx_w;
|
||||
wl_fixed_t sy_w;
|
||||
};
|
||||
} SDL_WaylandTabletInput;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -169,7 +139,7 @@ struct SDL_WaylandInput
|
||||
|
||||
SDL_WaylandKeyboardRepeat keyboard_repeat;
|
||||
|
||||
struct SDL_WaylandTabletInput *tablet;
|
||||
SDL_WaylandTabletInput *tablet_input;
|
||||
|
||||
SDL_bool keyboard_is_virtual;
|
||||
|
||||
@@ -178,11 +148,6 @@ struct SDL_WaylandInput
|
||||
SDL_Keymod locked_modifiers;
|
||||
};
|
||||
|
||||
struct SDL_WaylandTool
|
||||
{
|
||||
SDL_PenID penid;
|
||||
struct SDL_WaylandTabletInput *tablet;
|
||||
};
|
||||
|
||||
extern Uint64 Wayland_GetTouchTimestamp(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms);
|
||||
|
||||
@@ -209,8 +174,8 @@ extern int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input, SDL_W
|
||||
extern int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *input);
|
||||
extern int Wayland_input_ungrab_keyboard(SDL_Window *window);
|
||||
|
||||
extern void Wayland_input_add_tablet(struct SDL_WaylandInput *input, struct SDL_WaylandTabletManager *tablet_manager);
|
||||
extern void Wayland_input_destroy_tablet(struct SDL_WaylandInput *input);
|
||||
extern void Wayland_input_init_tablet_support(struct SDL_WaylandInput *input, struct zwp_tablet_manager_v2 *tablet_manager);
|
||||
extern void Wayland_input_quit_tablet_support(struct SDL_WaylandInput *input);
|
||||
|
||||
extern void Wayland_RegisterTimestampListeners(struct SDL_WaylandInput *input);
|
||||
extern void Wayland_CreateCursorShapeDevice(struct SDL_WaylandInput *input);
|
||||
|
||||
@@ -1167,7 +1167,7 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
|
||||
d->decoration_manager = wl_registry_bind(d->registry, id, &zxdg_decoration_manager_v1_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "zwp_tablet_manager_v2") == 0) {
|
||||
d->tablet_manager = wl_registry_bind(d->registry, id, &zwp_tablet_manager_v2_interface, 1);
|
||||
Wayland_input_add_tablet(d->input, d->tablet_manager);
|
||||
Wayland_input_init_tablet_support(d->input, d->tablet_manager);
|
||||
} else if (SDL_strcmp(interface, "zxdg_output_manager_v1") == 0) {
|
||||
version = SDL_min(version, 3); /* Versions 1 through 3 are supported. */
|
||||
d->xdg_output_manager = wl_registry_bind(d->registry, id, &zxdg_output_manager_v1_interface, version);
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
|
||||
struct xkb_context;
|
||||
struct SDL_WaylandInput;
|
||||
struct SDL_WaylandTabletManager;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -84,10 +83,10 @@ struct SDL_VideoData
|
||||
struct wp_alpha_modifier_v1 *wp_alpha_modifier_v1;
|
||||
struct kde_output_order_v1 *kde_output_order;
|
||||
struct frog_color_management_factory_v1 *frog_color_management_factory_v1;
|
||||
struct zwp_tablet_manager_v2 *tablet_manager;
|
||||
|
||||
struct xkb_context *xkb_context;
|
||||
struct SDL_WaylandInput *input;
|
||||
struct SDL_WaylandTabletManager *tablet_manager;
|
||||
struct wl_list output_list;
|
||||
struct wl_list output_order;
|
||||
|
||||
|
||||
@@ -1996,9 +1996,6 @@ void X11_PumpEvents(SDL_VideoDevice *_this)
|
||||
}
|
||||
|
||||
if (data->xinput_hierarchy_changed) {
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||
X11_InitPen(_this);
|
||||
#endif
|
||||
X11_Xinput2UpdateDevices(_this, SDL_FALSE);
|
||||
data->xinput_hierarchy_changed = SDL_FALSE;
|
||||
}
|
||||
|
||||
+247
-523
File diff suppressed because it is too large
Load Diff
+32
-13
@@ -23,32 +23,51 @@
|
||||
#ifndef SDL_x11pen_h_
|
||||
#define SDL_x11pen_h_
|
||||
|
||||
// Pressure-sensitive pen support for X11.
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||
|
||||
#include "SDL_x11video.h"
|
||||
#include "../../events/SDL_pen_c.h"
|
||||
|
||||
/* Pressure-sensitive pen */
|
||||
|
||||
/* Forward definition for SDL_x11video.h */
|
||||
// Forward definition for SDL_x11video.h
|
||||
struct SDL_VideoData;
|
||||
|
||||
/* Function definitions */
|
||||
#define SDL_X11_PEN_AXIS_VALUATOR_MISSING -1
|
||||
|
||||
/* Detect XINPUT2 devices that are pens / erasers, or update the list after hotplugging */
|
||||
typedef struct X11_PenHandle
|
||||
{
|
||||
SDL_PenID pen;
|
||||
SDL_bool is_eraser;
|
||||
int x11_deviceid;
|
||||
int valuator_for_axis[SDL_PEN_NUM_AXES];
|
||||
float slider_bias; // shift value to add to PEN_AXIS_SLIDER (before normalisation)
|
||||
float rotation_bias; // rotation to add to PEN_AXIS_ROTATION (after normalisation)
|
||||
float axis_min[SDL_PEN_NUM_AXES];
|
||||
float axis_max[SDL_PEN_NUM_AXES];
|
||||
} X11_PenHandle;
|
||||
|
||||
// Prep pen support (never fails; pens simply won't be added if there's a problem).
|
||||
extern void X11_InitPen(SDL_VideoDevice *_this);
|
||||
|
||||
/* Converts XINPUT2 valuators into pen axis information, including normalisation */
|
||||
extern void X11_PenAxesFromValuators(const SDL_Pen *pen,
|
||||
// Clean up pen support.
|
||||
extern void X11_QuitPen(SDL_VideoDevice *_this);
|
||||
|
||||
// Converts XINPUT2 valuators into pen axis information, including normalisation.
|
||||
extern void X11_PenAxesFromValuators(const X11_PenHandle *pen,
|
||||
const double *input_values, const unsigned char *mask, const int mask_len,
|
||||
/* out-mode parameters: */
|
||||
float axis_values[SDL_PEN_NUM_AXES]);
|
||||
|
||||
/* Map X11 device ID to pen ID */
|
||||
extern int X11_PenIDFromDeviceID(int deviceid);
|
||||
// Add a pen (if this function's further checks validate it).
|
||||
extern X11_PenHandle *X11_MaybeAddPenByDeviceID(SDL_VideoDevice *_this, int deviceid);
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_X11_XINPUT2 */
|
||||
// Remove a pen. It's okay if deviceid is bogus or not a pen, we'll check it.
|
||||
extern void X11_RemovePenByDeviceID(int deviceid);
|
||||
|
||||
#endif /* SDL_x11pen_h_ */
|
||||
// Map X11 device ID to pen ID.
|
||||
extern X11_PenHandle *X11_FindPenByDeviceID(int deviceid);
|
||||
|
||||
#endif // SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||
|
||||
#endif // SDL_x11pen_h_
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -456,9 +456,7 @@ int X11_VideoInit(SDL_VideoDevice *_this)
|
||||
|
||||
X11_InitTouch(_this);
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2
|
||||
X11_InitPen(_this);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -485,6 +483,7 @@ void X11_VideoQuit(SDL_VideoDevice *_this)
|
||||
X11_QuitKeyboard(_this);
|
||||
X11_QuitMouse(_this);
|
||||
X11_QuitTouch(_this);
|
||||
X11_QuitPen(_this);
|
||||
X11_QuitClipboard(_this);
|
||||
X11_QuitXsettings(_this);
|
||||
}
|
||||
|
||||
@@ -104,6 +104,14 @@ struct SDL_VideoData
|
||||
Atom XdndSelection;
|
||||
Atom XKLAVIER_STATE;
|
||||
|
||||
/* Pen atoms (these have names that don't map well to C symbols) */
|
||||
Atom pen_atom_device_product_id;
|
||||
Atom pen_atom_abs_pressure;
|
||||
Atom pen_atom_abs_tilt_x;
|
||||
Atom pen_atom_abs_tilt_y;
|
||||
Atom pen_atom_wacom_serial_ids;
|
||||
Atom pen_atom_wacom_tool_type;
|
||||
|
||||
SDL_Scancode key_layout[256];
|
||||
SDL_bool selection_waiting;
|
||||
SDL_bool selection_incr_waiting;
|
||||
@@ -141,7 +149,6 @@ struct SDL_VideoData
|
||||
SDL_bool steam_keyboard_open;
|
||||
|
||||
SDL_bool is_xwayland;
|
||||
|
||||
};
|
||||
|
||||
extern SDL_bool X11_UseDirectColorVisuals(void);
|
||||
|
||||
@@ -274,18 +274,6 @@ static SDL_XInput2DeviceInfo *xinput2_get_device_info(SDL_VideoData *videodata,
|
||||
|
||||
return devinfo;
|
||||
}
|
||||
|
||||
static void xinput2_pen_ensure_window(SDL_VideoDevice *_this, const SDL_Pen *pen, Window window)
|
||||
{
|
||||
/* When "flipping" a Wacom eraser pen, we get an XI_DeviceChanged event
|
||||
* with the newly-activated pen, but this event is global for the display.
|
||||
* We won't get a window until the pen starts triggering motion or
|
||||
* button events, so we instead hook the pen to its window at that point. */
|
||||
const SDL_WindowData *windowdata = X11_FindWindow(_this, window);
|
||||
if (windowdata) {
|
||||
SDL_SendPenWindowEvent(0, pen->header.id, windowdata->window);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
|
||||
@@ -303,6 +291,14 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
|
||||
const XIHierarchyEvent *hierev = (const XIHierarchyEvent *)cookie->data;
|
||||
int i;
|
||||
for (i = 0; i < hierev->num_info; i++) {
|
||||
// pen stuff...
|
||||
if ((hierev->info[i].flags & (XISlaveRemoved | XIDeviceDisabled)) != 0) {
|
||||
X11_RemovePenByDeviceID(hierev->info[i].deviceid); // it's okay if this thing isn't actually a pen, it'll handle it.
|
||||
} else if ((hierev->info[i].flags & (XISlaveAdded | XIDeviceEnabled)) != 0) {
|
||||
X11_MaybeAddPenByDeviceID(_this, hierev->info[i].deviceid); // this will do more checks to make sure this is valid.
|
||||
}
|
||||
|
||||
// not pen stuff...
|
||||
if (hierev->info[i].flags & XISlaveRemoved) {
|
||||
xinput2_remove_device_info(videodata, hierev->info[i].deviceid);
|
||||
}
|
||||
@@ -310,29 +306,14 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
|
||||
videodata->xinput_hierarchy_changed = SDL_TRUE;
|
||||
} break;
|
||||
|
||||
case XI_PropertyEvent:
|
||||
case XI_DeviceChanged:
|
||||
{
|
||||
// FIXME: We shouldn't rescan all devices for pen changes every time a property or active slave changes
|
||||
X11_InitPen(_this);
|
||||
} break;
|
||||
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
{
|
||||
const XIEnterEvent *enterev = (const XIEnterEvent *)cookie->data;
|
||||
const SDL_WindowData *windowdata = X11_FindWindow(_this, enterev->event);
|
||||
const SDL_Pen *pen = SDL_GetPenPtr(X11_PenIDFromDeviceID(enterev->sourceid));
|
||||
SDL_Window *window = (windowdata && (cookie->evtype == XI_Enter)) ? windowdata->window : NULL;
|
||||
if (pen) {
|
||||
SDL_SendPenWindowEvent(0, pen->header.id, window);
|
||||
}
|
||||
} break;
|
||||
// !!! FIXME: the pen code used to rescan all devices here, but we can do this device-by-device with XI_HierarchyChanged. When do these events fire and why?
|
||||
//case XI_PropertyEvent:
|
||||
//case XI_DeviceChanged:
|
||||
|
||||
case XI_RawMotion:
|
||||
{
|
||||
const XIRawEvent *rawev = (const XIRawEvent *)cookie->data;
|
||||
const SDL_bool is_pen = X11_PenIDFromDeviceID(rawev->sourceid) != SDL_PEN_INVALID;
|
||||
const SDL_bool is_pen = X11_FindPenByDeviceID(rawev->sourceid) != NULL;
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
SDL_XInput2DeviceInfo *devinfo;
|
||||
double coords[2];
|
||||
@@ -341,11 +322,9 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
|
||||
|
||||
videodata->global_mouse_changed = SDL_TRUE;
|
||||
if (is_pen) {
|
||||
break; /* Pens check for XI_Motion instead */
|
||||
break; // Pens check for XI_Motion instead
|
||||
}
|
||||
|
||||
/* Non-pen: */
|
||||
|
||||
if (!mouse->relative_mode || mouse->relative_mode_warp) {
|
||||
break;
|
||||
}
|
||||
@@ -426,31 +405,17 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
|
||||
case XI_ButtonRelease:
|
||||
{
|
||||
const XIDeviceEvent *xev = (const XIDeviceEvent *)cookie->data;
|
||||
const SDL_Pen *pen = SDL_GetPenPtr(X11_PenIDFromDeviceID(xev->deviceid));
|
||||
X11_PenHandle *pen = X11_FindPenByDeviceID(xev->deviceid);
|
||||
const int button = xev->detail;
|
||||
const SDL_bool pressed = (cookie->evtype == XI_ButtonPress) ? SDL_TRUE : SDL_FALSE;
|
||||
|
||||
if (pen) {
|
||||
xinput2_pen_ensure_window(_this, pen, xev->event);
|
||||
|
||||
/* Only report button event; if there was also pen movement / pressure changes, we expect
|
||||
an XI_Motion event first anyway */
|
||||
if (button == 1) {
|
||||
/* button 1 is the pen tip */
|
||||
if (pressed && SDL_PenPerformHitTest()) {
|
||||
/* Check whether we should handle window resize / move events */
|
||||
SDL_WindowData *windowdata = X11_FindWindow(_this, xev->event);
|
||||
if (windowdata && X11_TriggerHitTestAction(_this, windowdata, pen->last.x, pen->last.y)) {
|
||||
SDL_SendWindowEvent(windowdata->window, SDL_EVENT_WINDOW_HIT_TEST, 0, 0);
|
||||
break; /* Don't pass on this event */
|
||||
}
|
||||
}
|
||||
SDL_SendPenTipEvent(0, pen->header.id,
|
||||
pressed ? SDL_PRESSED : SDL_RELEASED);
|
||||
// Only report button event; if there was also pen movement / pressure changes, we expect an XI_Motion event first anyway.
|
||||
SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event);
|
||||
if (button == 1) { // button 1 is the pen tip
|
||||
SDL_SendPenTouch(0, pen->pen, window, pressed ? SDL_PRESSED : SDL_RELEASED, pen->is_eraser);
|
||||
} else {
|
||||
SDL_SendPenButton(0, pen->header.id,
|
||||
pressed ? SDL_PRESSED : SDL_RELEASED,
|
||||
button - 1);
|
||||
SDL_SendPenButton(0, pen->pen, window, pressed ? SDL_PRESSED : SDL_RELEASED, button - 1);
|
||||
}
|
||||
} else {
|
||||
/* Otherwise assume a regular mouse */
|
||||
@@ -475,7 +440,6 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
|
||||
case XI_Motion:
|
||||
{
|
||||
const XIDeviceEvent *xev = (const XIDeviceEvent *)cookie->data;
|
||||
const SDL_Pen *pen = SDL_GetPenPtr(X11_PenIDFromDeviceID(xev->deviceid));
|
||||
#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH
|
||||
SDL_bool pointer_emulated = ((xev->flags & XIPointerEmulated) != 0);
|
||||
#else
|
||||
@@ -489,25 +453,20 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
|
||||
break;
|
||||
}
|
||||
|
||||
X11_PenHandle *pen = X11_FindPenByDeviceID(xev->deviceid);
|
||||
if (pen) {
|
||||
SDL_PenStatusInfo pen_status;
|
||||
SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event);
|
||||
SDL_SendPenMotion(0, pen->pen, window, (float) xev->event_x, (float) xev->event_y);
|
||||
|
||||
pen_status.x = (float)xev->event_x;
|
||||
pen_status.y = (float)xev->event_y;
|
||||
float axes[SDL_PEN_NUM_AXES];
|
||||
X11_PenAxesFromValuators(pen, xev->valuators.values, xev->valuators.mask, xev->valuators.mask_len, axes);
|
||||
|
||||
X11_PenAxesFromValuators(pen,
|
||||
xev->valuators.values, xev->valuators.mask, xev->valuators.mask_len,
|
||||
&pen_status.axes[0]);
|
||||
|
||||
xinput2_pen_ensure_window(_this, pen, xev->event);
|
||||
|
||||
SDL_SendPenMotion(0, pen->header.id,
|
||||
SDL_TRUE,
|
||||
&pen_status);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pointer_emulated) {
|
||||
for (int i = 0; i < SDL_arraysize(axes); i++) {
|
||||
if (pen->valuator_for_axis[i] != SDL_X11_PEN_AXIS_VALUATOR_MISSING) {
|
||||
SDL_SendPenAxis(0, pen->pen, window, (SDL_PenAxis) i, axes[i]);
|
||||
}
|
||||
}
|
||||
} else if (!pointer_emulated) {
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
if (!mouse->relative_mode || mouse->relative_mode_warp) {
|
||||
SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event);
|
||||
|
||||
@@ -34,9 +34,6 @@ static SDLTest_TestSuiteReference *testSuites[] = {
|
||||
&mainTestSuite,
|
||||
&mathTestSuite,
|
||||
&mouseTestSuite,
|
||||
#if !defined(SDL_PLATFORM_IOS) && !defined(SDL_PLATFORM_TVOS)
|
||||
&penTestSuite,
|
||||
#endif
|
||||
&pixelsTestSuite,
|
||||
&platformTestSuite,
|
||||
&propertiesTestSuite,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,6 @@ extern SDLTest_TestSuiteReference logTestSuite;
|
||||
extern SDLTest_TestSuiteReference mainTestSuite;
|
||||
extern SDLTest_TestSuiteReference mathTestSuite;
|
||||
extern SDLTest_TestSuiteReference mouseTestSuite;
|
||||
extern SDLTest_TestSuiteReference penTestSuite;
|
||||
extern SDLTest_TestSuiteReference pixelsTestSuite;
|
||||
extern SDLTest_TestSuiteReference platformTestSuite;
|
||||
extern SDLTest_TestSuiteReference propertiesTestSuite;
|
||||
|
||||
+258
-494
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user