Skip to content

Commit 3ec0832

Browse files
authored
Merge pull request #3207 from pygame-community/ankith26-more-sdl3-2
Port key and mouse to SDL3
2 parents 146c43c + 634619b commit 3ec0832

File tree

3 files changed

+112
-7
lines changed

3 files changed

+112
-7
lines changed

src_c/key.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ pg_scancodewrapper_subscript(pgScancodeWrapper *self, PyObject *item)
8080
PyObject *adjustedvalue, *ret;
8181
if ((index = PyLong_AsLong(item)) == -1 && PyErr_Occurred())
8282
return NULL;
83+
#if SDL_VERSION_ATLEAST(3, 0, 0)
84+
index = SDL_GetScancodeFromKey(index, NULL);
85+
#else
8386
index = SDL_GetScancodeFromKey(index);
87+
#endif
8488
adjustedvalue = PyLong_FromLong(index);
8589
ret = PyTuple_Type.tp_as_mapping->mp_subscript((PyObject *)self,
8690
adjustedvalue);
@@ -163,7 +167,11 @@ static PyObject *
163167
key_get_pressed(PyObject *self, PyObject *_null)
164168
{
165169
int num_keys;
170+
#if SDL_VERSION_ATLEAST(3, 0, 0)
171+
const bool *key_state;
172+
#else
166173
const Uint8 *key_state;
174+
#endif
167175
PyObject *ret_obj = NULL;
168176
PyObject *key_tuple;
169177
int i;
@@ -511,16 +519,42 @@ key_get_focused(PyObject *self, PyObject *_null)
511519
static PyObject *
512520
key_start_text_input(PyObject *self, PyObject *_null)
513521
{
522+
#if SDL_VERSION_ATLEAST(3, 0, 0)
523+
/* Can consider making this a method of the Window class, this function
524+
* just does backcompat */
525+
SDL_Window *win = pg_GetDefaultWindow();
526+
if (!win) {
527+
return RAISE(pgExc_SDLError,
528+
"display.set_mode has not been called yet.");
529+
}
530+
if (!SDL_StartTextInput(win)) {
531+
return RAISE(pgExc_SDLError, SDL_GetError());
532+
}
533+
#else
514534
/* https://wiki.libsdl.org/SDL_StartTextInput */
515535
SDL_StartTextInput();
536+
#endif
516537
Py_RETURN_NONE;
517538
}
518539

519540
static PyObject *
520541
key_stop_text_input(PyObject *self, PyObject *_null)
521542
{
543+
#if SDL_VERSION_ATLEAST(3, 0, 0)
544+
/* Can consider making this a method of the Window class, this function
545+
* just does backcompat */
546+
SDL_Window *win = pg_GetDefaultWindow();
547+
if (!win) {
548+
return RAISE(pgExc_SDLError,
549+
"display.set_mode has not been called yet.");
550+
}
551+
if (!SDL_StopTextInput(win)) {
552+
return RAISE(pgExc_SDLError, SDL_GetError());
553+
}
554+
#else
522555
/* https://wiki.libsdl.org/SDL_StopTextInput */
523556
SDL_StopTextInput();
557+
#endif
524558
Py_RETURN_NONE;
525559
}
526560

@@ -552,11 +586,23 @@ key_set_text_input_rect(PyObject *self, PyObject *obj)
552586
rect2.w = (int)(rect->w * scalex);
553587
rect2.h = (int)(rect->h * scaley);
554588

589+
#if SDL_VERSION_ATLEAST(3, 0, 0)
590+
/* Should consider how to expose the cursor argument to the user, maybe
591+
* this should be new API in Window? */
592+
SDL_SetTextInputArea(sdlWindow, &rect2, 0);
593+
#else
555594
SDL_SetTextInputRect(&rect2);
595+
#endif
556596
Py_RETURN_NONE;
557597
}
558598

