mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-06-01 23:07:45 +08:00
add SDL_SetRelativeMouseTransform
This commit is contained in:
@@ -147,6 +147,38 @@ typedef enum SDL_MouseWheelDirection
|
|||||||
*/
|
*/
|
||||||
typedef Uint32 SDL_MouseButtonFlags;
|
typedef Uint32 SDL_MouseButtonFlags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A callback used to transform mouse motion delta from raw values.
|
||||||
|
*
|
||||||
|
* This is called during SDL's handling of platform mouse events to
|
||||||
|
* scale the values of the resulting motion delta.
|
||||||
|
*
|
||||||
|
* \param userdata what was passed as `userdata` to SDL_SetRelativeMouseTransform().
|
||||||
|
* \param timestamp the associated time at which this mouse motion event was received.
|
||||||
|
* \param window the associated window to which this mouse motion event was addressed.
|
||||||
|
* \param mouseID the associated mouse from which this mouse motion event was emitted.
|
||||||
|
* \param x pointer to a variable that will be treated as the resulting x-axis motion.
|
||||||
|
* \param y pointer to a variable that will be treated as the resulting y-axis motion.
|
||||||
|
*
|
||||||
|
* \threadsafety This callback is called by SDL's internal mouse input processing
|
||||||
|
* procedure, which may be a thread separate from the main event loop
|
||||||
|
* that is run at realtime priority. Stalling this thread with too much
|
||||||
|
* work in the callback can therefore potentially freeze the entire
|
||||||
|
* system. Care should be taken with proper synchronization practices
|
||||||
|
* when adding other side effects beyond mutation of the x and y values.
|
||||||
|
*
|
||||||
|
* \since This datatype is available since SDL 3.2.6.
|
||||||
|
*
|
||||||
|
* \sa SDL_SetRelativeMouseTransform
|
||||||
|
*/
|
||||||
|
typedef void (SDLCALL *SDL_MouseMotionTransformCallback)(
|
||||||
|
void *userdata,
|
||||||
|
Uint64 timestamp,
|
||||||
|
SDL_Window *window,
|
||||||
|
SDL_MouseID mouseID,
|
||||||
|
float *x, float *y
|
||||||
|
);
|
||||||
|
|
||||||
#define SDL_BUTTON_LEFT 1
|
#define SDL_BUTTON_LEFT 1
|
||||||
#define SDL_BUTTON_MIDDLE 2
|
#define SDL_BUTTON_MIDDLE 2
|
||||||
#define SDL_BUTTON_RIGHT 3
|
#define SDL_BUTTON_RIGHT 3
|
||||||
@@ -380,6 +412,17 @@ extern SDL_DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window *window,
|
|||||||
*/
|
*/
|
||||||
extern SDL_DECLSPEC bool SDLCALL SDL_WarpMouseGlobal(float x, float y);
|
extern SDL_DECLSPEC bool SDLCALL SDL_WarpMouseGlobal(float x, float y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a user-defined function by which to transform relative mouse inputs.
|
||||||
|
* This overrides the relative system scale and relative speed scale hints.
|
||||||
|
*
|
||||||
|
* \param callback a callback used to transform relative mouse motion, or NULL for default behavior.
|
||||||
|
* \param userdata a pointer that is passed to `callback`.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.6.
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC void SDLCALL SDL_SetRelativeMouseTransform(SDL_MouseMotionTransformCallback callback, void *userdata);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set relative mouse mode for a window.
|
* Set relative mouse mode for a window.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -705,6 +705,10 @@ static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL
|
|||||||
|
|
||||||
if (relative) {
|
if (relative) {
|
||||||
if (mouse->relative_mode) {
|
if (mouse->relative_mode) {
|
||||||
|
if (mouse->InputTransform) {
|
||||||
|
void *data = mouse->input_transform_data;
|
||||||
|
mouse->InputTransform(data, timestamp, window, mouseID, &x, &y);
|
||||||
|
} else {
|
||||||
if (mouse->enable_relative_system_scale) {
|
if (mouse->enable_relative_system_scale) {
|
||||||
if (mouse->ApplySystemScale) {
|
if (mouse->ApplySystemScale) {
|
||||||
mouse->ApplySystemScale(mouse->system_scale_data, timestamp, window, mouseID, &x, &y);
|
mouse->ApplySystemScale(mouse->system_scale_data, timestamp, window, mouseID, &x, &y);
|
||||||
@@ -714,6 +718,7 @@ static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL
|
|||||||
x *= mouse->relative_speed_scale;
|
x *= mouse->relative_speed_scale;
|
||||||
y *= mouse->relative_speed_scale;
|
y *= mouse->relative_speed_scale;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mouse->enable_normal_speed_scale) {
|
if (mouse->enable_normal_speed_scale) {
|
||||||
x *= mouse->normal_speed_scale;
|
x *= mouse->normal_speed_scale;
|
||||||
@@ -1115,6 +1120,13 @@ void SDL_QuitMouse(void)
|
|||||||
SDL_mice = NULL;
|
SDL_mice = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDL_SetRelativeMouseTransform(SDL_MouseMotionTransformCallback transform, void *userdata)
|
||||||
|
{
|
||||||
|
SDL_Mouse *mouse = SDL_GetMouse();
|
||||||
|
mouse->InputTransform = transform;
|
||||||
|
mouse->input_transform_data = userdata;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_MouseButtonFlags SDL_GetMouseState(float *x, float *y)
|
SDL_MouseButtonFlags SDL_GetMouseState(float *x, float *y)
|
||||||
{
|
{
|
||||||
SDL_Mouse *mouse = SDL_GetMouse();
|
SDL_Mouse *mouse = SDL_GetMouse();
|
||||||
|
|||||||
@@ -87,10 +87,14 @@ typedef struct
|
|||||||
// Get absolute mouse coordinates. (x) and (y) are never NULL and set to zero before call.
|
// Get absolute mouse coordinates. (x) and (y) are never NULL and set to zero before call.
|
||||||
SDL_MouseButtonFlags (*GetGlobalMouseState)(float *x, float *y);
|
SDL_MouseButtonFlags (*GetGlobalMouseState)(float *x, float *y);
|
||||||
|
|
||||||
// Platform-specific system mouse transform
|
// Platform-specific system mouse transform applied in relative mode
|
||||||
void (*ApplySystemScale)(void *internal, Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float *x, float *y);
|
SDL_MouseMotionTransformCallback ApplySystemScale;
|
||||||
void *system_scale_data;
|
void *system_scale_data;
|
||||||
|
|
||||||
|
// User-defined mouse input transform applied in relative mode
|
||||||
|
SDL_MouseMotionTransformCallback InputTransform;
|
||||||
|
void *input_transform_data;
|
||||||
|
|
||||||
// Data common to all mice
|
// Data common to all mice
|
||||||
SDL_Window *focus;
|
SDL_Window *focus;
|
||||||
float x;
|
float x;
|
||||||
|
|||||||
@@ -1012,6 +1012,7 @@ static void relative_pointer_handle_relative_motion(void *data,
|
|||||||
struct SDL_WaylandInput *input = data;
|
struct SDL_WaylandInput *input = data;
|
||||||
SDL_VideoData *d = input->display;
|
SDL_VideoData *d = input->display;
|
||||||
SDL_WindowData *window = input->pointer_focus;
|
SDL_WindowData *window = input->pointer_focus;
|
||||||
|
SDL_Mouse *mouse = SDL_GetMouse();
|
||||||
|
|
||||||
// Relative pointer event times are in microsecond granularity.
|
// Relative pointer event times are in microsecond granularity.
|
||||||
const Uint64 timestamp = Wayland_GetEventTimestamp(SDL_US_TO_NS(((Uint64)time_hi << 32) | (Uint64)time_lo));
|
const Uint64 timestamp = Wayland_GetEventTimestamp(SDL_US_TO_NS(((Uint64)time_hi << 32) | (Uint64)time_lo));
|
||||||
@@ -1019,7 +1020,7 @@ static void relative_pointer_handle_relative_motion(void *data,
|
|||||||
if (input->pointer_focus && d->relative_mouse_mode) {
|
if (input->pointer_focus && d->relative_mouse_mode) {
|
||||||
double dx;
|
double dx;
|
||||||
double dy;
|
double dy;
|
||||||
if (!SDL_GetMouse()->enable_relative_system_scale) {
|
if (mouse->InputTransform || !mouse->enable_relative_system_scale) {
|
||||||
dx = wl_fixed_to_double(dx_unaccel_w);
|
dx = wl_fixed_to_double(dx_unaccel_w);
|
||||||
dy = wl_fixed_to_double(dy_unaccel_w);
|
dy = wl_fixed_to_double(dy_unaccel_w);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user