Skip to content

Commit 16d89cf

Browse files
committed
SDL3: event: runtime issue fixes
1 parent 6f9bfbe commit 16d89cf

File tree

4 files changed

+1024
-35
lines changed

4 files changed

+1024
-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: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
*/
2626
#define PYGAMEAPI_EVENT_INTERNAL
2727

28+
/* We include SDL_gesture.h in _pygame.h. That header defines the
29+
* implementation when this macro is set. So this macro needs to be set in only
30+
* one source file (and not any header) and we set it here because its API is
31+
* used here */
32+
#define SDL_GESTURE_IMPLEMENTATION 1
2833
#include "pygame.h"
2934

3035
#include "pgcompat.h"
@@ -401,10 +406,8 @@ _pg_pgevent_proxify_helper(Uint32 type, Uint8 proxify)
401406
_PG_HANDLE_PROXIFY(CONTROLLERTOUCHPADMOTION);
402407
_PG_HANDLE_PROXIFY(CONTROLLERTOUCHPADUP);
403408
_PG_HANDLE_PROXIFY(CONTROLLERSENSORUPDATE);
404-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
405409
_PG_HANDLE_PROXIFY(DOLLARGESTURE);
406410
_PG_HANDLE_PROXIFY(DOLLARRECORD);
407-
#endif
408411
_PG_HANDLE_PROXIFY(DROPFILE);
409412
_PG_HANDLE_PROXIFY(DROPTEXT);
410413
_PG_HANDLE_PROXIFY(DROPBEGIN);
@@ -427,9 +430,7 @@ _pg_pgevent_proxify_helper(Uint32 type, Uint8 proxify)
427430
_PG_HANDLE_PROXIFY(MOUSEBUTTONDOWN);
428431
_PG_HANDLE_PROXIFY(MOUSEBUTTONUP);
429432
_PG_HANDLE_PROXIFY(MOUSEWHEEL);
430-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
431433
_PG_HANDLE_PROXIFY(MULTIGESTURE);
432-
#endif
433434
_PG_HANDLE_PROXIFY(NOEVENT);
434435
_PG_HANDLE_PROXIFY(QUIT);
435436
_PG_HANDLE_PROXIFY(RENDER_TARGETS_RESET);
@@ -493,19 +494,28 @@ _pg_pgevent_type(SDL_Event *event)
493494
* Currently this only includes WINDOWEVENT, but can be expanded in the
494495
* future.
495496
*/
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)
497+
static bool
498+
_pg_event_psuedo_block(SDL_Event *event)
502499
{
503500
#if SDL_VERSION_ATLEAST(3, 0, 0)
504501
if (event->type >= SDL_EVENT_WINDOW_FIRST &&
505502
event->type <= SDL_EVENT_WINDOW_LAST) {
506503
#else
507504
if (event->type == SDL_WINDOWEVENT) {
508505
#endif
506+
return true;
507+
}
508+
return false;
509+
}
510+
511+
#if SDL_VERSION_ATLEAST(3, 0, 0)
512+
static bool SDLCALL
513+
#else
514+
static int SDLCALL
515+
#endif
516+
_pg_filter_blocked_events(void *_, SDL_Event *event)
517+
{
518+
if (_pg_event_psuedo_block(event)) {
509519
return PG_EventEnabled(_pg_pgevent_proxify(_pg_pgevent_type(event)));
510520
}
511521
return 1;
@@ -732,14 +742,15 @@ pg_event_filter(void *_, SDL_Event *event)
732742
return RAISE(pgExc_SDLError, SDL_GetError()), 0;
733743
*/
734744
}
735-
/* TODO:
745+
/*
736746
* Any event that gets blocked here will not be visible to the event
737747
* 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.
740748
* If the user requests a block on WINDOWEVENTs we are going to handle
741749
* it specially and call it a "pseudo-block", where the filtering will
742750
* happen in a _pg_filter_blocked_events call. */
751+
if (_pg_event_psuedo_block(event)) {
752+
return 1;
753+
}
743754
return PG_EventEnabled(_pg_pgevent_proxify(event->type));
744755
}
745756

