Skip to content

Commit 634619b

Browse files
committed
Port mouse.c to SDL3
1 parent 262a407 commit 634619b

File tree

2 files changed

+66
-4
lines changed

2 files changed

+66
-4
lines changed

src_c/meson.build

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ key = py.extension_module(
5757
subdir: pg,
5858
)
5959

60-
# TODO: support SDL3
61-
if sdl_api != 3
6260
mouse = py.extension_module(
6361
'mouse',
6462
'mouse.c',
@@ -67,7 +65,6 @@ mouse = py.extension_module(
6765
install: true,
6866
subdir: pg,
6967
)
70-
endif
7168

7269
rect = py.extension_module(
7370
'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)