diff --git a/src_c/key.c b/src_c/key.c index 44ea2457c2..3de4387839 100644 --- a/src_c/key.c +++ b/src_c/key.c @@ -80,7 +80,11 @@ pg_scancodewrapper_subscript(pgScancodeWrapper *self, PyObject *item) PyObject *adjustedvalue, *ret; if ((index = PyLong_AsLong(item)) == -1 && PyErr_Occurred()) return NULL; +#if SDL_VERSION_ATLEAST(3, 0, 0) + index = SDL_GetScancodeFromKey(index, NULL); +#else index = SDL_GetScancodeFromKey(index); +#endif adjustedvalue = PyLong_FromLong(index); ret = PyTuple_Type.tp_as_mapping->mp_subscript((PyObject *)self, adjustedvalue); @@ -163,7 +167,11 @@ static PyObject * key_get_pressed(PyObject *self, PyObject *_null) { int num_keys; +#if SDL_VERSION_ATLEAST(3, 0, 0) + const bool *key_state; +#else const Uint8 *key_state; +#endif PyObject *ret_obj = NULL; PyObject *key_tuple; int i; @@ -511,16 +519,42 @@ key_get_focused(PyObject *self, PyObject *_null) static PyObject * key_start_text_input(PyObject *self, PyObject *_null) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + /* Can consider making this a method of the Window class, this function + * just does backcompat */ + SDL_Window *win = pg_GetDefaultWindow(); + if (!win) { + return RAISE(pgExc_SDLError, + "display.set_mode has not been called yet."); + } + if (!SDL_StartTextInput(win)) { + return RAISE(pgExc_SDLError, SDL_GetError()); + } +#else /* https://wiki.libsdl.org/SDL_StartTextInput */ SDL_StartTextInput(); +#endif Py_RETURN_NONE; } static PyObject * key_stop_text_input(PyObject *self, PyObject *_null) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + /* Can consider making this a method of the Window class, this function + * just does backcompat */ + SDL_Window *win = pg_GetDefaultWindow(); + if (!win) { + return RAISE(pgExc_SDLError, + "display.set_mode has not been called yet."); + } + if (!SDL_StopTextInput(win)) { + return RAISE(pgExc_SDLError, SDL_GetError()); + } +#else /* https://wiki.libsdl.org/SDL_StopTextInput */ SDL_StopTextInput(); +#endif Py_RETURN_NONE; } @@ -552,11 +586,23 @@ key_set_text_input_rect(PyObject *self, PyObject *obj) rect2.w = (int)(rect->w * scalex); rect2.h = (int)(rect->h * scaley); +#if SDL_VERSION_ATLEAST(3, 0, 0) + /* Should consider how to expose the cursor argument to the user, maybe + * this should be new API in Window? */ + SDL_SetTextInputArea(sdlWindow, &rect2, 0); +#else SDL_SetTextInputRect(&rect2); +#endif Py_RETURN_NONE; } +#if SDL_VERSION_ATLEAST(3, 0, 0) + /* Should consider how to expose the cursor argument to the user, maybe + * this should be new API in Window? */ + SDL_SetTextInputArea(sdlWindow, rect, 0); +#else SDL_SetTextInputRect(rect); +#endif Py_RETURN_NONE; } diff --git a/src_c/meson.build b/src_c/meson.build index fb43a584eb..ca8205a7e8 100644 --- a/src_c/meson.build +++ b/src_c/meson.build @@ -54,8 +54,6 @@ event = py.extension_module( ) endif -# TODO: support SDL3 -if sdl_api != 3 key = py.extension_module( 'key', 'key.c', @@ -64,10 +62,7 @@ key = py.extension_module( install: true, subdir: pg, ) -endif -# TODO: support SDL3 -if sdl_api != 3 mouse = py.extension_module( 'mouse', 'mouse.c', @@ -76,7 +71,6 @@ mouse = py.extension_module( install: true, subdir: pg, ) -endif rect = py.extension_module( 'rect', diff --git a/src_c/mouse.c b/src_c/mouse.c index b6a5ae9195..97f7b0345c 100644 --- a/src_c/mouse.c +++ b/src_c/mouse.c @@ -65,7 +65,14 @@ mouse_set_pos(PyObject *self, PyObject *args) static PyObject * mouse_get_pos(PyObject *self, PyObject *args, PyObject *kwargs) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + /* SDL3 changed the mouse API to deal with float coordinates, for now we + * still truncate the result to int before returning to python side. + * This can be changed in a breaking release in the future if needed. */ + float x, y; +#else int x, y; +#endif int desktop = 0; static char *kwids[] = {"desktop", NULL}; @@ -114,7 +121,14 @@ mouse_get_pos(PyObject *self, PyObject *args, PyObject *kwargs) static PyObject * mouse_get_rel(PyObject *self, PyObject *_null) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + /* SDL3 changed the mouse API to deal with float coordinates, for now we + * still truncate the result to int before returning to python side. + * This can be changed in a breaking release in the future if needed. */ + float x, y; +#else int x, y; +#endif VIDEO_INIT_CHECK(); @@ -224,6 +238,10 @@ mouse_set_visible(PyObject *self, PyObject *args) win = pg_GetDefaultWindow(); if (win) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_SetWindowRelativeMouseMode(win, + SDL_GetWindowMouseGrab(win) && !toggle); +#else int mode = SDL_GetWindowGrab(win); if ((mode == SDL_ENABLE) & !toggle) { SDL_SetRelativeMouseMode(1); @@ -231,6 +249,7 @@ mouse_set_visible(PyObject *self, PyObject *args) else { SDL_SetRelativeMouseMode(0); } +#endif window_flags = SDL_GetWindowFlags(win); if (!toggle && (window_flags & PG_WINDOW_FULLSCREEN_INCLUSIVE)) { SDL_SetHint(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, "0"); @@ -263,7 +282,13 @@ mouse_get_visible(PyObject *self, PyObject *_null) VIDEO_INIT_CHECK(); +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_Window *win = pg_GetDefaultWindow(); + result = + win ? (PG_CursorVisible() && !SDL_GetWindowRelativeMouseMode(win)) : 0; +#else result = (PG_CursorVisible() && !SDL_GetRelativeMouseMode()); +#endif if (0 > result) { return RAISE(pgExc_SDLError, SDL_GetError()); @@ -527,7 +552,12 @@ mouse_get_cursor(PyObject *self, PyObject *_null) static PyObject * mouse_get_relative_mode(PyObject *self) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_Window *win = pg_GetDefaultWindow(); + return PyBool_FromLong(win ? SDL_GetWindowRelativeMouseMode(win) : 0); +#else return PyBool_FromLong(SDL_GetRelativeMouseMode()); +#endif } static PyObject * @@ -537,9 +567,20 @@ mouse_set_relative_mode(PyObject *self, PyObject *arg) if (mode == -1) { return NULL; } +#if SDL_VERSION_ATLEAST(3, 0, 0) + SDL_Window *win = pg_GetDefaultWindow(); + if (!win) { + return RAISE(pgExc_SDLError, + "display.set_mode has not been called yet."); + } + if (!SDL_SetWindowRelativeMouseMode(win, (bool)mode)) { + return RAISE(pgExc_SDLError, SDL_GetError()); + } +#else if (SDL_SetRelativeMouseMode((SDL_bool)mode)) { return RAISE(pgExc_SDLError, SDL_GetError()); } +#endif Py_RETURN_NONE; }