Skip to content

Commit

Permalink
add transform function customization, remove hints
Browse files Browse the repository at this point in the history
  • Loading branch information
expikr committed Dec 19, 2024
1 parent 5c0f8dc commit 5ebda77
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 75 deletions.
29 changes: 0 additions & 29 deletions include/SDL3/SDL_hints.h
Original file line number Diff line number Diff line change
Expand Up @@ -2547,35 +2547,6 @@ extern "C" {
*/
#define SDL_HINT_MOUSE_RELATIVE_MODE_WARP "SDL_MOUSE_RELATIVE_MODE_WARP"

/**
* A variable setting the scale for mouse motion, in floating point, when the
* mouse is in relative mode.
*
* This hint can be set anytime.
*
* \since This hint is available since SDL 3.1.3.
*/
#define SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE "SDL_MOUSE_RELATIVE_SPEED_SCALE"

/**
* A variable controlling whether the system mouse acceleration curve is used
* for relative mouse motion.
*
* The variable can be set to the following values:
*
* - "0": Relative mouse motion will be unscaled. (default)
* - "1": Relative mouse motion will be scaled using the system mouse
* acceleration curve.
*
* If SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE is set, that will override the
* system speed scale.
*
* This hint can be set anytime.
*
* \since This hint is available since SDL 3.1.3.
*/
#define SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE "SDL_MOUSE_RELATIVE_SYSTEM_SCALE"

/**
* A variable controlling whether a motion event should be generated for mouse
* warping in relative mode.
Expand Down
31 changes: 31 additions & 0 deletions include/SDL3/SDL_mouse.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,37 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetMouseNameForID(SDL_MouseID insta
*/
extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void);

/**
* Retieve an implementation of the function by which the platform
* transforms raw mouse inputs into cursor motion.
*
* This returns a function pointer to the implmentation if one exists,
* or NULL if not. This pointer can be passed to SDL_SetRelativeMouseTransform
* if one wishes to scale relative mouse motion using the implementation,
* in which case the userdata argument is ignored and platform-specific
* data will be used instead.
*
* \returns a pointer to an input transform function.
*
* \since This function is available since SDL 3.1.3.
*
* \sa SDL_SetRelativeMouseTransform
*/
extern SDL_DECLSPEC const void * SDLCALL SDL_GetSystemMouseTransform(void);

/**
* Set a user-defined function by which to transform relative mouse inputs,
* and its associated internal data which will be passed to the function.
*
* \param transform a pointer to an input transform function, or NULL to disable.
* \param userdata an optional pointer to the associated internal data.
*
* \since This function is available since SDL 3.1.3.
*
* \sa SDL_GetSystemMouseTransform
*/
extern SDL_DECLSPEC void SDLCALL SDL_SetRelativeMouseTransform(const void *transform, void *userdata);