599+
#if SDL_VERSION_ATLEAST(3, 0, 0)
600+
/* Should consider how to expose the cursor argument to the user, maybe
601+
* this should be new API in Window? */
602+
SDL_SetTextInputArea(sdlWindow, rect, 0);
603+
#else
559604
SDL_SetTextInputRect(rect);
605+
#endif
560606

561607
Py_RETURN_NONE;
562608
}

src_c/meson.build

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ event = py.extension_module(
4848
subdir: pg,
4949
)
5050

51-
# TODO: support SDL3
52-
if sdl_api != 3
5351
key = py.extension_module(
5452
'key',
5553
'key.c',
@@ -58,10 +56,7 @@ key = py.extension_module(
5856
install: true,
5957
subdir: pg,
6058
)
61-
endif
6259

63-
# TODO: support SDL3
64-
if sdl_api != 3
6560
mouse = py.extension_module(
6661
'mouse',
6762
'mouse.c',
@@ -70,7 +65,6 @@ mouse = py.extension_module(
7065
install: true,
7166
subdir: pg,
7267
)
73-
endif
7468

7569
rect = py.extension_module(
7670
'rect',

src_c/mouse.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,14 @@ mouse_set_pos(PyObject *self, PyObject *args)
6565
static PyObject *
6666
mouse_get_pos(PyObject *self, PyObject *args, PyObject *kwargs)
6767
{
68+
#if SDL_VERSION_ATLEAST(3, 0, 0)
69+
/* SDL3 changed the mouse API to deal with float coordinates, for now we
70+
* still truncate the result to int before returning to python side.
71+
* This can be changed in a breaking release in the future if needed. */
72+
float x, y;
73+
#else
6874
int x, y;
75+
#endif
6976
int desktop = 0;
7077

7178
static char *kwids[] = {"desktop", NULL};
@@ -90,12 +97,27 @@ mouse_get_pos(PyObject *self, PyObject *args, PyObject *kwargs)
9097
SDL_RenderGetScale(sdlRenderer, &scalex, &scaley);
9198
SDL_RenderGetViewport(sdlRenderer, &vprect);
9299

100+
#if SDL_VERSION_ATLEAST(3, 0, 0)
101+
x = x / scalex;
102+
y = y / scaley;
103+
#else
93104
x = (int)(x / scalex);
94105
y = (int)(y / scaley);
106+
#endif
95107

96108
x -= vprect.x;
97109
y -= vprect.y;
98110

111+
#if SDL_VERSION_ATLEAST(3, 0, 0)
112+
if (x < 0)
113+
x = 0;
114+
if (x >= vprect.w)
115+
x = (float)vprect.w - 1;
116+
if (y < 0)
117+
y = 0;
118+
if (y >= vprect.h)
119+
y = (float)vprect.h - 1;
120+
#else
99121
if (x < 0)
100122
x = 0;
101123
if (x >= vprect.w)
@@ -104,17 +126,29 @@ mouse_get_pos(PyObject *self, PyObject *args, PyObject *kwargs)
104126
y = 0;
105127
if (y >= vprect.h)
106128
y = vprect.h - 1;
129+
#endif
107130
}
108131
}
109132
}
110133

134+
#if SDL_VERSION_ATLEAST(3, 0, 0)
135+
return pg_tuple_couple_from_values_int((int)x, (int)y);
136+
#else
111137
return pg_tuple_couple_from_values_int(x, y);
138+
#endif
112139
}
113140

114141
static PyObject *
115142
mouse_get_rel(PyObject *self, PyObject *_null)
116143
{
144+
#if SDL_VERSION_ATLEAST(3, 0, 0)
145+
/* SDL3 changed the mouse API to deal with float coordinates, for now we
146+
* still truncate the result to int before returning to python side.
147+
* This can be changed in a breaking release in the future if needed. */
148+
float x, y;
149+
#else
117150
int x, y;
151+
#endif
118152

119153
VIDEO_INIT_CHECK();
120154

@@ -132,7 +166,11 @@ mouse_get_rel(PyObject *self, PyObject *_null)
132166
y/=scaley;
133167
}
134168
*/
169+
#if SDL_VERSION_ATLEAST(3, 0, 0)
170+
return pg_tuple_couple_from_values_int((int)x, (int)y);
171+
#else
135172
return pg_tuple_couple_from_values_int(x, y);
173+
#endif
136174
}
137175

