Skip to content

Commit 138b114

Browse files
committed
SDL3: event: runtime issue fixes
1 parent a88e23b commit 138b114

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
@@ -183,10 +184,6 @@ PG_GetSurfaceFormat(SDL_Surface *surf)
183184
#define PG_AUDIO_ALLOW_CHANNELS_CHANGE SDL_AUDIO_ALLOW_CHANNELS_CHANGE
184185
#define PG_AUDIO_ALLOW_ANY_CHANGE SDL_AUDIO_ALLOW_ANY_CHANGE
185186

186-
#define PG_MULTIGESTURE SDL_MULTIGESTURE
187-
188-
#define PG_JOYBALLMOTION SDL_JOYBALLMOTION
189-
190187
#define PG_CreateSurface(width, height, format) \
191188
SDL_CreateRGBSurfaceWithFormat(0, width, height, 0, format)
192189
#define PG_CreateSurfaceFrom(width, height, format, pixels, pitch) \
@@ -425,6 +422,40 @@ typedef enum {
425422
PGM_BUTTON_KEEP = 0x80
426423
} PygameMouseFlags;
427424

425+
#if SDL_VERSION_ATLEAST(3, 0, 0)
426+
typedef enum {
427+
PGE_WINDOWSHOWN = SDL_EVENT_WINDOW_SHOWN,
428+
PGE_WINDOWHIDDEN = SDL_EVENT_WINDOW_HIDDEN,
429+
PGE_WINDOWEXPOSED = SDL_EVENT_WINDOW_EXPOSED,
430+
PGE_WINDOWMOVED = SDL_EVENT_WINDOW_MOVED,
431+
PGE_WINDOWRESIZED = SDL_EVENT_WINDOW_RESIZED,
432+
PGE_WINDOWSIZECHANGED = SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED,
433+
PGE_WINDOWMINIMIZED = SDL_EVENT_WINDOW_MINIMIZED,
434+
PGE_WINDOWMAXIMIZED = SDL_EVENT_WINDOW_MAXIMIZED,
435+
PGE_WINDOWRESTORED = SDL_EVENT_WINDOW_RESTORED,
436+
PGE_WINDOWENTER = SDL_EVENT_WINDOW_MOUSE_ENTER,
437+
PGE_WINDOWLEAVE = SDL_EVENT_WINDOW_MOUSE_LEAVE,
438+
PGE_WINDOWFOCUSGAINED = SDL_EVENT_WINDOW_FOCUS_GAINED,
439+
PGE_WINDOWFOCUSLOST = SDL_EVENT_WINDOW_FOCUS_LOST,
440+
PGE_WINDOWCLOSE = SDL_EVENT_WINDOW_CLOSE_REQUESTED,
441+
PGE_WINDOWTAKEFOCUS = -1, /* No SDL3 equivalent */
442+
PGE_WINDOWHITTEST = SDL_EVENT_WINDOW_HIT_TEST,
443+
PGE_WINDOWICCPROFCHANGED = SDL_EVENT_WINDOW_ICCPROF_CHANGED,
444+
PGE_WINDOWDISPLAYCHANGED = SDL_EVENT_WINDOW_DISPLAY_CHANGED,
445+
} PygameWindowEventCode;
446+
/*
447+
TODO: expose these window events in pygame API
448+
SDL_EVENT_WINDOW_METAL_VIEW_RESIZED,
449+
SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED,
450+
SDL_EVENT_WINDOW_SAFE_AREA_CHANGED,
451+
SDL_EVENT_WINDOW_OCCLUDED,
452+
SDL_EVENT_WINDOW_ENTER_FULLSCREEN,
453+
SDL_EVENT_WINDOW_LEAVE_FULLSCREEN,
454+
SDL_EVENT_WINDOW_DESTROYED,
455+
SDL_EVENT_WINDOW_HDR_STATE_CHANGED,
456+
*/
457+
#endif
458+
428459
typedef enum {
429460
/* Any SDL_* events here are for backward compatibility. */
430461
SDL_NOEVENT = 0,
@@ -440,6 +471,9 @@ typedef enum {
440471
PGE_MIDIIN,
441472
PGE_MIDIOUT,
442473

474+
/* These PGE events are only needed on SDL2: SDL3 has dedicated events for
475+
* these */
476+
#if !SDL_VERSION_ATLEAST(3, 0, 0)
443477
/* DO NOT CHANGE THE ORDER OF EVENTS HERE */
444478
PGE_WINDOWSHOWN,
445479
PGE_WINDOWHIDDEN,
@@ -459,6 +493,7 @@ typedef enum {
459493
PGE_WINDOWHITTEST,
460494
PGE_WINDOWICCPROFCHANGED,
461495
PGE_WINDOWDISPLAYCHANGED,
496+
#endif
462497

463498
/* Here we define PGPOST_* events, events that act as a one-to-one
464499
* proxy for SDL events (and some extra events too!), the proxy is used
@@ -494,10 +529,8 @@ typedef enum {
494529
PGPOST_CONTROLLERTOUCHPADMOTION,
495530
PGPOST_CONTROLLERTOUCHPADUP,
496531
PGPOST_CONTROLLERSENSORUPDATE,
497-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
498532
PGPOST_DOLLARGESTURE,
499533
PGPOST_DOLLARRECORD,
500-
#endif
501534
PGPOST_DROPFILE,
502535
PGPOST_DROPTEXT,
503536
PGPOST_DROPBEGIN,
@@ -522,9 +555,7 @@ typedef enum {
522555
PGPOST_MOUSEBUTTONDOWN,
523556
PGPOST_MOUSEBUTTONUP,
524557
PGPOST_MOUSEWHEEL,
525-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
526558
PGPOST_MULTIGESTURE,
527-
#endif
528559
PGPOST_NOEVENT,
529560
PGPOST_QUIT,
530561
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)