Skip to content

Commit 2e0c6bd

Browse files
committed
SDL3: event: runtime issue fixes
1 parent 4efba9a commit 2e0c6bd

File tree

4 files changed

+1020
-35
lines changed

4 files changed

+1020
-35
lines changed

src_c/_pygame.h

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@
5050
#include "stdbool.h"
5151

5252
#if SDL_VERSION_ATLEAST(3, 0, 0)
53+
54+
#include "include/SDL_gesture.h"
55+
56+
#define SDL_DOLLARGESTURE GESTURE_DOLLARGESTURE
57+
#define SDL_DOLLARRECORD GESTURE_DOLLARRECORD
58+
#define SDL_MULTIGESTURE GESTURE_MULTIGESTURE
59+
5360
#define PG_ShowCursor SDL_ShowCursor
5461
#define PG_HideCursor SDL_HideCursor
5562
#define PG_CursorVisible SDL_CursorVisible
@@ -68,12 +75,6 @@
6875
#define PG_AUDIO_ALLOW_CHANNELS_CHANGE 0
6976
#define PG_AUDIO_ALLOW_ANY_CHANGE 0
7077

71-
// Todo: deal with multigesture.. See
72-
// https://github.com/pygame-community/pygame-ce/issues/2420
73-
#define PG_MULTIGESTURE 0
74-
75-
#define PG_JOYBALLMOTION 0
76-
7778
#define PG_CreateSurface SDL_CreateSurface
7879
#define PG_CreateSurfaceFrom SDL_CreateSurfaceFrom
7980
#define PG_ConvertSurface SDL_ConvertSurface
@@ -208,10 +209,6 @@ PG_GetSurfaceFormat(SDL_Surface *surf)
208209
#define PG_AUDIO_ALLOW_CHANNELS_CHANGE SDL_AUDIO_ALLOW_CHANNELS_CHANGE
209210
#define PG_AUDIO_ALLOW_ANY_CHANGE SDL_AUDIO_ALLOW_ANY_CHANGE
210211

211-
#define PG_MULTIGESTURE SDL_MULTIGESTURE
212-
213-
#define PG_JOYBALLMOTION SDL_JOYBALLMOTION
214-
215212
#define PG_CreateSurface(width, height, format) \
216213
SDL_CreateRGBSurfaceWithFormat(0, width, height, 0, format)
217214
#define PG_CreateSurfaceFrom(width, height, format, pixels, pitch) \
@@ -450,6 +447,40 @@ typedef enum {
450447
PGM_BUTTON_KEEP = 0x80
451448
} PygameMouseFlags;
452449