/**
* Query SDL's cache for the synchronous mouse button state and the
* window-relative SDL-cursor position.
Expand Down
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ SDL3_0.0.0 {
SDL_GetSurfaceImages;
SDL_GetSurfacePalette;
SDL_GetSurfaceProperties;
SDL_GetSystemMouseTransform;
SDL_GetSystemRAM;
SDL_GetSystemTheme;
SDL_GetTLS;
Expand Down Expand Up @@ -820,6 +821,7 @@ SDL3_0.0.0 {
SDL_SetHint;
SDL_SetHintWithPriority;
SDL_SetInitialized;
SDL_SetRelativeMouseTransform;
SDL_SetJoystickEventsEnabled;
SDL_SetJoystickLED;
SDL_SetJoystickPlayerIndex;
Expand Down
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@
#define SDL_GetSurfaceImages SDL_GetSurfaceImages_REAL
#define SDL_GetSurfacePalette SDL_GetSurfacePalette_REAL
#define SDL_GetSurfaceProperties SDL_GetSurfaceProperties_REAL
#define SDL_GetSystemMouseTransform SDL_GetSystemMouseTransform_REAL
#define SDL_GetSystemRAM SDL_GetSystemRAM_REAL
#define SDL_GetSystemTheme SDL_GetSystemTheme_REAL
#define SDL_GetTLS SDL_GetTLS_REAL
Expand Down Expand Up @@ -844,6 +845,7 @@
#define SDL_SetHapticGain SDL_SetHapticGain_REAL
#define SDL_SetHint SDL_SetHint_REAL
#define SDL_SetHintWithPriority SDL_SetHintWithPriority_REAL
#define SDL_SetRelativeMouseTransform SDL_SetRelativeMouseTransform_REAL
#define SDL_SetInitialized SDL_SetInitialized_REAL
#define SDL_SetJoystickEventsEnabled SDL_SetJoystickEventsEnabled_REAL
#define SDL_SetJoystickLED SDL_SetJoystickLED_REAL
Expand Down
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ SDL_DYNAPI_PROC(SDL_Colorspace,SDL_GetSurfaceColorspace,(SDL_Surface *a),(a),ret
SDL_DYNAPI_PROC(SDL_Surface**,SDL_GetSurfaceImages,(SDL_Surface *a, int *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_Palette*,SDL_GetSurfacePalette,(SDL_Surface *a),(a),return)
SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetSurfaceProperties,(SDL_Surface *a),(a),return)
SDL_DYNAPI_PROC(const void*,SDL_GetSystemMouseTransform,(void),(),return)
SDL_DYNAPI_PROC(int,SDL_GetSystemRAM,(void),(),return)
SDL_DYNAPI_PROC(SDL_SystemTheme,SDL_GetSystemTheme,(void),(),return)
SDL_DYNAPI_PROC(void*,SDL_GetTLS,(SDL_TLSID *a),(a),return)
Expand Down Expand Up @@ -855,6 +856,7 @@ SDL_DYNAPI_PROC(bool,SDL_SetHapticGain,(SDL_Haptic *a, int b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_SetHint,(const char *a, const char *b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_SetHintWithPriority,(const char *a, const char *b, SDL_HintPriority c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_SetInitialized,(SDL_InitState *a, bool b),(a,b),)
SDL_DYNAPI_PROC(void,SDL_SetRelativeMouseTransform,(const void *a, void *b),(a,b),)
SDL_DYNAPI_PROC(void,SDL_SetJoystickEventsEnabled,(bool a),(a),)
SDL_DYNAPI_PROC(bool,SDL_SetJoystickLED,(SDL_Joystick *a, Uint8 b, Uint8 c, Uint8 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(bool,SDL_SetJoystickPlayerIndex,(SDL_Joystick *a, int b),(a,b),return)
Expand Down
56 changes: 17 additions & 39 deletions src/events/SDL_mouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,33 +89,13 @@ static void SDLCALL SDL_MouseNormalSpeedScaleChanged(void *userdata, const char
}
}

static void SDLCALL SDL_MouseRelativeSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;

if (hint && *hint) {
mouse->enable_relative_speed_scale = true;
mouse->relative_speed_scale = (float)SDL_atof(hint);
} else {
mouse->enable_relative_speed_scale = false;
mouse->relative_speed_scale = 1.0f;
}
}

static void SDLCALL SDL_MouseRelativeModeCenterChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;

mouse->relative_mode_center = SDL_GetStringBoolean(hint, true);
}

static void SDLCALL SDL_MouseRelativeSystemScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;

mouse->enable_relative_system_scale = SDL_GetStringBoolean(hint, false);
}

static void SDLCALL SDL_MouseWarpEmulationChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
Expand Down Expand Up @@ -215,13 +195,7 @@ bool SDL_PreInitMouse(void)

SDL_AddHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
SDL_MouseNormalSpeedScaleChanged, mouse);

SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE,
SDL_MouseRelativeSpeedScaleChanged, mouse);

SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE,
SDL_MouseRelativeSystemScaleChanged, mouse);


SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER,
SDL_MouseRelativeModeCenterChanged, mouse);

Expand Down Expand Up @@ -720,13 +694,12 @@ static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL

if (relative) {
if (mouse->relative_mode) {
if (mouse->enable_relative_speed_scale) {
x *= mouse->relative_speed_scale;
y *= mouse->relative_speed_scale;
} else if (mouse->enable_relative_system_scale) {
if (mouse->ApplySystemScale) {
mouse->ApplySystemScale(mouse->system_scale_data, timestamp, window, mouseID, &x, &y);
if (mouse->InputTransform) {
void *data = mouse->input_transform_data;
if (mouse->InputTransform == mouse->ApplySystemScale) {
data = mouse->system_scale_data;
}
mouse->InputTransform(data, timestamp, window, mouseID, &x, &y);
}
} else {
if (mouse->enable_normal_speed_scale) {
Expand Down Expand Up @@ -1073,12 +1046,6 @@ void SDL_QuitMouse(void)
SDL_RemoveHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
SDL_MouseNormalSpeedScaleChanged, mouse);

SDL_RemoveHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE,
SDL_MouseRelativeSpeedScaleChanged, mouse);

SDL_RemoveHintCallback(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE,
SDL_MouseRelativeSystemScaleChanged, mouse);

SDL_RemoveHintCallback(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER,
SDL_MouseRelativeModeCenterChanged, mouse);

Expand Down Expand Up @@ -1107,6 +1074,17 @@ void SDL_QuitMouse(void)
SDL_mice = NULL;
}

const void *SDL_GetSystemMouseTransform(void) {
SDL_Mouse *mouse = SDL_GetMouse();
return mouse->ApplySystemScale;
}

void SDL_SetRelativeMouseTransform(const void *transform, void *userdata) {
SDL_Mouse *mouse = SDL_GetMouse();
mouse->InputTransform = (SDL_InputTransform)transform;
mouse->input_transform_data = userdata;
}

SDL_MouseButtonFlags SDL_GetMouseState(float *x, float *y)
{
SDL_Mouse *mouse = SDL_GetMouse();
Expand Down
11 changes: 7 additions & 4 deletions src/events/SDL_mouse_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ typedef struct
Uint8 click_count;
} SDL_MouseClickState;

typedef void (*SDL_InputTransform)(void *userdata, Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float *x, float *y);

typedef struct
{
// Create a cursor from a surface
Expand Down Expand Up @@ -83,9 +85,13 @@ typedef struct
SDL_MouseButtonFlags (*GetGlobalMouseState)(float *x, float *y);

// Platform-specific system mouse transform
void (*ApplySystemScale)(void *internal, Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float *x, float *y);
SDL_InputTransform ApplySystemScale;
void *system_scale_data;

// User-defined mouse input transform
SDL_InputTransform InputTransform;
void *input_transform_data;

// Data common to all mice
SDL_Window *focus;
float x;
Expand All @@ -105,9 +111,6 @@ typedef struct
Uint64 last_center_warp_time_ns;
bool enable_normal_speed_scale;
float normal_speed_scale;
bool enable_relative_speed_scale;
float relative_speed_scale;
bool enable_relative_system_scale;
Uint32 double_click_time;
int double_click_radius;
bool touch_mouse_events;
Expand Down
6 changes: 3 additions & 3 deletions src/video/windows/SDL_windowsmouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,9 +694,9 @@ void WIN_UpdateMouseSystemScale(void)
{
SDL_Mouse *mouse = SDL_GetMouse();

if (mouse->ApplySystemScale == WIN_ApplySystemScale) {
mouse->system_scale_data = &WIN_system_scale_data;
}
// always set to platform impl to be safe, even though it's not exposed to user.
mouse->ApplySystemScale = WIN_ApplySystemScale;
mouse->system_scale_data = &WIN_system_scale_data;

// always reinitialize to valid defaults, whether fetch was successful or not.
WIN_MouseData *data = &WIN_system_scale_data;
Expand Down

0 comments on commit 5ebda77

Please sign in to comment.