138176
static PyObject *
@@ -216,21 +254,26 @@ mouse_set_visible(PyObject *self, PyObject *args)
216254
{
217255
int toggle, prevstate;
218256
SDL_Window *win = NULL;
219-
Uint32 window_flags = 0;
257+
SDL_WindowFlags window_flags = 0;
220258

221259
if (!PyArg_ParseTuple(args, "i", &toggle))
222260
return NULL;
223261
VIDEO_INIT_CHECK();
224262

225263
win = pg_GetDefaultWindow();
226264
if (win) {
265+
#if SDL_VERSION_ATLEAST(3, 0, 0)
266+
SDL_SetWindowRelativeMouseMode(win,
267+
SDL_GetWindowMouseGrab(win) && !toggle);
268+
#else
227269
int mode = SDL_GetWindowGrab(win);
228270
if ((mode == SDL_ENABLE) & !toggle) {
229271
SDL_SetRelativeMouseMode(1);
230272
}
231273
else {
232274
SDL_SetRelativeMouseMode(0);
233275
}
276+
#endif
234277
window_flags = SDL_GetWindowFlags(win);
235278
if (!toggle && (window_flags & PG_WINDOW_FULLSCREEN_INCLUSIVE)) {
236279
SDL_SetHint(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, "0");
@@ -263,7 +306,13 @@ mouse_get_visible(PyObject *self, PyObject *_null)
263306

264307
VIDEO_INIT_CHECK();
265308

309+
#if SDL_VERSION_ATLEAST(3, 0, 0)
310+
SDL_Window *win = pg_GetDefaultWindow();
311+
result =
312+
win ? (PG_CursorVisible() && !SDL_GetWindowRelativeMouseMode(win)) : 0;
313+
#else
266314
result = (PG_CursorVisible() && !SDL_GetRelativeMouseMode());
315+
#endif
267316

268317
if (0 > result) {
269318
return RAISE(pgExc_SDLError, SDL_GetError());
@@ -527,7 +576,12 @@ mouse_get_cursor(PyObject *self, PyObject *_null)
527576
static PyObject *
528577
mouse_get_relative_mode(PyObject *self)
529578
{
579+
#if SDL_VERSION_ATLEAST(3, 0, 0)
580+
SDL_Window *win = pg_GetDefaultWindow();
581+
return PyBool_FromLong(win ? SDL_GetWindowRelativeMouseMode(win) : 0);
582+
#else
530583
return PyBool_FromLong(SDL_GetRelativeMouseMode());
584+
#endif
531585
}
532586

533587
static PyObject *
@@ -537,9 +591,20 @@ mouse_set_relative_mode(PyObject *self, PyObject *arg)
537591
if (mode == -1) {
538592
return NULL;
539593
}
594+
#if SDL_VERSION_ATLEAST(3, 0, 0)
595+
SDL_Window *win = pg_GetDefaultWindow();
596+
if (!win) {
597+
return RAISE(pgExc_SDLError,
598+
"display.set_mode has not been called yet.");
599+
}
600+
if (!SDL_SetWindowRelativeMouseMode(win, (bool)mode)) {
601+
return RAISE(pgExc_SDLError, SDL_GetError());
602+
}
603+
#else
540604
if (SDL_SetRelativeMouseMode((SDL_bool)mode)) {
541605
return RAISE(pgExc_SDLError, SDL_GetError());
542606
}
607+
#endif
543608
Py_RETURN_NONE;
544609
}
545610

0 commit comments

Comments
 (0)