Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/SDL3/SDL_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,9 @@ typedef struct SDL_PinchFingerEvent
* 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.
*
* Not all platforms have a window associated with the pen during proximity
* events. Some wait until motion/button/etc events to offer this info.
*
* \since This struct is available since SDL 3.2.0.
*/
typedef struct SDL_PenProximityEvent
Expand Down
6 changes: 4 additions & 2 deletions src/events/SDL_pen.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ SDL_PenCapabilityFlags SDL_GetPenCapabilityFromAxis(SDL_PenAxis axis)
return 0; // oh well.
}

SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, const SDL_PenInfo *info, void *handle)
SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, SDL_Window *window, const SDL_PenInfo *info, void *handle)
{
SDL_assert(handle != NULL); // just allocate a Uint8 so you have a unique pointer if not needed!
SDL_assert(SDL_FindPenByHandle(handle) == 0); // Backends shouldn't double-add pens!
Expand Down Expand Up @@ -262,13 +262,14 @@ SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, const SDL_PenInfo
event.pproximity.type = SDL_EVENT_PEN_PROXIMITY_IN;
event.pproximity.timestamp = timestamp;
event.pproximity.which = result;
event.pproximity.windowID = window ? window->id : 0;
SDL_PushEvent(&event);
}

return result;
}

void SDL_RemovePenDevice(Uint64 timestamp, SDL_PenID instance_id)
void SDL_RemovePenDevice(Uint64 timestamp, SDL_Window *window, SDL_PenID instance_id)
{
if (!instance_id) {
return;
Expand Down Expand Up @@ -306,6 +307,7 @@ void SDL_RemovePenDevice(Uint64 timestamp, SDL_PenID instance_id)
event.pproximity.type = SDL_EVENT_PEN_PROXIMITY_OUT;
event.pproximity.timestamp = timestamp;
event.pproximity.which = instance_id;
event.pproximity.windowID = window ? window->id : 0;
SDL_PushEvent(&event);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/events/SDL_pen_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ typedef struct SDL_PenInfo
// 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);
extern SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, SDL_Window *window, const SDL_PenInfo *info, void *handle);

// 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);
extern void SDL_RemovePenDevice(Uint64 timestamp, SDL_Window *window, SDL_PenID instance_id);

// 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);
Expand Down
4 changes: 2 additions & 2 deletions src/video/android/SDL_androidpen.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void Android_OnPen(SDL_Window *window, int pen_id_in, SDL_PenDeviceType device_t
peninfo.num_buttons = 2;
peninfo.subtype = SDL_PEN_TYPE_PEN;
peninfo.device_type = device_type;
pen = SDL_AddPenDevice(0, NULL, &peninfo, (void *) (size_t) pen_id_in);
pen = SDL_AddPenDevice(0, NULL, window, &peninfo, (void *) (size_t) pen_id_in);
if (!pen) {
SDL_Log("error: can't add a pen device %d", pen_id_in);
return;
Expand All @@ -78,7 +78,7 @@ void Android_OnPen(SDL_Window *window, int pen_id_in, SDL_PenDeviceType device_t
switch (action) {
case ACTION_CANCEL:
case ACTION_HOVER_EXIT:
SDL_RemovePenDevice(0, pen);
SDL_RemovePenDevice(0, window, pen);
break;

case ACTION_DOWN:
Expand Down
4 changes: 2 additions & 2 deletions src/video/cocoa/SDL_cocoapen.m
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ static void Cocoa_HandlePenProximityEvent(SDL_CocoaWindowData *_data, NSEvent *e
handle->deviceid = devid;
handle->toolid = toolid;
handle->is_eraser = is_eraser;
handle->pen = SDL_AddPenDevice(Cocoa_GetEventTimestamp([event timestamp]), NULL, &peninfo, handle);
handle->pen = SDL_AddPenDevice(Cocoa_GetEventTimestamp([event timestamp]), NULL, _data.window, &peninfo, handle);
if (!handle->pen) {
SDL_free(handle); // oh well.
}
} else { // old pen leaving!
Cocoa_PenHandle *handle = Cocoa_FindPenByDeviceID(devid, toolid);
if (handle) {
SDL_RemovePenDevice(Cocoa_GetEventTimestamp([event timestamp]), handle->pen);
SDL_RemovePenDevice(Cocoa_GetEventTimestamp([event timestamp]), _data.window, handle->pen);
SDL_free(handle);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/video/emscripten/SDL_emscriptenevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ static void Emscripten_HandlePenEnter(SDL_WindowData *window_data, const Emscrip
peninfo.max_tilt = 90.0f;
peninfo.num_buttons = 2;
peninfo.subtype = SDL_PEN_TYPE_PEN;
SDL_AddPenDevice(0, NULL, &peninfo, (void *) (size_t) event->pointerid);
SDL_AddPenDevice(0, NULL, window_data->window, &peninfo, (void *) (size_t) event->pointerid);
Emscripten_UpdatePenFromEvent(window_data, event);
}

Expand All @@ -878,7 +878,7 @@ static void Emscripten_HandlePenLeave(SDL_WindowData *window_data, const Emscrip
const SDL_PenID pen = SDL_FindPenByHandle((void *) (size_t) event->pointerid);
if (pen) {
Emscripten_UpdatePointerFromEvent(window_data, event); // last data updates?
SDL_RemovePenDevice(0, pen);
SDL_RemovePenDevice(0, window_data->window, pen);
}
}

Expand Down
18 changes: 10 additions & 8 deletions src/video/uikit/SDL_uikitpen.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ bool UIKit_InitPen(SDL_VideoDevice *_this)
// we only have one Apple Pencil at a time, and it must be paired to the iOS device.
// We only know about its existence when it first sends an event, so add an single SDL pen
// device here if we haven't already.
static SDL_PenID UIKit_AddPenIfNecesary()
static SDL_PenID UIKit_AddPenIfNecesary(SDL_Window *window)
{
if (!apple_pencil_id) {
SDL_PenInfo info;
Expand All @@ -86,7 +86,7 @@ static SDL_PenID UIKit_AddPenIfNecesary()
// so we can't use it for tangential pressure.

// There's only ever one Apple Pencil at most, so we just pass a non-zero value for the handle.
apple_pencil_id = SDL_AddPenDevice(0, "Apple Pencil", &info, (void *) (size_t) 0x1);
apple_pencil_id = SDL_AddPenDevice(0, "Apple Pencil", window, &info, (void *) (size_t) 0x1);
}

return apple_pencil_id;
Expand All @@ -95,7 +95,7 @@ static SDL_PenID UIKit_AddPenIfNecesary()
static void UIKit_HandlePenAxes(SDL_Window *window, NSTimeInterval nstimestamp, float zOffset, const CGPoint *point, float force,
float maximumPossibleForce, float azimuthAngleInView, float altitudeAngle, float rollAngle)
{
const SDL_PenID penId = UIKit_AddPenIfNecesary();
const SDL_PenID penId = UIKit_AddPenIfNecesary(window);
if (penId) {
const Uint64 timestamp = UIKit_GetEventTimestamp(nstimestamp);
const float radians_to_degrees = 180.0f / SDL_PI_F;
Expand Down Expand Up @@ -188,26 +188,28 @@ void UIKit_HandlePenMotion(SDL_uikitview *view, UITouch *pencil)

void UIKit_HandlePenPress(SDL_uikitview *view, UITouch *pencil)
{
const SDL_PenID penId = UIKit_AddPenIfNecesary();
SDL_Window *window = [view getSDLWindow];
const SDL_PenID penId = UIKit_AddPenIfNecesary(window);
if (penId) {
UIKit_HandlePenAxesFromUITouch(view, pencil);
SDL_SendPenTouch(UIKit_GetEventTimestamp([pencil timestamp]), penId, [view getSDLWindow], false, true);
SDL_SendPenTouch(UIKit_GetEventTimestamp([pencil timestamp]), penId, window, false, true);
}
}

void UIKit_HandlePenRelease(SDL_uikitview *view, UITouch *pencil)
{
const SDL_PenID penId = UIKit_AddPenIfNecesary();
SDL_Window *window = [view getSDLWindow];
const SDL_PenID penId = UIKit_AddPenIfNecesary(window);
if (penId) {
SDL_SendPenTouch(UIKit_GetEventTimestamp([pencil timestamp]), penId, [view getSDLWindow], false, false);
SDL_SendPenTouch(UIKit_GetEventTimestamp([pencil timestamp]), penId, window, false, false);
UIKit_HandlePenAxesFromUITouch(view, pencil);
}
}

void UIKit_QuitPen(SDL_VideoDevice *_this)
{
if (apple_pencil_id) {
SDL_RemovePenDevice(0, apple_pencil_id);
SDL_RemovePenDevice(0, NULL, apple_pencil_id);
apple_pencil_id = 0;
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/video/wayland/SDL_waylandevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -3306,7 +3306,8 @@ static void tablet_tool_handle_removed(void *data, struct zwp_tablet_tool_v2 *to
{
SDL_WaylandPenTool *sdltool = (SDL_WaylandPenTool *) data;
if (sdltool->instance_id) {
SDL_RemovePenDevice(0, sdltool->instance_id);
SDL_Window *window = sdltool->focus ? sdltool->focus->sdlwindow : NULL;
SDL_RemovePenDevice(0, window, sdltool->instance_id);
}

Wayland_CursorStateRelease(&sdltool->cursor_state);
Expand Down Expand Up @@ -3439,7 +3440,7 @@ static void tablet_tool_handle_frame(void *data, struct zwp_tablet_tool_v2 *tool
if (sdltool->frame.have_proximity_in) {
SDL_assert(sdltool->instance_id == 0); // shouldn't be added at this point.
if (sdltool->info.subtype != SDL_PEN_TYPE_UNKNOWN) { // don't tell SDL about it if we don't know its role.
sdltool->instance_id = SDL_AddPenDevice(timestamp, NULL, &sdltool->info, sdltool);
sdltool->instance_id = SDL_AddPenDevice(timestamp, NULL, window, &sdltool->info, sdltool);
Wayland_TabletToolUpdateCursor(sdltool);
}
}
Expand Down Expand Up @@ -3487,7 +3488,7 @@ static void tablet_tool_handle_frame(void *data, struct zwp_tablet_tool_v2 *tool
if (sdltool->frame.have_proximity_out) {
sdltool->focus = NULL;
Wayland_TabletToolUpdateCursor(sdltool);
SDL_RemovePenDevice(timestamp, sdltool->instance_id);
SDL_RemovePenDevice(timestamp, window, sdltool->instance_id);
sdltool->instance_id = 0;
}

Expand Down Expand Up @@ -3656,7 +3657,7 @@ void Wayland_DisplayRemoveWindowReferencesFromSeats(SDL_VideoData *display, SDL_
tool->focus = NULL;
Wayland_TabletToolUpdateCursor(tool);
if (tool->instance_id) {
SDL_RemovePenDevice(0, tool->instance_id);
SDL_RemovePenDevice(0, window->sdlwindow, tool->instance_id);
tool->instance_id = 0;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/video/windows/SDL_windowsevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -1277,7 +1277,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
info.max_tilt = 90.0f;
info.num_buttons = 1;
info.subtype = SDL_PEN_TYPE_PENCIL;
SDL_AddPenDevice(0, NULL, &info, hpointer);
SDL_AddPenDevice(0, NULL, data->window, &info, hpointer);
returnCode = 0;
} break;

Expand All @@ -1293,7 +1293,7 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara

// if this just left the _window_, we don't care. If this is no longer visible to the tablet, time to remove it!
if ((msg == WM_POINTERCAPTURECHANGED) || !IS_POINTER_INCONTACT_WPARAM(wParam)) {
SDL_RemovePenDevice(WIN_GetEventTimestamp(), pen);
SDL_RemovePenDevice(WIN_GetEventTimestamp(), data->window, pen);
}
returnCode = 0;
} break;
Expand Down
4 changes: 2 additions & 2 deletions src/video/x11/SDL_x11pen.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ static X11_PenHandle *X11_MaybeAddPen(SDL_VideoDevice *_this, const XIDeviceInfo
handle->is_eraser = is_eraser;
handle->x11_deviceid = dev->deviceid;

handle->pen = SDL_AddPenDevice(0, dev->name, &peninfo, handle);
handle->pen = SDL_AddPenDevice(0, dev->name, NULL, &peninfo, handle);
if (!handle->pen) {
SDL_free(handle);
return NULL;
Expand Down Expand Up @@ -301,7 +301,7 @@ void X11_RemovePenByDeviceID(int deviceid)
{
X11_PenHandle *handle = X11_FindPenByDeviceID(deviceid);
if (handle) {
SDL_RemovePenDevice(0, handle->pen);
SDL_RemovePenDevice(0, NULL, handle->pen);
SDL_free(handle);
}
}
Expand Down
Loading