450+
#if SDL_VERSION_ATLEAST(3, 0, 0)
451+
typedef enum {
452+
PGE_WINDOWSHOWN = SDL_EVENT_WINDOW_SHOWN,
453+
PGE_WINDOWHIDDEN = SDL_EVENT_WINDOW_HIDDEN,
454+
PGE_WINDOWEXPOSED = SDL_EVENT_WINDOW_EXPOSED,
455+
PGE_WINDOWMOVED = SDL_EVENT_WINDOW_MOVED,
456+
PGE_WINDOWRESIZED = SDL_EVENT_WINDOW_RESIZED,
457+
PGE_WINDOWSIZECHANGED = SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED,
458+
PGE_WINDOWMINIMIZED = SDL_EVENT_WINDOW_MINIMIZED,
459+
PGE_WINDOWMAXIMIZED = SDL_EVENT_WINDOW_MAXIMIZED,
460+
PGE_WINDOWRESTORED = SDL_EVENT_WINDOW_RESTORED,
461+
PGE_WINDOWENTER = SDL_EVENT_WINDOW_MOUSE_ENTER,
462+
PGE_WINDOWLEAVE = SDL_EVENT_WINDOW_MOUSE_LEAVE,
463+
PGE_WINDOWFOCUSGAINED = SDL_EVENT_WINDOW_FOCUS_GAINED,
464+
PGE_WINDOWFOCUSLOST = SDL_EVENT_WINDOW_FOCUS_LOST,
465+
PGE_WINDOWCLOSE = SDL_EVENT_WINDOW_CLOSE_REQUESTED,
466+
PGE_WINDOWTAKEFOCUS = -1, /* No SDL3 equivalent */
467+
PGE_WINDOWHITTEST = SDL_EVENT_WINDOW_HIT_TEST,
468+
PGE_WINDOWICCPROFCHANGED = SDL_EVENT_WINDOW_ICCPROF_CHANGED,
469+
PGE_WINDOWDISPLAYCHANGED = SDL_EVENT_WINDOW_DISPLAY_CHANGED,
470+
} PygameWindowEventCode;
471+
/*
472+
TODO: expose these window events in pygame API
473+
SDL_EVENT_WINDOW_METAL_VIEW_RESIZED,
474+
SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED,
475+
SDL_EVENT_WINDOW_SAFE_AREA_CHANGED,
476+
SDL_EVENT_WINDOW_OCCLUDED,
477+
SDL_EVENT_WINDOW_ENTER_FULLSCREEN,
478+
SDL_EVENT_WINDOW_LEAVE_FULLSCREEN,
479+
SDL_EVENT_WINDOW_DESTROYED,
480+
SDL_EVENT_WINDOW_HDR_STATE_CHANGED,
481+
*/
482+
#endif
483+
453484
typedef enum {
454485
/* Any SDL_* events here are for backward compatibility. */
455486
SDL_NOEVENT = 0,
@@ -465,6 +496,9 @@ typedef enum {
465496
PGE_MIDIIN,
466497
PGE_MIDIOUT,
467498

499+
/* These PGE events are only needed on SDL2: SDL3 has dedicated events for
500+
* these */
501+
#if !SDL_VERSION_ATLEAST(3, 0, 0)
468502
/* DO NOT CHANGE THE ORDER OF EVENTS HERE */
469503
PGE_WINDOWSHOWN,
470504
PGE_WINDOWHIDDEN,
@@ -484,6 +518,7 @@ typedef enum {
484518
PGE_WINDOWHITTEST,
485519
PGE_WINDOWICCPROFCHANGED,
486520
PGE_WINDOWDISPLAYCHANGED,
521+
#endif
487522

488523
/* Here we define PGPOST_* events, events that act as a one-to-one
489524
* proxy for SDL events (and some extra events too!), the proxy is used
@@ -519,10 +554,8 @@ typedef enum {
519554
PGPOST_CONTROLLERTOUCHPADMOTION,
520555
PGPOST_CONTROLLERTOUCHPADUP,
521556
PGPOST_CONTROLLERSENSORUPDATE,
522-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
523557
PGPOST_DOLLARGESTURE,
524558
PGPOST_DOLLARRECORD,
525-
#endif
526559
PGPOST_DROPFILE,
527560
PGPOST_DROPTEXT,
528561
PGPOST_DROPBEGIN,
@@ -547,9 +580,7 @@ typedef enum {
547580
PGPOST_MOUSEBUTTONDOWN,
548581
PGPOST_MOUSEBUTTONUP,
549582
PGPOST_MOUSEWHEEL,
550-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
551583
PGPOST_MULTIGESTURE,
552-
#endif
553584
PGPOST_NOEVENT,
554585
PGPOST_QUIT,
555586
PGPOST_RENDER_TARGETS_RESET,

src_c/constants.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ MODINIT_DEFINE(constants)
260260
DEC_CONST(MOUSEBUTTONDOWN);
261261
DEC_CONST(MOUSEBUTTONUP);
262262
DEC_CONST(JOYAXISMOTION);
263-
DEC_CONSTS(JOYBALLMOTION, PG_JOYBALLMOTION);
263+
DEC_CONST(JOYBALLMOTION);
264264
DEC_CONST(JOYHATMOTION);
265265
DEC_CONST(JOYBUTTONDOWN);
266266
DEC_CONST(JOYBUTTONUP);
@@ -302,7 +302,7 @@ MODINIT_DEFINE(constants)
302302
DEC_CONST(FINGERMOTION);
303303
DEC_CONST(FINGERDOWN);
304304
DEC_CONST(FINGERUP);
305-
DEC_CONSTS(MULTIGESTURE, PG_MULTIGESTURE);
305+
DEC_CONST(MULTIGESTURE);
306306
DEC_CONST(AUDIODEVICEADDED);
307307
DEC_CONST(AUDIODEVICEREMOVED);
308308
DEC_CONST(MOUSEWHEEL);

src_c/event.c

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*/
2626
#define PYGAMEAPI_EVENT_INTERNAL
2727

28+
#define SDL_GESTURE_IMPLEMENTATION 1
2829
#include "pygame.h"
2930

3031
#include "pgcompat.h"
@@ -401,10 +402,8 @@ _pg_pgevent_proxify_helper(Uint32 type, Uint8 proxify)
401402
_PG_HANDLE_PROXIFY(CONTROLLERTOUCHPADMOTION);
402403
_PG_HANDLE_PROXIFY(CONTROLLERTOUCHPADUP);
403404
_PG_HANDLE_PROXIFY(CONTROLLERSENSORUPDATE);
404-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
405405
_PG_HANDLE_PROXIFY(DOLLARGESTURE);
406406
_PG_HANDLE_PROXIFY(DOLLARRECORD);
407-
#endif
408407
_PG_HANDLE_PROXIFY(DROPFILE);
409408
_PG_HANDLE_PROXIFY(DROPTEXT);
410409
_PG_HANDLE_PROXIFY(DROPBEGIN);
@@ -427,9 +426,7 @@ _pg_pgevent_proxify_helper(Uint32 type, Uint8 proxify)
427426
_PG_HANDLE_PROXIFY(MOUSEBUTTONDOWN);
428427
_PG_HANDLE_PROXIFY(MOUSEBUTTONUP);
429428
_PG_HANDLE_PROXIFY(MOUSEWHEEL);
430-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
431429
_PG_HANDLE_PROXIFY(MULTIGESTURE);
432-
#endif
433430
_PG_HANDLE_PROXIFY(NOEVENT);
434431
_PG_HANDLE_PROXIFY(QUIT);
435432
_PG_HANDLE_PROXIFY(RENDER_TARGETS_RESET);
@@ -493,19 +490,28 @@ _pg_pgevent_type(SDL_Event *event)
493490
* Currently this only includes WINDOWEVENT, but can be expanded in the
494491
* future.
495492
*/
496-
#if SDL_VERSION_ATLEAST(3, 0, 0)
497-
static bool SDLCALL
498-
#else
499-
static int SDLCALL
500-
#endif
501-
_pg_filter_blocked_events(void *_, SDL_Event *event)
493+
static bool
494+
_pg_event_psuedo_block(SDL_Event *event)
502495
{
503496
#if SDL_VERSION_ATLEAST(3, 0, 0)
504497
if (event->type >= SDL_EVENT_WINDOW_FIRST &&
505498
event->type <= SDL_EVENT_WINDOW_LAST) {
506499
#else
507500
if (event->type == SDL_WINDOWEVENT) {
508501
#endif
502+
return true;
503+
}
504+
return false;
505+
}
506+
507+
#if SDL_VERSION_ATLEAST(3, 0, 0)
508+
static bool SDLCALL
509+
#else
510+
static int SDLCALL
511+
#endif
512+
_pg_filter_blocked_events(void *_, SDL_Event *event)
513+
{
514+
if (_pg_event_psuedo_block(event)) {
509515
return PG_EventEnabled(_pg_pgevent_proxify(_pg_pgevent_type(event)));
510516
}
511517
return 1;
@@ -732,14 +738,15 @@ pg_event_filter(void *_, SDL_Event *event)
732738
return RAISE(pgExc_SDLError, SDL_GetError()), 0;
733739
*/
734740
}
735-
/* TODO:
741+
/*
736742
* Any event that gets blocked here will not be visible to the event
737743
* watchers. So things like WINDOWEVENT should never be blocked here.
738-
* This is taken care of in SDL2 codepaths already but needs to also
739-
* be verified in SDL3 porting.
740744
* If the user requests a block on WINDOWEVENTs we are going to handle
741745
* it specially and call it a "pseudo-block", where the filtering will
742746
* happen in a _pg_filter_blocked_events call. */
747+
if (_pg_event_psuedo_block(event)) {
748+
return 1;
749+
}
743750
return PG_EventEnabled(_pg_pgevent_proxify(event->type));
744751
}
745752

@@ -773,6 +780,9 @@ static PyObject *
773780
pgEvent_AutoQuit(PyObject *self, PyObject *_null)
774781
{
775782
if (_pg_event_is_init) {
783+
#if SDL_VERSION_ATLEAST(3, 0, 0)
784+
Gesture_Quit();
785+
#endif
776786
PG_LOCK_EVFILTER_MUTEX
777787
if (_pg_repeat_timer) {
778788
SDL_RemoveTimer(_pg_repeat_timer);
@@ -805,6 +815,11 @@ pgEvent_AutoInit(PyObject *self, PyObject *_null)
805815
}
806816
#endif
807817
SDL_SetEventFilter(pg_event_filter, NULL);
818+
#if SDL_VERSION_ATLEAST(3, 0, 0)
819+
if (Gesture_Init() != 0) {
820+
return RAISE(pgExc_SDLError, SDL_GetError());
821+
}
822+
#endif
808823
}
809824
_pg_event_is_init = 1;
810825
Py_RETURN_NONE;
@@ -936,10 +951,8 @@ _pg_name_from_eventtype(int type)
936951
return "FingerDown";
937952
case SDL_FINGERUP:
938953
return "FingerUp";
939-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
940954
case SDL_MULTIGESTURE:
941955
return "MultiGesture";
942-
#endif
943956
case SDL_MOUSEWHEEL:
944957
return "MouseWheel";
945958
case SDL_TEXTINPUT:
@@ -1142,7 +1155,6 @@ dict_from_event(SDL_Event *event)
11421155
state = SDL_APPACTIVE;
11431156
break;
11441157
default:
1145-
assert(event->window.event == SDL_WINDOWEVENT_RESTORED);
11461158
gain = 1;
11471159
state = SDL_APPACTIVE;
11481160
}
@@ -1294,9 +1306,27 @@ dict_from_event(SDL_Event *event)
12941306
_pg_insobj(dict, "pressure",
12951307
PyFloat_FromDouble(event->tfinger.dy));
12961308
break;
1297-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
12981309
case SDL_MULTIGESTURE:
1299-
/* https://wiki.libsdl.org/SDL_MultiGestureEvent */
1310+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1311+
_pg_insobj(dict, "touch_id",
1312+
PyLong_FromLongLong(
1313+
((Gesture_MultiGestureEvent *)event)->touchID));
1314+
_pg_insobj(
1315+
dict, "x",
1316+
PyFloat_FromDouble(((Gesture_MultiGestureEvent *)event)->x));
1317+
_pg_insobj(
1318+
dict, "y",
1319+
PyFloat_FromDouble(((Gesture_MultiGestureEvent *)event)->y));
1320+
_pg_insobj(dict, "rotated",
1321+
PyFloat_FromDouble(
1322+
((Gesture_MultiGestureEvent *)event)->dTheta));
1323+
_pg_insobj(dict, "pinched",
1324+
PyFloat_FromDouble(
1325+
((Gesture_MultiGestureEvent *)event)->dDist));
1326+
_pg_insobj(dict, "num_fingers",
1327+
PyLong_FromLong(
1328+
((Gesture_MultiGestureEvent *)event)->numFingers));
1329+
#else
13001330
_pg_insobj(dict, "touch_id",
13011331
PyLong_FromLongLong(event->mgesture.touchId));
13021332
_pg_insobj(dict, "x", PyFloat_FromDouble(event->mgesture.x));
@@ -1307,8 +1337,8 @@ dict_from_event(SDL_Event *event)
13071337
PyFloat_FromDouble(event->mgesture.dDist));
13081338
_pg_insobj(dict, "num_fingers",
13091339
PyLong_FromLong(event->mgesture.numFingers));
1310-
break;
13111340
#endif
1341+
break;
13121342
case SDL_MOUSEWHEEL:
13131343
/* https://wiki.libsdl.org/SDL_MouseWheelEvent */
13141344
#ifndef NO_SDL_MOUSEWHEEL_FLIPPED

0 commit comments

Comments
 (0)