@@ -773,6 +784,9 @@ static PyObject *
773784
pgEvent_AutoQuit(PyObject *self, PyObject *_null)
774785
{
775786
if (_pg_event_is_init) {
787+
#if SDL_VERSION_ATLEAST(3, 0, 0)
788+
Gesture_Quit();
789+
#endif
776790
PG_LOCK_EVFILTER_MUTEX
777791
if (_pg_repeat_timer) {
778792
SDL_RemoveTimer(_pg_repeat_timer);
@@ -805,6 +819,11 @@ pgEvent_AutoInit(PyObject *self, PyObject *_null)
805819
}
806820
#endif
807821
SDL_SetEventFilter(pg_event_filter, NULL);
822+
#if SDL_VERSION_ATLEAST(3, 0, 0)
823+
if (Gesture_Init() != 0) {
824+
return RAISE(pgExc_SDLError, SDL_GetError());
825+
}
826+
#endif
808827
}
809828
_pg_event_is_init = 1;
810829
Py_RETURN_NONE;
@@ -936,10 +955,8 @@ _pg_name_from_eventtype(int type)
936955
return "FingerDown";
937956
case SDL_FINGERUP:
938957
return "FingerUp";
939-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
940958
case SDL_MULTIGESTURE:
941959
return "MultiGesture";
942-
#endif
943960
case SDL_MOUSEWHEEL:
944961
return "MouseWheel";
945962
case SDL_TEXTINPUT:
@@ -1142,7 +1159,6 @@ dict_from_event(SDL_Event *event)
11421159
state = SDL_APPACTIVE;
11431160
break;
11441161
default:
1145-
assert(event->window.event == SDL_WINDOWEVENT_RESTORED);
11461162
gain = 1;
11471163
state = SDL_APPACTIVE;
11481164
}
@@ -1294,9 +1310,27 @@ dict_from_event(SDL_Event *event)
12941310
_pg_insobj(dict, "pressure",
12951311
PyFloat_FromDouble(event->tfinger.dy));
12961312
break;
1297-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
12981313
case SDL_MULTIGESTURE:
1299-
/* https://wiki.libsdl.org/SDL_MultiGestureEvent */
1314+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1315+
_pg_insobj(dict, "touch_id",
1316+
PyLong_FromLongLong(
1317+
((Gesture_MultiGestureEvent *)event)->touchID));
1318+
_pg_insobj(
1319+
dict, "x",
1320+
PyFloat_FromDouble(((Gesture_MultiGestureEvent *)event)->x));
1321+
_pg_insobj(
1322+
dict, "y",
1323+
PyFloat_FromDouble(((Gesture_MultiGestureEvent *)event)->y));
1324+
_pg_insobj(dict, "rotated",
1325+
PyFloat_FromDouble(
1326+
((Gesture_MultiGestureEvent *)event)->dTheta));
1327+
_pg_insobj(dict, "pinched",
1328+
PyFloat_FromDouble(
1329+
((Gesture_MultiGestureEvent *)event)->dDist));
1330+
_pg_insobj(dict, "num_fingers",
1331+
PyLong_FromLong(
1332+
((Gesture_MultiGestureEvent *)event)->numFingers));
1333+
#else
13001334
_pg_insobj(dict, "touch_id",
13011335
PyLong_FromLongLong(event->mgesture.touchId));
13021336
_pg_insobj(dict, "x", PyFloat_FromDouble(event->mgesture.x));
@@ -1307,8 +1341,8 @@ dict_from_event(SDL_Event *event)
13071341
PyFloat_FromDouble(event->mgesture.dDist));
13081342
_pg_insobj(dict, "num_fingers",
13091343
PyLong_FromLong(event->mgesture.numFingers));
1310-
break;
13111344
#endif
1345+
break;
13121346
case SDL_MOUSEWHEEL:
13131347
/* https://wiki.libsdl.org/SDL_MouseWheelEvent */
13141348
#ifndef NO_SDL_MOUSEWHEEL_FLIPPED

0 commit comments

Comments
 (0)