Skip to content

Commit

Permalink
Merge pull request #3207 from pygame-community/ankith26-more-sdl3-2
Browse files Browse the repository at this point in the history
Port key and mouse to SDL3
  • Loading branch information
ankith26 authored Jan 17, 2025
2 parents 146c43c + 634619b commit 3ec0832
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 7 deletions.
46 changes: 46 additions & 0 deletions src_c/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}
Expand Down
6 changes: 0 additions & 6 deletions src_c/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ event = py.extension_module(
subdir: pg,
)

# TODO: support SDL3
if sdl_api != 3
key = py.extension_module(
'key',
'key.c',
Expand All @@ -58,10 +56,7 @@ key = py.extension_module(
install: true,
subdir: pg,
)
endif

# TODO: support SDL3
if sdl_api != 3
mouse = py.extension_module(
'mouse',
'mouse.c',
Expand All @@ -70,7 +65,6 @@ mouse = py.extension_module(
install: true,
subdir: pg,
)
endif

rect = py.extension_module(
'rect',
Expand Down
67 changes: 66 additions & 1 deletion src_c/mouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -90,12 +97,27 @@ mouse_get_pos(PyObject *self, PyObject *args, PyObject *kwargs)
SDL_RenderGetScale(sdlRenderer, &scalex, &scaley);
SDL_RenderGetViewport(sdlRenderer, &vprect);

#if SDL_VERSION_ATLEAST(3, 0, 0)
x = x / scalex;
y = y / scaley;
#else
x = (int)(x / scalex);
y = (int)(y / scaley);
#endif

x -= vprect.x;
y -= vprect.y;

#if SDL_VERSION_ATLEAST(3, 0, 0)
if (x < 0)
x = 0;
if (x >= vprect.w)
x = (float)vprect.w - 1;
if (y < 0)
y = 0;
if (y >= vprect.h)
y = (float)vprect.h - 1;
#else
if (x < 0)
x = 0;
if (x >= vprect.w)
Expand All @@ -104,17 +126,29 @@ mouse_get_pos(PyObject *self, PyObject *args, PyObject *kwargs)
y = 0;
if (y >= vprect.h)
y = vprect.h - 1;
#endif
}
}
}

#if SDL_VERSION_ATLEAST(3, 0, 0)
return pg_tuple_couple_from_values_int((int)x, (int)y);
#else
return pg_tuple_couple_from_values_int(x, y);
#endif
}

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();

Expand All @@ -132,7 +166,11 @@ mouse_get_rel(PyObject *self, PyObject *_null)
y/=scaley;
}
*/
#if SDL_VERSION_ATLEAST(3, 0, 0)
return pg_tuple_couple_from_values_int((int)x, (int)y);
#else
return pg_tuple_couple_from_values_int(x, y);
#endif
}

static PyObject *
Expand Down Expand Up @@ -216,21 +254,26 @@ mouse_set_visible(PyObject *self, PyObject *args)
{
int toggle, prevstate;
SDL_Window *win = NULL;
Uint32 window_flags = 0;
SDL_WindowFlags window_flags = 0;

if (!PyArg_ParseTuple(args, "i", &toggle))
return NULL;
VIDEO_INIT_CHECK();

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);
}
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");
Expand Down Expand Up @@ -263,7 +306,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());
Expand Down Expand Up @@ -527,7 +576,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 *
Expand All @@ -537,9 +591,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;
}

Expand Down

0 comments on commit 3ec0832

Please sign in to comment.