Updated raw input events to match SDL style

Also added raw keyboard events, and implemented raw input events on iOS, OpenBSD console, Linux console, and X11
This commit is contained in:
Sam Lantinga 2024-12-19 16:18:05 -08:00
parent 1025087c2e
commit c44fa5bb07
25 changed files with 515 additions and 312 deletions

View file

@ -174,6 +174,8 @@ typedef enum SDL_EventType
SDL_EVENT_KEYBOARD_ADDED, /**< A new keyboard has been inserted into the system */ SDL_EVENT_KEYBOARD_ADDED, /**< A new keyboard has been inserted into the system */
SDL_EVENT_KEYBOARD_REMOVED, /**< A keyboard has been removed */ SDL_EVENT_KEYBOARD_REMOVED, /**< A keyboard has been removed */
SDL_EVENT_TEXT_EDITING_CANDIDATES, /**< Keyboard text editing candidates */ SDL_EVENT_TEXT_EDITING_CANDIDATES, /**< Keyboard text editing candidates */
SDL_EVENT_RAW_KEY_DOWN, /**< Key pressed (raw key press) */
SDL_EVENT_RAW_KEY_UP, /**< Key released (raw key release) */
/* Mouse events */ /* Mouse events */
SDL_EVENT_MOUSE_MOTION = 0x400, /**< Mouse moved */ SDL_EVENT_MOUSE_MOTION = 0x400, /**< Mouse moved */
@ -182,9 +184,10 @@ typedef enum SDL_EventType
SDL_EVENT_MOUSE_WHEEL, /**< Mouse wheel motion */ SDL_EVENT_MOUSE_WHEEL, /**< Mouse wheel motion */
SDL_EVENT_MOUSE_ADDED, /**< A new mouse has been inserted into the system */ SDL_EVENT_MOUSE_ADDED, /**< A new mouse has been inserted into the system */
SDL_EVENT_MOUSE_REMOVED, /**< A mouse has been removed */ SDL_EVENT_MOUSE_REMOVED, /**< A mouse has been removed */
SDL_EVENT_MOUSE_RAW_MOTION, /**< Mouse moved (raw motion deltas) */ SDL_EVENT_RAW_MOUSE_MOTION, /**< Mouse moved (raw motion deltas) */
SDL_EVENT_MOUSE_RAW_BUTTON, /**< Mouse click (raw button delta) */ SDL_EVENT_RAW_MOUSE_BUTTON_DOWN, /**< Mouse button pressed (raw button press) */
SDL_EVENT_MOUSE_RAW_SCROLL, /**< Mouse wheel (raw scroll deltas) */ SDL_EVENT_RAW_MOUSE_BUTTON_UP, /**< Mouse button released (raw button release) */
SDL_EVENT_RAW_MOUSE_WHEEL, /**< Mouse wheel motion (raw wheel deltas) */
/* Joystick events */ /* Joystick events */
SDL_EVENT_JOYSTICK_AXIS_MOTION = 0x600, /**< Joystick axis motion */ SDL_EVENT_JOYSTICK_AXIS_MOTION = 0x600, /**< Joystick axis motion */
@ -365,6 +368,22 @@ typedef struct SDL_KeyboardEvent
bool repeat; /**< true if this is a key repeat */ bool repeat; /**< true if this is a key repeat */
} SDL_KeyboardEvent; } SDL_KeyboardEvent;
/**
* Raw keyboard button event structure (event.raw_key.*)
*
* \since This struct is available since SDL 3.1.8.
*/
typedef struct SDL_RawKeyboardEvent
{
SDL_EventType type; /**< SDL_EVENT_RAW_KEY_DOWN or SDL_EVENT_RAW_KEY_UP */
Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_KeyboardID which; /**< The keyboard instance id */
SDL_Scancode scancode; /**< SDL physical key code */
Uint16 raw; /**< The platform dependent scancode for this event */
bool down; /**< true if the key is pressed */
} SDL_RawKeyboardEvent;
/** /**
* Keyboard text editing event structure (event.edit.*) * Keyboard text editing event structure (event.edit.*)
* *
@ -458,21 +477,21 @@ typedef struct SDL_MouseMotionEvent
} SDL_MouseMotionEvent; } SDL_MouseMotionEvent;
/** /**
* Mouse raw motion and wheel event structure (event.maxis.*) * Raw mouse motion event structure (event.raw_motion.*)
* *
* \since This struct is available since SDL 3.0.0. * \since This struct is available since SDL 3.1.8.
*/ */
typedef struct SDL_MouseRawAxisEvent typedef struct SDL_RawMouseMotionEvent
{ {
SDL_EventType type; /**< SDL_EVENT_MOUSE_RAW_MOTION or SDL_EVENT_MOUSE_RAW_SCROLL */ SDL_EventType type; /**< SDL_EVENT_RAW_MOUSE_MOTION */
Uint32 reserved; Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_MouseID which; /**< The mouse instance id, SDL_TOUCH_MOUSEID, or SDL_PEN_MOUSEID */ SDL_MouseID which; /**< The mouse instance id */
int dx; /**< The axis delta value in the X direction */ Sint32 dx; /**< X axis delta */
int dy; /**< The axis delta value in the Y direction */ Sint32 dy; /**< Y axis delta */
float ux; /**< The denominator unit in the X direction */ float scale_x; /**< X value scale to approximate desktop acceleration */
float uy; /**< The denominator unit in the Y direction */ float scale_y; /**< Y value scale to approximate desktop acceleration */
} SDL_MouseRawAxisEvent; } SDL_RawMouseMotionEvent;
/** /**
* Mouse button event structure (event.button.*) * Mouse button event structure (event.button.*)
@ -485,7 +504,7 @@ typedef struct SDL_MouseButtonEvent
Uint32 reserved; Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID; /**< The window with mouse focus, if any */ SDL_WindowID windowID; /**< The window with mouse focus, if any */
SDL_MouseID which; /**< The mouse instance id, SDL_TOUCH_MOUSEID */ SDL_MouseID which; /**< The mouse instance id or SDL_TOUCH_MOUSEID */
Uint8 button; /**< The mouse button index */ Uint8 button; /**< The mouse button index */
bool down; /**< true if the button is pressed */ bool down; /**< true if the button is pressed */
Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */ Uint8 clicks; /**< 1 for single-click, 2 for double-click, etc. */
@ -495,19 +514,19 @@ typedef struct SDL_MouseButtonEvent
} SDL_MouseButtonEvent; } SDL_MouseButtonEvent;
/** /**
* Mouse raw button event structure (event.mbutton.*) * Raw mouse button event structure (event.raw_button.*)
* *
* \since This struct is available since SDL 3.0.0. * \since This struct is available since SDL 3.1.8.
*/ */
typedef struct SDL_MouseRawButtonEvent typedef struct SDL_RawMouseButtonEvent
{ {
SDL_EventType type; /**< SDL_EVENT_MOUSE_RAW_BUTTON */ SDL_EventType type; /**< SDL_EVENT_RAW_MOUSE_BUTTON_DOWN or SDL_EVENT_RAW_MOUSE_BUTTON_UP */
Uint32 reserved; Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_MouseID which; /**< The mouse instance id, SDL_TOUCH_MOUSEID, or SDL_PEN_MOUSEID */ SDL_MouseID which; /**< The mouse instance id */
Uint8 button; /**< The mouse button index */ Uint8 button; /**< The mouse button index */
Uint8 state; /**< SDL_PRESSED or SDL_RELEASED */ bool down; /**< true if the button is pressed */
} SDL_MouseRawButtonEvent; } SDL_RawMouseButtonEvent;
/** /**
* Mouse wheel event structure (event.wheel.*) * Mouse wheel event structure (event.wheel.*)
@ -520,7 +539,7 @@ typedef struct SDL_MouseWheelEvent
Uint32 reserved; Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID; /**< The window with mouse focus, if any */ SDL_WindowID windowID; /**< The window with mouse focus, if any */
SDL_MouseID which; /**< The mouse instance id, SDL_TOUCH_MOUSEID */ SDL_MouseID which; /**< The mouse instance id */
float x; /**< The amount scrolled horizontally, positive to the right and negative to the left */ float x; /**< The amount scrolled horizontally, positive to the right and negative to the left */
float y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */ float y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */
SDL_MouseWheelDirection direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */ SDL_MouseWheelDirection direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */
@ -528,6 +547,23 @@ typedef struct SDL_MouseWheelEvent
float mouse_y; /**< Y coordinate, relative to window */ float mouse_y; /**< Y coordinate, relative to window */
} SDL_MouseWheelEvent; } SDL_MouseWheelEvent;
/**
* Raw mouse wheel event structure (event.raw_wheel.*)
*
* \since This struct is available since SDL 3.1.3.
*/
typedef struct SDL_RawMouseWheelEvent
{
SDL_EventType type; /**< SDL_EVENT_RAW_MOUSE_WHEEL */
Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_MouseID which; /**< The mouse instance id */
Sint32 dx; /**< X axis delta, positive to the right and negative to the left */
Sint32 dy; /**< Y axis delta, positive away from the user and negative toward the user */
float scale_x; /**< X value scale to convert to logical scroll units */
float scale_y; /**< Y value scale to convert to logical scroll units */
} SDL_RawMouseWheelEvent;
/** /**
* Joystick axis motion event structure (event.jaxis.*) * Joystick axis motion event structure (event.jaxis.*)
* *
@ -1025,15 +1061,17 @@ typedef union SDL_Event
SDL_WindowEvent window; /**< Window event data */ SDL_WindowEvent window; /**< Window event data */
SDL_KeyboardDeviceEvent kdevice; /**< Keyboard device change event data */ SDL_KeyboardDeviceEvent kdevice; /**< Keyboard device change event data */
SDL_KeyboardEvent key; /**< Keyboard event data */ SDL_KeyboardEvent key; /**< Keyboard event data */
SDL_RawKeyboardEvent raw_key; /**< Raw keyboard event data */
SDL_TextEditingEvent edit; /**< Text editing event data */ SDL_TextEditingEvent edit; /**< Text editing event data */
SDL_TextEditingCandidatesEvent edit_candidates; /**< Text editing candidates event data */ SDL_TextEditingCandidatesEvent edit_candidates; /**< Text editing candidates event data */
SDL_TextInputEvent text; /**< Text input event data */ SDL_TextInputEvent text; /**< Text input event data */
SDL_MouseDeviceEvent mdevice; /**< Mouse device change event data */ SDL_MouseDeviceEvent mdevice; /**< Mouse device change event data */
SDL_MouseMotionEvent motion; /**< Mouse motion event data */ SDL_MouseMotionEvent motion; /**< Mouse motion event data */
SDL_RawMouseMotionEvent raw_motion; /**< Raw mouse motion event data */
SDL_MouseButtonEvent button; /**< Mouse button event data */ SDL_MouseButtonEvent button; /**< Mouse button event data */
SDL_RawMouseButtonEvent raw_button; /**< Raw mouse button event data */
SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */ SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */
SDL_MouseRawAxisEvent maxis; /**< Mouse raw axis event data (motion or wheel deltas) */ SDL_RawMouseWheelEvent raw_wheel; /**< Raw mouse wheel event data */
SDL_MouseRawButtonEvent mbutton; /**< Mouse raw button event data */
SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */ SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */
SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */ SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */
SDL_JoyBallEvent jball; /**< Joystick ball event data */ SDL_JoyBallEvent jball; /**< Joystick ball event data */

View file

@ -346,8 +346,10 @@ void SDL_EVDEV_Poll(void)
switch (event->type) { switch (event->type) {
case EV_KEY: case EV_KEY:
if (event->code >= BTN_MOUSE && event->code < BTN_MOUSE + SDL_arraysize(EVDEV_MouseButtons)) { if (event->code >= BTN_MOUSE && event->code < BTN_MOUSE + SDL_arraysize(EVDEV_MouseButtons)) {
Uint64 timestamp = SDL_EVDEV_GetEventTimestamp(event);
mouse_button = event->code - BTN_MOUSE; mouse_button = event->code - BTN_MOUSE;
SDL_SendMouseButton(SDL_EVDEV_GetEventTimestamp(event), mouse->focus, (SDL_MouseID)item->fd, EVDEV_MouseButtons[mouse_button], (event->value != 0)); SDL_SendRawMouseButton(timestamp, (SDL_MouseID)item->fd, EVDEV_MouseButtons[mouse_button], (event->value != 0));
SDL_SendMouseButton(timestamp, mouse->focus, (SDL_MouseID)item->fd, EVDEV_MouseButtons[mouse_button], (event->value != 0));
break; break;
} }
@ -367,13 +369,18 @@ void SDL_EVDEV_Poll(void)
} }
// Probably keyboard // Probably keyboard
{
Uint64 timestamp = SDL_EVDEV_GetEventTimestamp(event);
scancode = SDL_EVDEV_translate_keycode(event->code); scancode = SDL_EVDEV_translate_keycode(event->code);
if (event->value == 0) { if (event->value == 0) {
SDL_SendKeyboardKey(SDL_EVDEV_GetEventTimestamp(event), (SDL_KeyboardID)item->fd, event->code, scancode, false); SDL_SendRawKeyboardKey(timestamp, (SDL_KeyboardID)item->fd, event->code, scancode, false);
SDL_SendKeyboardKey(timestamp, (SDL_KeyboardID)item->fd, event->code, scancode, false);
} else if (event->value == 1 || event->value == 2 /* key repeated */) { } else if (event->value == 1 || event->value == 2 /* key repeated */) {
SDL_SendKeyboardKey(SDL_EVDEV_GetEventTimestamp(event), (SDL_KeyboardID)item->fd, event->code, scancode, true); SDL_SendRawKeyboardKey(timestamp, (SDL_KeyboardID)item->fd, event->code, scancode, true);
SDL_SendKeyboardKey(timestamp, (SDL_KeyboardID)item->fd, event->code, scancode, true);
} }
SDL_EVDEV_kbd_keycode(_this->kbd, event->code, event->value); SDL_EVDEV_kbd_keycode(_this->kbd, event->code, event->value);
}
break; break;
case EV_ABS: case EV_ABS:
switch (event->code) { switch (event->code) {
@ -485,7 +492,9 @@ void SDL_EVDEV_Poll(void)
// Send mouse axis changes together to ensure consistency and reduce event processing overhead // Send mouse axis changes together to ensure consistency and reduce event processing overhead
if (item->relative_mouse) { if (item->relative_mouse) {
if (item->mouse_x != 0 || item->mouse_y != 0) { if (item->mouse_x != 0 || item->mouse_y != 0) {
SDL_SendMouseMotion(SDL_EVDEV_GetEventTimestamp(event), mouse->focus, (SDL_MouseID)item->fd, item->relative_mouse, (float)item->mouse_x, (float)item->mouse_y); Uint64 timestamp = SDL_EVDEV_GetEventTimestamp(event);
SDL_SendRawMouseMotion(timestamp, (SDL_MouseID)item->fd, item->mouse_x, item->mouse_y, 1.0f, 1.0f);
SDL_SendMouseMotion(timestamp, mouse->focus, (SDL_MouseID)item->fd, item->relative_mouse, (float)item->mouse_x, (float)item->mouse_y);
item->mouse_x = item->mouse_y = 0; item->mouse_x = item->mouse_y = 0;
} }
} else if (item->range_x > 0 && item->range_y > 0) { } else if (item->range_x > 0 && item->range_y > 0) {
@ -508,10 +517,15 @@ void SDL_EVDEV_Poll(void)
} }
if (item->mouse_wheel != 0 || item->mouse_hwheel != 0) { if (item->mouse_wheel != 0 || item->mouse_hwheel != 0) {
SDL_SendMouseWheel(SDL_EVDEV_GetEventTimestamp(event), Uint64 timestamp = SDL_EVDEV_GetEventTimestamp(event);
const float scale = (item->high_res_hwheel ? 1.0f / 120.0f : 1.0f);
SDL_SendRawMouseWheel(timestamp,
(SDL_MouseID)item->fd,
item->mouse_hwheel, item->mouse_wheel, scale, scale);
SDL_SendMouseWheel(timestamp,
mouse->focus, (SDL_MouseID)item->fd, mouse->focus, (SDL_MouseID)item->fd,
item->mouse_hwheel / (item->high_res_hwheel ? 120.0f : 1.0f), item->mouse_hwheel * scale,
item->mouse_wheel / (item->high_res_wheel ? 120.0f : 1.0f), item->mouse_wheel * scale,
SDL_MOUSEWHEEL_NORMAL); SDL_MOUSEWHEEL_NORMAL);
item->mouse_wheel = item->mouse_hwheel = 0; item->mouse_wheel = item->mouse_hwheel = 0;
} }

View file

@ -550,7 +550,7 @@ static void Translate_to_text(SDL_WSCONS_input_data *input, keysym_t ksym)
} }
} }
static void Translate_to_keycode(SDL_WSCONS_input_data *input, int type, keysym_t ksym) static void Translate_to_keycode(SDL_WSCONS_input_data *input, int type, keysym_t ksym, Uint64 timestamp)
{ {
struct wscons_keymap keyDesc = input->keymap.map[ksym]; struct wscons_keymap keyDesc = input->keymap.map[ksym];
keysym_t *group = &keyDesc.group1[KS_GROUP(keyDesc.group1[0]) == KS_GROUP_Keypad && IS_NUMLOCK_ON ? !IS_SHIFT_HELD : 0]; keysym_t *group = &keyDesc.group1[KS_GROUP(keyDesc.group1[0]) == KS_GROUP_Keypad && IS_NUMLOCK_ON ? !IS_SHIFT_HELD : 0];
@ -560,22 +560,32 @@ static void Translate_to_keycode(SDL_WSCONS_input_data *input, int type, keysym_
switch (keyDesc.command) { switch (keyDesc.command) {
case KS_Cmd_ScrollBack: case KS_Cmd_ScrollBack:
{ {
SDL_SendKeyboardKey(0, input->keyboardID, 0, SDL_SCANCODE_PAGEUP, (type == WSCONS_EVENT_KEY_DOWN)); SDL_SendKeyboardKey(timestamp, input->keyboardID, 0, SDL_SCANCODE_PAGEUP, (type == WSCONS_EVENT_KEY_DOWN));
return; return;
} }
case KS_Cmd_ScrollFwd: case KS_Cmd_ScrollFwd:
{ {
SDL_SendKeyboardKey(0, input->keyboardID, 0, SDL_SCANCODE_PAGEDOWN, (type == WSCONS_EVENT_KEY_DOWN)); SDL_SendKeyboardKey(timestamp, input->keyboardID, 0, SDL_SCANCODE_PAGEDOWN, (type == WSCONS_EVENT_KEY_DOWN));
return; return;
} }
default:
break;
} }
for (i = 0; i < sizeof(conversion_table) / sizeof(struct wscons_keycode_to_SDL); i++) { for (i = 0; i < SDL_arraysize(conversion_table); i++) {
if (conversion_table[i].sourcekey == group[0]) { if (conversion_table[i].sourcekey == group[0]) {
SDL_SendKeyboardKey(0, input->keyboardID, group[0], conversion_table[i].targetKey, (type == WSCONS_EVENT_KEY_DOWN)); SDL_SendRawKeyboardKey(timestamp, input->keyboardID, group[0], conversion_table[i].targetKey, (type == WSCONS_EVENT_KEY_DOWN));
SDL_SendKeyboardKey(timestamp, input->keyboardID, group[0], conversion_table[i].targetKey, (type == WSCONS_EVENT_KEY_DOWN));
return; return;
} }
} }
SDL_SendKeyboardKey(0, input->keyboardID, group[0], SDL_SCANCODE_UNKNOWN, (type == WSCONS_EVENT_KEY_DOWN)); SDL_SendRawKeyboardKey(timestamp, input->keyboardID, group[0], SDL_SCANCODE_UNKNOWN, (type == WSCONS_EVENT_KEY_DOWN));
SDL_SendKeyboardKey(timestamp, input->keyboardID, group[0], SDL_SCANCODE_UNKNOWN, (type == WSCONS_EVENT_KEY_DOWN));
}
static Uint64 GetEventTimestamp(struct timespec *time)
{
// FIXME: Get the event time in the SDL tick time base
return SDL_GetTicksNS();
} }
static void updateKeyboard(SDL_WSCONS_input_data *input) static void updateKeyboard(SDL_WSCONS_input_data *input)
@ -592,6 +602,7 @@ static void updateKeyboard(SDL_WSCONS_input_data *input)
if ((n = read(input->fd, events, sizeof(events))) > 0) { if ((n = read(input->fd, events, sizeof(events))) > 0) {
n /= sizeof(struct wscons_event); n /= sizeof(struct wscons_event);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
Uint64 timestamp = GetEventTimestamp(&events[i].time);
type = events[i].type; type = events[i].type;
switch (type) { switch (type) {
case WSCONS_EVENT_KEY_DOWN: case WSCONS_EVENT_KEY_DOWN:
@ -809,15 +820,20 @@ static void updateKeyboard(SDL_WSCONS_input_data *input)
} break; } break;
case WSCONS_EVENT_ALL_KEYS_UP: case WSCONS_EVENT_ALL_KEYS_UP:
for (i = 0; i < SDL_SCANCODE_COUNT; i++) { for (i = 0; i < SDL_SCANCODE_COUNT; i++) {
SDL_SendKeyboardKey(0, input->keyboardID, 0, (SDL_Scancode)i, false); SDL_SendRawKeyboardKey(timestamp, input->keyboardID, 0, (SDL_Scancode)i, false);
SDL_SendKeyboardKey(timestamp, input->keyboardID, 0, (SDL_Scancode)i, false);
} }
break; break;
default:
break;
} }
if (input->type == WSKBD_TYPE_USB && events[i].value <= 0xE7) if (input->type == WSKBD_TYPE_USB && events[i].value <= 0xE7) {
SDL_SendKeyboardKey(0, input->keyboardID, 0, (SDL_Scancode)events[i].value, (type == WSCONS_EVENT_KEY_DOWN)); SDL_SendRawKeyboardKey(timestamp, input->keyboardID, 0, (SDL_Scancode)events[i].value, (type == WSCONS_EVENT_KEY_DOWN));
else SDL_SendKeyboardKey(timestamp, input->keyboardID, 0, (SDL_Scancode)events[i].value, (type == WSCONS_EVENT_KEY_DOWN));
Translate_to_keycode(input, type, events[i].value); } else {
Translate_to_keycode(input, type, events[i].value, timestamp);
}
if (type == WSCONS_EVENT_KEY_UP) { if (type == WSCONS_EVENT_KEY_UP) {
continue; continue;
@ -910,7 +926,7 @@ static void updateKeyboard(SDL_WSCONS_input_data *input)
} }
if (IS_ALT_HELD) { if (IS_ALT_HELD) {
if (input->encoding & KB_METAESC) { if (input->encoding & KB_METAESC) {
Translate_to_keycode(input, WSCONS_EVENT_KEY_DOWN, KS_Escape); Translate_to_keycode(input, WSCONS_EVENT_KEY_DOWN, KS_Escape, 0);
Translate_to_text(input, result); Translate_to_text(input, result);
continue; continue;
} else { } else {

View file

@ -63,6 +63,12 @@ SDL_WSCONS_mouse_input_data *SDL_WSCONS_Init_Mouse(void)
return input; return input;
} }
static Uint64 GetEventTimestamp(struct timespec *time)
{
// FIXME: Get the event time in the SDL tick time base
return SDL_GetTicksNS();
}
void updateMouse(SDL_WSCONS_mouse_input_data *input) void updateMouse(SDL_WSCONS_mouse_input_data *input)
{ {
struct wscons_event events[64]; struct wscons_event events[64];
@ -73,56 +79,48 @@ void updateMouse(SDL_WSCONS_mouse_input_data *input)
int i; int i;
n /= sizeof(struct wscons_event); n /= sizeof(struct wscons_event);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
Uint64 timestamp = GetEventTimestamp(&events[i].time);
int type = events[i].type; int type = events[i].type;
switch (type) { switch (type) {
case WSCONS_EVENT_MOUSE_DOWN: case WSCONS_EVENT_MOUSE_DOWN:
{
switch (events[i].value) {
case 0: // Left Mouse Button.
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_BUTTON_LEFT, true);
break;
case 1: // Middle Mouse Button.
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_BUTTON_MIDDLE, true);
break;
case 2: // Right Mouse Button.
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_BUTTON_RIGHT, true);
break;
}
} break;
case WSCONS_EVENT_MOUSE_UP: case WSCONS_EVENT_MOUSE_UP:
{ {
switch (events[i].value) { Uint8 button = SDL_BUTTON_LEFT + events[i].value;
case 0: // Left Mouse Button. bool down = (type == WSCONS_EVENT_MOUSE_DOWN);
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_BUTTON_LEFT, false); SDL_SendRawMouseButton(timestamp, input->mouseID, button, down);
break; SDL_SendMouseButton(timestamp, mouse->focus, input->mouseID, button, down);
case 1: // Middle Mouse Button.
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_BUTTON_MIDDLE, false);
break;
case 2: // Right Mouse Button.
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_BUTTON_RIGHT, false);
break; break;
} }
} break;
case WSCONS_EVENT_MOUSE_DELTA_X: case WSCONS_EVENT_MOUSE_DELTA_X:
{ {
SDL_SendMouseMotion(0, mouse->focus, input->mouseID, 1, (float)events[i].value, 0.0f); const float scale = 1.0f;
SDL_SendRawMouseMotion(timestamp, input->mouseID, events[i].value, 0, scale, scale);
SDL_SendMouseMotion(timestamp, mouse->focus, input->mouseID, true, (float)events[i].value, 0.0f);
break; break;
} }
case WSCONS_EVENT_MOUSE_DELTA_Y: case WSCONS_EVENT_MOUSE_DELTA_Y:
{ {
SDL_SendMouseMotion(0, mouse->focus, input->mouseID, 1, 0.0f, -(float)events[i].value); const float scale = 1.0f;
SDL_SendRawMouseMotion(timestamp, input->mouseID, 0, -events[i].value, scale, scale);
SDL_SendMouseMotion(timestamp, mouse->focus, input->mouseID, true, 0.0f, -(float)events[i].value);
break; break;
} }
case WSCONS_EVENT_MOUSE_DELTA_W: case WSCONS_EVENT_MOUSE_DELTA_W:
{ {
SDL_SendMouseWheel(0, mouse->focus, input->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL); const float scale = 1.0f;
SDL_SendRawMouseWheel(timestamp, input->mouseID, events[i].value, 0, scale, scale);
SDL_SendMouseWheel(timestamp, mouse->focus, input->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL);
break; break;
} }
case WSCONS_EVENT_MOUSE_DELTA_Z: case WSCONS_EVENT_MOUSE_DELTA_Z:
{ {
SDL_SendMouseWheel(0, mouse->focus, input->mouseID, 0, -events[i].value, SDL_MOUSEWHEEL_NORMAL); const float scale = 1.0f;
SDL_SendRawMouseWheel(timestamp, input->mouseID, 0, -events[i].value, scale, scale);
SDL_SendMouseWheel(timestamp, mouse->focus, input->mouseID, 0, -events[i].value, SDL_MOUSEWHEEL_NORMAL);
break; break;
} }
default:
break;
} }
} }
} }

View file

@ -62,6 +62,8 @@ SDL_EventCategory SDL_GetEventCategory(Uint32 type)
case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_DOWN:
case SDL_EVENT_KEY_UP: case SDL_EVENT_KEY_UP:
case SDL_EVENT_RAW_KEY_DOWN:
case SDL_EVENT_RAW_KEY_UP:
return SDL_EVENTCATEGORY_KEY; return SDL_EVENTCATEGORY_KEY;
case SDL_EVENT_TEXT_EDITING: case SDL_EVENT_TEXT_EDITING:
@ -78,13 +80,17 @@ SDL_EventCategory SDL_GetEventCategory(Uint32 type)
return SDL_EVENTCATEGORY_EDIT_CANDIDATES; return SDL_EVENTCATEGORY_EDIT_CANDIDATES;
case SDL_EVENT_MOUSE_MOTION: case SDL_EVENT_MOUSE_MOTION:
case SDL_EVENT_RAW_MOUSE_MOTION:
return SDL_EVENTCATEGORY_MOTION; return SDL_EVENTCATEGORY_MOTION;
case SDL_EVENT_MOUSE_BUTTON_DOWN: case SDL_EVENT_MOUSE_BUTTON_DOWN:
case SDL_EVENT_MOUSE_BUTTON_UP: case SDL_EVENT_MOUSE_BUTTON_UP:
case SDL_EVENT_RAW_MOUSE_BUTTON_DOWN:
case SDL_EVENT_RAW_MOUSE_BUTTON_UP:
return SDL_EVENTCATEGORY_BUTTON; return SDL_EVENTCATEGORY_BUTTON;
case SDL_EVENT_MOUSE_WHEEL: case SDL_EVENT_MOUSE_WHEEL:
case SDL_EVENT_RAW_MOUSE_WHEEL:
return SDL_EVENTCATEGORY_WHEEL; return SDL_EVENTCATEGORY_WHEEL;
case SDL_EVENT_MOUSE_ADDED: case SDL_EVENT_MOUSE_ADDED:

View file

@ -390,7 +390,7 @@ static void SDL_LogEvent(const SDL_Event *event)
// sensor/mouse/pen/finger motion are spammy, ignore these if they aren't demanded. // sensor/mouse/pen/finger motion are spammy, ignore these if they aren't demanded.
if ((SDL_EventLoggingVerbosity < 2) && if ((SDL_EventLoggingVerbosity < 2) &&
((event->type == SDL_EVENT_MOUSE_MOTION) || ((event->type == SDL_EVENT_MOUSE_MOTION) ||
(event->type == SDL_EVENT_MOUSE_RAW_MOTION) || (event->type == SDL_EVENT_RAW_MOUSE_MOTION) ||
(event->type == SDL_EVENT_FINGER_MOTION) || (event->type == SDL_EVENT_FINGER_MOTION) ||
(event->type == SDL_EVENT_PEN_AXIS) || (event->type == SDL_EVENT_PEN_AXIS) ||
(event->type == SDL_EVENT_PEN_MOTION) || (event->type == SDL_EVENT_PEN_MOTION) ||
@ -535,6 +535,19 @@ static void SDL_LogEvent(const SDL_Event *event)
break; break;
#undef PRINT_KEY_EVENT #undef PRINT_KEY_EVENT
#define PRINT_RAW_KEY_EVENT(event) \
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u state=%s scancode=%u)", \
(uint)event->raw_key.timestamp, (uint)event->raw_key.which, \
event->raw_key.down ? "pressed" : "released", \
(uint)event->raw_key.scancode);
SDL_EVENT_CASE(SDL_EVENT_RAW_KEY_DOWN)
PRINT_RAW_KEY_EVENT(event);
break;
SDL_EVENT_CASE(SDL_EVENT_RAW_KEY_UP)
PRINT_RAW_KEY_EVENT(event);
break;
#undef PRINT_RAW_KEY_EVENT
SDL_EVENT_CASE(SDL_EVENT_TEXT_EDITING) SDL_EVENT_CASE(SDL_EVENT_TEXT_EDITING)
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u text='%s' start=%d length=%d)", (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u text='%s' start=%d length=%d)",
(uint)event->edit.timestamp, (uint)event->edit.windowID, (uint)event->edit.timestamp, (uint)event->edit.windowID,
@ -568,6 +581,13 @@ static void SDL_LogEvent(const SDL_Event *event)
event->motion.xrel, event->motion.yrel); event->motion.xrel, event->motion.yrel);
break; break;
SDL_EVENT_CASE(SDL_EVENT_RAW_MOUSE_MOTION)
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u dx=%d dy=%d)",
(uint)event->raw_motion.timestamp,
(uint)event->raw_motion.which,
(int)event->raw_motion.dx, (int)event->raw_motion.dy);
break;
#define PRINT_MBUTTON_EVENT(event) \ #define PRINT_MBUTTON_EVENT(event) \
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u button=%u state=%s clicks=%u x=%g y=%g)", \ (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u button=%u state=%s clicks=%u x=%g y=%g)", \
(uint)event->button.timestamp, (uint)event->button.windowID, \ (uint)event->button.timestamp, (uint)event->button.windowID, \
@ -582,6 +602,19 @@ static void SDL_LogEvent(const SDL_Event *event)
break; break;
#undef PRINT_MBUTTON_EVENT #undef PRINT_MBUTTON_EVENT
#define PRINT_RAW_MBUTTON_EVENT(event) \
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u button=%u state=%s)", \
(uint)event->raw_button.timestamp, \
(uint)event->raw_button.which, (uint)event->raw_button.button, \
event->raw_button.down ? "pressed" : "released");
SDL_EVENT_CASE(SDL_EVENT_RAW_MOUSE_BUTTON_DOWN)
PRINT_RAW_MBUTTON_EVENT(event);
break;
SDL_EVENT_CASE(SDL_EVENT_RAW_MOUSE_BUTTON_UP)
PRINT_RAW_MBUTTON_EVENT(event);
break;
#undef PRINT_RAW_MBUTTON_EVENT
SDL_EVENT_CASE(SDL_EVENT_MOUSE_WHEEL) SDL_EVENT_CASE(SDL_EVENT_MOUSE_WHEEL)
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u x=%g y=%g direction=%s)", (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u x=%g y=%g direction=%s)",
(uint)event->wheel.timestamp, (uint)event->wheel.windowID, (uint)event->wheel.timestamp, (uint)event->wheel.windowID,
@ -589,6 +622,13 @@ static void SDL_LogEvent(const SDL_Event *event)
event->wheel.direction == SDL_MOUSEWHEEL_NORMAL ? "normal" : "flipped"); event->wheel.direction == SDL_MOUSEWHEEL_NORMAL ? "normal" : "flipped");
break; break;
SDL_EVENT_CASE(SDL_EVENT_RAW_MOUSE_WHEEL)
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u dx=%d dy=%d)",
(uint)event->raw_wheel.timestamp,
(uint)event->raw_wheel.which,
(int)event->raw_wheel.dx, (int)event->raw_wheel.dy);
break;
SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_AXIS_MOTION) SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_AXIS_MOTION)
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d axis=%u value=%d)", (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d axis=%u value=%d)",
(uint)event->jaxis.timestamp, (int)event->jaxis.which, (uint)event->jaxis.timestamp, (int)event->jaxis.which,
@ -1890,12 +1930,6 @@ void SDL_SetEventEnabled(Uint32 type, bool enabled)
if (type == SDL_EVENT_DROP_FILE || type == SDL_EVENT_DROP_TEXT) { if (type == SDL_EVENT_DROP_FILE || type == SDL_EVENT_DROP_TEXT) {
SDL_ToggleDragAndDropSupport(); SDL_ToggleDragAndDropSupport();
} }
if (type == SDL_EVENT_MOUSE_RAW_MOTION ||
type == SDL_EVENT_MOUSE_RAW_SCROLL ||
type == SDL_EVENT_MOUSE_RAW_BUTTON) {
SDL_UpdateRawMouseDataEnabled();
}
} }
} }
@ -1984,9 +2018,6 @@ bool SDL_InitEvents(void)
return false; return false;
} }
SDL_SetEventEnabled(SDL_EVENT_MOUSE_RAW_MOTION, false);
SDL_SetEventEnabled(SDL_EVENT_MOUSE_RAW_SCROLL, false);
SDL_SetEventEnabled(SDL_EVENT_MOUSE_RAW_BUTTON, false);
SDL_InitQuit(); SDL_InitQuit();
return true; return true;

View file

@ -690,6 +690,22 @@ bool SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode)
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, true); return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, true);
} }
void SDL_SendRawKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down)
{
const SDL_EventType type = down ? SDL_EVENT_RAW_KEY_DOWN : SDL_EVENT_RAW_KEY_UP;
if (SDL_EventEnabled(type)) {
SDL_Event event;
event.type = type;
event.common.timestamp = timestamp;
event.raw_key.which = keyboardID;
event.raw_key.scancode = scancode;
event.raw_key.raw = rawcode;
event.raw_key.down = down;
SDL_PushEvent(&event);
}
}
void SDL_ReleaseAutoReleaseKeys(void) void SDL_ReleaseAutoReleaseKeys(void)
{ {
SDL_Keyboard *keyboard = &SDL_keyboard; SDL_Keyboard *keyboard = &SDL_keyboard;

View file

@ -63,6 +63,9 @@ extern bool SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scanco
Most platforms should prefer to optionally call SDL_SetKeymap and then use SDL_SendKeyboardKey. */ Most platforms should prefer to optionally call SDL_SetKeymap and then use SDL_SendKeyboardKey. */
extern bool SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, SDL_Keycode keycode, bool down); extern bool SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, SDL_Keycode keycode, bool down);
// Send a raw keyboard key event
extern void SDL_SendRawKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down);
// Release all the autorelease keys // Release all the autorelease keys
extern void SDL_ReleaseAutoReleaseKeys(void); extern void SDL_ReleaseAutoReleaseKeys(void);

View file

@ -597,34 +597,6 @@ void SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouse
SDL_PrivateSendMouseMotion(timestamp, window, mouseID, relative, x, y); SDL_PrivateSendMouseMotion(timestamp, window, mouseID, relative, x, y);
} }
void SDL_SendRawMouseAxis(Uint64 timestamp, SDL_MouseID mouseID, int dx, int dy, float ux, float uy, SDL_EventType type)
{
if (SDL_EventEnabled(type)) {
SDL_Event event;
event.type = type;
event.common.timestamp = timestamp;
event.maxis.which = mouseID;
event.maxis.dx = dx;
event.maxis.dy = dy;
event.maxis.ux = ux;
event.maxis.uy = uy;
SDL_PushEvent(&event);
}
}
void SDL_SendRawMouseButton(Uint64 timestamp, SDL_MouseID mouseID, Uint8 state, Uint8 button)
{
if (SDL_EventEnabled(SDL_EVENT_MOUSE_RAW_BUTTON)) {
SDL_Event event;
event.type = SDL_EVENT_MOUSE_RAW_BUTTON;
event.common.timestamp = timestamp;
event.mbutton.which = mouseID;
event.mbutton.button = button;
event.mbutton.state = state;
SDL_PushEvent(&event);
}
}
static void ConstrainMousePosition(SDL_Mouse *mouse, SDL_Window *window, float *x, float *y) static void ConstrainMousePosition(SDL_Mouse *mouse, SDL_Window *window, float *x, float *y)
{ {
/* make sure that the pointers find themselves inside the windows, /* make sure that the pointers find themselves inside the windows,
@ -998,6 +970,51 @@ void SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseI
} }
} }
void SDL_SendRawMouseMotion(Uint64 timestamp, SDL_MouseID mouseID, int dx, int dy, float scale_x, float scale_y)
{
if (SDL_EventEnabled(SDL_EVENT_RAW_MOUSE_MOTION)) {
SDL_Event event;
event.type = SDL_EVENT_RAW_MOUSE_MOTION;
event.common.timestamp = timestamp;
event.raw_motion.which = mouseID;
event.raw_motion.dx = dx;
event.raw_motion.dy = dy;
event.raw_motion.scale_x = scale_x;
event.raw_motion.scale_y = scale_y;
SDL_PushEvent(&event);
}
}
void SDL_SendRawMouseButton(Uint64 timestamp, SDL_MouseID mouseID, Uint8 button, bool down)
{
const SDL_EventType type = down ? SDL_EVENT_RAW_MOUSE_BUTTON_DOWN : SDL_EVENT_RAW_MOUSE_BUTTON_UP;
if (SDL_EventEnabled(type)) {
SDL_Event event;
event.type = type;
event.common.timestamp = timestamp;
event.raw_button.which = mouseID;
event.raw_button.button = button;
event.raw_button.down = down;
SDL_PushEvent(&event);
}
}
void SDL_SendRawMouseWheel(Uint64 timestamp, SDL_MouseID mouseID, int dx, int dy, float scale_x, float scale_y)
{
if (SDL_EventEnabled(SDL_EVENT_RAW_MOUSE_WHEEL)) {
SDL_Event event;
event.type = SDL_EVENT_RAW_MOUSE_WHEEL;
event.common.timestamp = timestamp;
event.raw_wheel.which = mouseID;
event.raw_wheel.dx = dx;
event.raw_wheel.dy = dy;
event.raw_wheel.scale_x = scale_x;
event.raw_wheel.scale_y = scale_y;
SDL_PushEvent(&event);
}
}
void SDL_QuitMouse(void) void SDL_QuitMouse(void)
{ {
SDL_Cursor *cursor, *next; SDL_Cursor *cursor, *next;

View file

@ -169,12 +169,6 @@ extern bool SDL_UpdateMouseCapture(bool force_release);
// Send a mouse motion event // Send a mouse motion event
extern void SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, bool relative, float x, float y); extern void SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, bool relative, float x, float y);
/* Send a raw mouse motion or scroll event */
extern void SDL_SendRawMouseAxis(Uint64 timestamp, SDL_MouseID mouseID, int dx, int dy, float ux, float uy, SDL_EventType type);
/* Send a raw mouse button event */
extern void SDL_SendRawMouseButton(Uint64 timestamp, SDL_MouseID mouseID, Uint8 state, Uint8 button);
// Send a mouse button event // Send a mouse button event
extern void SDL_SendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 button, bool down); extern void SDL_SendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 button, bool down);
@ -184,6 +178,15 @@ extern void SDL_SendMouseButtonClicks(Uint64 timestamp, SDL_Window *window, SDL_
// Send a mouse wheel event // Send a mouse wheel event
extern void SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction); extern void SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction);
// Send raw mouse motion
extern void SDL_SendRawMouseMotion(Uint64 timestamp, SDL_MouseID mouseID, int dx, int dy, float scale_x, float scale_y);
// Send a raw mouse button event
extern void SDL_SendRawMouseButton(Uint64 timestamp, SDL_MouseID mouseID, Uint8 button, bool down);
// Send a raw mouse wheel event
extern void SDL_SendRawMouseWheel(Uint64 timestamp, SDL_MouseID mouseID, int dx, int dy, float scale_x, float scale_y);
// Warp the mouse within the window, potentially overriding relative mode // Warp the mouse within the window, potentially overriding relative mode
extern void SDL_PerformWarpMouseInWindow(SDL_Window *window, float x, float y, bool ignore_relative_mode); extern void SDL_PerformWarpMouseInWindow(SDL_Window *window, float x, float y, bool ignore_relative_mode);

View file

@ -2881,6 +2881,8 @@ bool SDL_ConvertEventToRenderCoordinates(SDL_Renderer *renderer, SDL_Event *even
SDL_RenderCoordinatesFromWindow(renderer, event->motion.x, event->motion.y, &event->motion.x, &event->motion.y); SDL_RenderCoordinatesFromWindow(renderer, event->motion.x, event->motion.y, &event->motion.x, &event->motion.y);
SDL_RenderVectorFromWindow(renderer, event->motion.xrel, event->motion.yrel, &event->motion.xrel, &event->motion.yrel); SDL_RenderVectorFromWindow(renderer, event->motion.xrel, event->motion.yrel, &event->motion.xrel, &event->motion.yrel);
} }
} else if (event->type == SDL_EVENT_RAW_MOUSE_MOTION) {
SDL_RenderVectorFromWindow(renderer, event->raw_motion.scale_x, event->raw_motion.scale_y, &event->raw_motion.scale_x, &event->raw_motion.scale_y);
} else if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN || } else if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN ||
event->type == SDL_EVENT_MOUSE_BUTTON_UP) { event->type == SDL_EVENT_MOUSE_BUTTON_UP) {
SDL_Window *window = SDL_GetWindowFromID(event->button.windowID); SDL_Window *window = SDL_GetWindowFromID(event->button.windowID);

View file

@ -1784,6 +1784,11 @@ void SDLTest_PrintEvent(const SDL_Event *event)
event->motion.xrel, event->motion.yrel, event->motion.xrel, event->motion.yrel,
event->motion.windowID); event->motion.windowID);
break; break;
case SDL_EVENT_RAW_MOUSE_MOTION:
SDL_Log("SDL EVENT: Raw Mouse: mouse %" SDL_PRIu32 " moved %" SDL_PRIs32 ",%" SDL_PRIs32,
event->raw_motion.which,
event->raw_motion.dx, event->raw_motion.dy);
break;
case SDL_EVENT_MOUSE_BUTTON_DOWN: case SDL_EVENT_MOUSE_BUTTON_DOWN:
SDL_Log("SDL EVENT: Mouse: button %d pressed at %g,%g with click count %d in window %" SDL_PRIu32, SDL_Log("SDL EVENT: Mouse: button %d pressed at %g,%g with click count %d in window %" SDL_PRIu32,
event->button.button, event->button.x, event->button.y, event->button.clicks, event->button.button, event->button.x, event->button.y, event->button.clicks,
@ -1794,10 +1799,22 @@ void SDLTest_PrintEvent(const SDL_Event *event)
event->button.button, event->button.x, event->button.y, event->button.clicks, event->button.button, event->button.x, event->button.y, event->button.clicks,
event->button.windowID); event->button.windowID);
break; break;
case SDL_EVENT_RAW_MOUSE_BUTTON_DOWN:
SDL_Log("SDL EVENT: Raw Mouse: mouse %" SDL_PRIu32 " button %d pressed",
event->raw_button.which, event->raw_button.button);
break;
case SDL_EVENT_RAW_MOUSE_BUTTON_UP:
SDL_Log("SDL EVENT: Raw Mouse: mouse %" SDL_PRIu32 " button %d released",
event->raw_button.which, event->raw_button.button);
break;
case SDL_EVENT_MOUSE_WHEEL: case SDL_EVENT_MOUSE_WHEEL:
SDL_Log("SDL EVENT: Mouse: wheel scrolled %g in x and %g in y (reversed: %d) in window %" SDL_PRIu32, SDL_Log("SDL EVENT: Mouse: wheel scrolled %g in x and %g in y (reversed: %d) in window %" SDL_PRIu32,
event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID); event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID);
break; break;
case SDL_EVENT_RAW_MOUSE_WHEEL:
SDL_Log("SDL EVENT: Raw Mouse: mouse %" SDL_PRIu32 " wheel scrolled %" SDL_PRIs32 " in x and %" SDL_PRIs32 " in y",
event->raw_wheel.which, event->raw_wheel.dx, event->raw_wheel.dy);
break;
case SDL_EVENT_JOYSTICK_ADDED: case SDL_EVENT_JOYSTICK_ADDED:
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " attached", SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " attached",
event->jdevice.which); event->jdevice.which);
@ -2221,6 +2238,7 @@ SDL_AppResult SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const
if (state->verbose & VERBOSE_EVENT) { if (state->verbose & VERBOSE_EVENT) {
if ((event->type != SDL_EVENT_MOUSE_MOTION && if ((event->type != SDL_EVENT_MOUSE_MOTION &&
event->type != SDL_EVENT_RAW_MOUSE_MOTION &&
event->type != SDL_EVENT_FINGER_MOTION && event->type != SDL_EVENT_FINGER_MOTION &&
event->type != SDL_EVENT_PEN_MOTION && event->type != SDL_EVENT_PEN_MOTION &&
event->type != SDL_EVENT_PEN_AXIS && event->type != SDL_EVENT_PEN_AXIS &&

View file

@ -385,9 +385,6 @@ struct SDL_VideoDevice
// Display the system-level window menu // Display the system-level window menu
void (*ShowWindowSystemMenu)(SDL_Window *window, int x, int y); void (*ShowWindowSystemMenu)(SDL_Window *window, int x, int y);
/* Re-synchronize platform raw input subscription */
bool (*RefreshRawInput)(SDL_VideoDevice *_this);
/* * * */ /* * * */
// Data common to all drivers // Data common to all drivers
SDL_ThreadID thread; SDL_ThreadID thread;

View file

@ -2109,13 +2109,6 @@ void SDL_ToggleDragAndDropSupport(void)
} }
} }
void SDL_UpdateRawMouseDataEnabled(void)
{
if (_this && _this->RefreshRawInput) {
_this->RefreshRawInput(_this);
}
}
SDL_Window **SDLCALL SDL_GetWindows(int *count) SDL_Window **SDLCALL SDL_GetWindows(int *count)
{ {
if (count) { if (count) {

View file

@ -1210,9 +1210,11 @@ static bool OPENVR_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
static void OPENVR_HandleMouse(float x, float y, int btn, int evt) static void OPENVR_HandleMouse(float x, float y, int btn, int evt)
{ {
if (evt == 2) { if (evt == 2) {
SDL_SendMouseMotion(0, 0, 0, false, (int)x, (int)y); SDL_SendMouseMotion(0, NULL, SDL_GLOBAL_MOUSE_ID, false, x, y);
} else { } else {
SDL_SendMouseButton(0, 0, 0, btn + 1, (evt != 0)); const Uint8 button = SDL_BUTTON_LEFT + btn;
const bool down = (evt != 0);
SDL_SendMouseButton(0, NULL, SDL_GLOBAL_MOUSE_ID, button, down);
} }
} }

View file

@ -187,7 +187,9 @@ static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0
SDL_AddKeyboard(keyboardID, NULL, true); SDL_AddKeyboard(keyboardID, NULL, true);
keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *kbrd, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed) { keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *kbrd, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed) {
SDL_SendKeyboardKey(0, keyboardID, 0, (SDL_Scancode)keyCode, pressed); Uint64 timestamp = SDL_GetTicksNS();
SDL_SendRawKeyboardKey(timestamp, keyboardID, 0, (SDL_Scancode)keyCode, pressed);
SDL_SendKeyboardKey(timestamp, keyboardID, 0, (SDL_Scancode)keyCode, pressed);
}; };
dispatch_queue_t queue = dispatch_queue_create("org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL); dispatch_queue_t queue = dispatch_queue_create("org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL);
@ -318,7 +320,9 @@ static bool SetGCMouseRelativeMode(bool enabled)
static void OnGCMouseButtonChanged(SDL_MouseID mouseID, Uint8 button, BOOL pressed) static void OnGCMouseButtonChanged(SDL_MouseID mouseID, Uint8 button, BOOL pressed)
{ {
SDL_SendMouseButton(0, SDL_GetMouseFocus(), mouseID, button, pressed); Uint64 timestamp = SDL_GetTicksNS();
SDL_SendRawMouseButton(timestamp, mouseID, button, pressed);
SDL_SendMouseButton(timestamp, SDL_GetMouseFocus(), mouseID, button, pressed);
} }
static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
@ -346,12 +350,19 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14
} }
mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouseInput, float deltaX, float deltaY) { mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouseInput, float deltaX, float deltaY) {
Uint64 timestamp = SDL_GetTicksNS();
// FIXME: Do we get non-integer deltas here?
SDL_SendRawMouseMotion(timestamp, mouseID, (int)deltaX, (int)-deltaY, 1.0f, 1.0f);
if (SDL_GCMouseRelativeMode()) { if (SDL_GCMouseRelativeMode()) {
SDL_SendMouseMotion(0, SDL_GetMouseFocus(), mouseID, 1, deltaX, -deltaY); SDL_SendMouseMotion(timestamp, SDL_GetMouseFocus(), mouseID, true, deltaX, -deltaY);
} }
}; };
mouse.mouseInput.scroll.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { mouse.mouseInput.scroll.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) {
Uint64 timestamp = SDL_GetTicksNS();
/* Raw scroll values come in here, vertical values in the first axis, horizontal values in the second axis. /* Raw scroll values come in here, vertical values in the first axis, horizontal values in the second axis.
* The vertical values are negative moving the mouse wheel up and positive moving it down. * The vertical values are negative moving the mouse wheel up and positive moving it down.
* The horizontal values are negative moving the mouse wheel left and positive moving it right. * The horizontal values are negative moving the mouse wheel left and positive moving it right.
@ -359,12 +370,16 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14
*/ */
float vertical = -xValue; float vertical = -xValue;
float horizontal = yValue; float horizontal = yValue;
// FIXME: Do we get non-integer deltas here?
SDL_SendRawMouseWheel(timestamp, mouseID, (int)horizontal, (int)vertical, 1.0f, 1.0f);
if (mouse_scroll_direction == SDL_MOUSEWHEEL_FLIPPED) { if (mouse_scroll_direction == SDL_MOUSEWHEEL_FLIPPED) {
// Since these are raw values, we need to flip them ourselves // Since these are raw values, we need to flip them ourselves
vertical = -vertical; vertical = -vertical;
horizontal = -horizontal; horizontal = -horizontal;
} }
SDL_SendMouseWheel(0, SDL_GetMouseFocus(), mouseID, horizontal, vertical, mouse_scroll_direction); SDL_SendMouseWheel(timestamp, SDL_GetMouseFocus(), mouseID, horizontal, vertical, mouse_scroll_direction);
}; };
UpdateScrollDirection(); UpdateScrollDirection();

View file

@ -697,22 +697,12 @@ static void pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_
SDL_WindowData *window = input->pointer_focus; SDL_WindowData *window = input->pointer_focus;
enum wl_pointer_button_state state = state_w; enum wl_pointer_button_state state = state_w;
Uint64 timestamp = Wayland_GetPointerTimestamp(input, time); Uint64 timestamp = Wayland_GetPointerTimestamp(input, time);
Uint8 sdl_button;
if (SDL_EventEnabled(SDL_EVENT_MOUSE_RAW_BUTTON)) { const bool down = (state != 0);
SDL_SendRawMouseButton(timestamp, input->pointer_id, !!state, button);
}
if (window) {
SDL_VideoData *viddata = window->waylandData;
Uint32 sdl_button;
bool ignore_click = false;
switch (button) { switch (button) {
case BTN_LEFT: case BTN_LEFT:
sdl_button = SDL_BUTTON_LEFT; sdl_button = SDL_BUTTON_LEFT;
if (ProcessHitTest(input->pointer_focus, input->seat, input->sx_w, input->sy_w, serial)) {
return; // don't pass this event on to app.
}
break; break;
case BTN_MIDDLE: case BTN_MIDDLE:
sdl_button = SDL_BUTTON_MIDDLE; sdl_button = SDL_BUTTON_MIDDLE;
@ -729,6 +719,16 @@ static void pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_
default: default:
return; return;
} }
SDL_SendRawMouseButton(timestamp, input->pointer_id, sdl_button, down);
if (window) {
SDL_VideoData *viddata = window->waylandData;
bool ignore_click = false;
if (sdl_button == SDL_BUTTON_LEFT &&
ProcessHitTest(input->pointer_focus, input->seat, input->sx_w, input->sy_w, serial)) {
return; // don't pass this event on to app.
}
// Possibly ignore this click if it was to gain focus. // Possibly ignore this click if it was to gain focus.
if (window->last_focus_event_time_ns) { if (window->last_focus_event_time_ns) {
@ -765,8 +765,7 @@ static void pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_
} }
if (!ignore_click) { if (!ignore_click) {
SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, time), window->sdlwindow, input->pointer_id, SDL_SendMouseButton(timestamp, window->sdlwindow, input->pointer_id, sdl_button, down);
sdl_button, !!state);
} }
} }
} }
@ -786,15 +785,13 @@ static void pointer_handle_axis_common_v1(struct SDL_WaylandInput *input,
const Uint64 timestamp = Wayland_GetPointerTimestamp(input, time); const Uint64 timestamp = Wayland_GetPointerTimestamp(input, time);
const enum wl_pointer_axis a = axis; const enum wl_pointer_axis a = axis;
if (SDL_EventEnabled(SDL_EVENT_MOUSE_RAW_SCROLL)) {
// wl_fixed_t is a 24.8 signed fixed-point number which needs to be converted by dividing by 256 // wl_fixed_t is a 24.8 signed fixed-point number which needs to be converted by dividing by 256
const float denom = (float)(WAYLAND_WHEEL_AXIS_UNIT * 256); const float scale = 1.0f / WAYLAND_WHEEL_AXIS_UNIT;
const int amount = (value * WAYLAND_WHEEL_AXIS_UNIT) >> 8;
if (a == WL_POINTER_AXIS_VERTICAL_SCROLL) { if (a == WL_POINTER_AXIS_VERTICAL_SCROLL) {
SDL_SendRawMouseAxis(timestamp, input->pointer_id, 0, (int)value, 0.f, denom, SDL_EVENT_MOUSE_RAW_SCROLL); SDL_SendRawMouseWheel(timestamp, input->pointer_id, 0, amount, scale, scale);
} else { } else {
SDL_SendRawMouseAxis(timestamp, input->pointer_id, (int)value, 0, denom, 0.f, SDL_EVENT_MOUSE_RAW_SCROLL); SDL_SendRawMouseWheel(timestamp, input->pointer_id, amount, 0, scale, scale);
}
} }
if (input->pointer_focus) { if (input->pointer_focus) {
@ -825,15 +822,13 @@ static void pointer_handle_axis_common(struct SDL_WaylandInput *input, enum SDL_
{ {
const enum wl_pointer_axis a = axis; const enum wl_pointer_axis a = axis;
if (SDL_EventEnabled(SDL_EVENT_MOUSE_RAW_SCROLL)) {
// wl_fixed_t is a 24.8 signed fixed-point number which needs to be converted by dividing by 256 // wl_fixed_t is a 24.8 signed fixed-point number which needs to be converted by dividing by 256
const float denom = (float)((type == AXIS_EVENT_VALUE120 ? 120 : WAYLAND_WHEEL_AXIS_UNIT) * 256); const float scale = (type == AXIS_EVENT_VALUE120) ? (1.0f / 120.0f) : (1.0f / WAYLAND_WHEEL_AXIS_UNIT);
const int amount = (type == AXIS_EVENT_VALUE120) ? (value >> 8) : ((value * WAYLAND_WHEEL_AXIS_UNIT) >> 8);
if (a == WL_POINTER_AXIS_VERTICAL_SCROLL) { if (a == WL_POINTER_AXIS_VERTICAL_SCROLL) {
SDL_SendRawMouseAxis(input->pointer_curr_axis_info.timestamp_ns, input->pointer_id, 0, (int)value, 0.f, denom, SDL_EVENT_MOUSE_RAW_SCROLL); SDL_SendRawMouseWheel(0, input->pointer_id, 0, amount, scale, scale);
} else { } else {
SDL_SendRawMouseAxis(input->pointer_curr_axis_info.timestamp_ns, input->pointer_id, (int)value, 0, denom, 0.f, SDL_EVENT_MOUSE_RAW_SCROLL); SDL_SendRawMouseWheel(0, input->pointer_id, amount, 0, scale, scale);
}
} }
if (input->pointer_focus) { if (input->pointer_focus) {
@ -1038,10 +1033,10 @@ static void relative_pointer_handle_relative_motion(void *data,
// 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));
if (SDL_EventEnabled(SDL_EVENT_MOUSE_RAW_MOTION)) {
// wl_fixed_t is a 24.8 signed fixed-point number which needs to be converted by dividing by 256 // wl_fixed_t is a 24.8 signed fixed-point number which needs to be converted by dividing by 256
SDL_SendRawMouseAxis(timestamp, input->pointer_id, (int)dx_unaccel_w, (int)dy_unaccel_w, 256.0f, 256.0f, SDL_EVENT_MOUSE_RAW_MOTION); const float scale_x = dx_unaccel_w ? (dx_w / (float)dx_unaccel_w) : 1.0f;
} const float scale_y = dy_unaccel_w ? (dy_w / (float)dy_unaccel_w) : 1.0f;
SDL_SendRawMouseMotion(timestamp, input->pointer_id, dx_unaccel_w >> 8, dy_unaccel_w >> 8, scale_x, scale_y);
if (input->pointer_focus && d->relative_mouse_mode) { if (input->pointer_focus && d->relative_mouse_mode) {
double dx; double dx;
@ -1719,7 +1714,8 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
} }
#endif #endif
window->last_focus_event_time_ns = SDL_GetTicksNS(); Uint64 timestamp = SDL_GetTicksNS();
window->last_focus_event_time_ns = timestamp;
wl_array_for_each (key, keys) { wl_array_for_each (key, keys) {
const SDL_Scancode scancode = Wayland_get_scancode_from_key(input, *key + 8); const SDL_Scancode scancode = Wayland_get_scancode_from_key(input, *key + 8);
@ -1736,7 +1732,8 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
case SDLK_RGUI: case SDLK_RGUI:
case SDLK_MODE: case SDLK_MODE:
Wayland_HandleModifierKeys(input, scancode, true); Wayland_HandleModifierKeys(input, scancode, true);
SDL_SendKeyboardKeyIgnoreModifiers(0, input->keyboard_id, *key, scancode, true); SDL_SendRawKeyboardKey(timestamp, input->keyboard_id, *key, scancode, true);
SDL_SendKeyboardKeyIgnoreModifiers(timestamp, input->keyboard_id, *key, scancode, true);
break; break;
default: default:
break; break;
@ -1872,7 +1869,9 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
scancode = Wayland_get_scancode_from_key(input, key + 8); scancode = Wayland_get_scancode_from_key(input, key + 8);
Wayland_HandleModifierKeys(input, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED); Wayland_HandleModifierKeys(input, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED);
SDL_SendKeyboardKeyIgnoreModifiers(Wayland_GetKeyboardTimestamp(input, time), input->keyboard_id, key, scancode, (state == WL_KEYBOARD_KEY_STATE_PRESSED)); Uint64 timestamp = Wayland_GetKeyboardTimestamp(input, time);
SDL_SendRawKeyboardKey(timestamp, input->keyboard_id, key, scancode, (state == WL_KEYBOARD_KEY_STATE_PRESSED));
SDL_SendKeyboardKeyIgnoreModifiers(timestamp, input->keyboard_id, key, scancode, (state == WL_KEYBOARD_KEY_STATE_PRESSED));
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
if (has_text && !(SDL_GetModState() & SDL_KMOD_CTRL)) { if (has_text && !(SDL_GetModState() & SDL_KMOD_CTRL)) {

View file

@ -521,46 +521,66 @@ static bool WIN_SwapButtons(HANDLE hDevice)
static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDLE hDevice, RAWMOUSE *rawmouse) static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDLE hDevice, RAWMOUSE *rawmouse)
{ {
int xraw = (int)rawmouse->lLastX; static struct {
int yraw = (int)rawmouse->lLastY; USHORT usButtonFlags;
bool haveMotion = (xraw || yraw) ? true : false; Uint8 button;
bool haveButton = (rawmouse->usButtonFlags) ? true : false; bool down;
bool isAbsolute = (rawmouse->usFlags & MOUSE_MOVE_ABSOLUTE) ? true : false; } raw_buttons[] = {
{ RI_MOUSE_LEFT_BUTTON_DOWN, SDL_BUTTON_LEFT, true },
{ RI_MOUSE_LEFT_BUTTON_UP, SDL_BUTTON_LEFT, false },
{ RI_MOUSE_RIGHT_BUTTON_DOWN, SDL_BUTTON_RIGHT, true },
{ RI_MOUSE_RIGHT_BUTTON_UP, SDL_BUTTON_RIGHT, false },
{ RI_MOUSE_MIDDLE_BUTTON_DOWN, SDL_BUTTON_MIDDLE, true },
{ RI_MOUSE_MIDDLE_BUTTON_UP, SDL_BUTTON_MIDDLE, false },
{ RI_MOUSE_BUTTON_4_DOWN, SDL_BUTTON_X1, true },
{ RI_MOUSE_BUTTON_4_UP, SDL_BUTTON_X1, false },
{ RI_MOUSE_BUTTON_5_DOWN, SDL_BUTTON_X2, true },
{ RI_MOUSE_BUTTON_5_UP, SDL_BUTTON_X2, false }
};
int dx = (int)rawmouse->lLastX;
int dy = (int)rawmouse->lLastY;
bool haveMotion = (dx || dy);
bool haveButton = (rawmouse->usButtonFlags != 0);
bool isAbsolute = ((rawmouse->usFlags & MOUSE_MOVE_ABSOLUTE) != 0);
SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)hDevice; SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)hDevice;
if (SDL_EventEnabled(SDL_EVENT_MOUSE_RAW_MOTION)) {
if (haveMotion && !isAbsolute) { if (haveMotion && !isAbsolute) {
SDL_SendRawMouseAxis(timestamp, mouseID, xraw, yraw, 1.0f, 1.0f, SDL_EVENT_MOUSE_RAW_MOTION); // FIXME: Apply desktop mouse scale?
const float scale = 1.0f;
SDL_SendRawMouseMotion(timestamp, mouseID, dx, dy, scale, scale);
}
if (haveButton) {
for (int i = 0; i < SDL_arraysize(raw_buttons); ++i) {
if (rawmouse->usButtonFlags & raw_buttons[i].usButtonFlags) {
Uint8 button = raw_buttons[i].button;
bool down = raw_buttons[i].down;
if (button == SDL_BUTTON_LEFT) {
if (WIN_SwapButtons(hDevice)) {
button = SDL_BUTTON_RIGHT;
}
} else if (button == SDL_BUTTON_RIGHT) {
if (WIN_SwapButtons(hDevice)) {
button = SDL_BUTTON_LEFT;
} }
} }
if (SDL_EventEnabled(SDL_EVENT_MOUSE_RAW_BUTTON)) { SDL_SendRawMouseButton(timestamp, mouseID, button, down);
if (haveButton) {
USHORT flagBits = rawmouse->usButtonFlags;
for (Uint8 i = 0; i < 10; ++i) {
if (flagBits & 1) {
Uint8 state = (i & 1) ^ 1;
Uint8 button = (i >> 1) + 1;
SDL_SendRawMouseButton(timestamp, mouseID, state, button);
}
flagBits = flagBits >> 1;
}
} }
} }
if (SDL_EventEnabled(SDL_EVENT_MOUSE_RAW_SCROLL)) { const float scale = 1.0f / 120.0f;
if (haveButton) { SHORT amount = (SHORT)rawmouse->usButtonData;
short amount = (short)rawmouse->usButtonData;
if (rawmouse->usButtonFlags & RI_MOUSE_WHEEL) { if (rawmouse->usButtonFlags & RI_MOUSE_WHEEL) {
SDL_SendRawMouseAxis(timestamp, mouseID, 0, (int)amount, 120.0f, 120.0f, SDL_EVENT_MOUSE_RAW_SCROLL); SDL_SendRawMouseWheel(timestamp, mouseID, 0, amount, scale, scale);
} else if (rawmouse->usButtonFlags & RI_MOUSE_HWHEEL) { } else if (rawmouse->usButtonFlags & RI_MOUSE_HWHEEL) {
SDL_SendRawMouseAxis(timestamp, mouseID, (int)amount, 0, 120.0f, 120.0f, SDL_EVENT_MOUSE_RAW_SCROLL); SDL_SendRawMouseWheel(timestamp, mouseID, amount, 0, scale, scale);
}
} }
} }
// this check is for whether relative mode should also receive events from the rawinput stream, // Check whether relative mode should also receive events from the rawinput stream
// separate from whether or not the optional rawaxis/rawbutton events should be generated.
if (!data->raw_mouse_enabled) { if (!data->raw_mouse_enabled) {
return; return;
} }
@ -579,7 +599,7 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDL
if (haveMotion) { if (haveMotion) {
if (!isAbsolute) { if (!isAbsolute) {
SDL_SendMouseMotion(timestamp, window, mouseID, true, (float)xraw, (float)yraw); SDL_SendMouseMotion(timestamp, window, mouseID, true, (float)dx, (float)dy);
} else { } else {
/* This is absolute motion, either using a tablet or mouse over RDP /* This is absolute motion, either using a tablet or mouse over RDP
@ -591,13 +611,13 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDL
We handle this by creating a safe area within the application window, and when the mouse leaves that safe area, we warp back to the opposite side. Any single motion > 50% of the safe area is assumed to be a warp and ignored. We handle this by creating a safe area within the application window, and when the mouse leaves that safe area, we warp back to the opposite side. Any single motion > 50% of the safe area is assumed to be a warp and ignored.
*/ */
bool remote_desktop = GetSystemMetrics(SM_REMOTESESSION) ? true : false; bool remote_desktop = (GetSystemMetrics(SM_REMOTESESSION) == TRUE);
bool virtual_desktop = (rawmouse->usFlags & MOUSE_VIRTUAL_DESKTOP) ? true : false; bool virtual_desktop = ((rawmouse->usFlags & MOUSE_VIRTUAL_DESKTOP) != 0);
bool raw_coordinates = (rawmouse->usFlags & 0x40) ? true : false; bool raw_coordinates = ((rawmouse->usFlags & 0x40) != 0);
int w = GetSystemMetrics(virtual_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); int w = GetSystemMetrics(virtual_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
int h = GetSystemMetrics(virtual_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); int h = GetSystemMetrics(virtual_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);
int x = raw_coordinates ? (int)xraw : (int)(((float)xraw / 65535.0f) * w); int x = raw_coordinates ? dx : (int)(((float)dx / 65535.0f) * w);
int y = raw_coordinates ? (int)yraw : (int)(((float)yraw / 65535.0f) * h); int y = raw_coordinates ? dy : (int)(((float)dy / 65535.0f) * h);
int relX, relY; int relX, relY;
/* Calculate relative motion */ /* Calculate relative motion */
@ -655,23 +675,6 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDL
} }
if (haveButton) { if (haveButton) {
static struct {
USHORT usButtonFlags;
Uint8 button;
bool down;
} raw_buttons[] = {
{ RI_MOUSE_LEFT_BUTTON_DOWN, SDL_BUTTON_LEFT, true },
{ RI_MOUSE_LEFT_BUTTON_UP, SDL_BUTTON_LEFT, false },
{ RI_MOUSE_RIGHT_BUTTON_DOWN, SDL_BUTTON_RIGHT, true },
{ RI_MOUSE_RIGHT_BUTTON_UP, SDL_BUTTON_RIGHT, false },
{ RI_MOUSE_MIDDLE_BUTTON_DOWN, SDL_BUTTON_MIDDLE, true },
{ RI_MOUSE_MIDDLE_BUTTON_UP, SDL_BUTTON_MIDDLE, false },
{ RI_MOUSE_BUTTON_4_DOWN, SDL_BUTTON_X1, true },
{ RI_MOUSE_BUTTON_4_UP, SDL_BUTTON_X1, false },
{ RI_MOUSE_BUTTON_5_DOWN, SDL_BUTTON_X2, true },
{ RI_MOUSE_BUTTON_5_UP, SDL_BUTTON_X2, false }
};
for (int i = 0; i < SDL_arraysize(raw_buttons); ++i) { for (int i = 0; i < SDL_arraysize(raw_buttons); ++i) {
if (rawmouse->usButtonFlags & raw_buttons[i].usButtonFlags) { if (rawmouse->usButtonFlags & raw_buttons[i].usButtonFlags) {
Uint8 button = raw_buttons[i].button; Uint8 button = raw_buttons[i].button;
@ -703,11 +706,11 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDL
} }
if (rawmouse->usButtonFlags & RI_MOUSE_WHEEL) { if (rawmouse->usButtonFlags & RI_MOUSE_WHEEL) {
short amount = (short)rawmouse->usButtonData; SHORT amount = (SHORT)rawmouse->usButtonData;
float fAmount = (float)amount / WHEEL_DELTA; float fAmount = (float)amount / WHEEL_DELTA;
SDL_SendMouseWheel(WIN_GetEventTimestamp(), window, mouseID, 0.0f, fAmount, SDL_MOUSEWHEEL_NORMAL); SDL_SendMouseWheel(WIN_GetEventTimestamp(), window, mouseID, 0.0f, fAmount, SDL_MOUSEWHEEL_NORMAL);
} else if (rawmouse->usButtonFlags & RI_MOUSE_HWHEEL) { } else if (rawmouse->usButtonFlags & RI_MOUSE_HWHEEL) {
short amount = (short)rawmouse->usButtonData; SHORT amount = (SHORT)rawmouse->usButtonData;
float fAmount = (float)amount / WHEEL_DELTA; float fAmount = (float)amount / WHEEL_DELTA;
SDL_SendMouseWheel(WIN_GetEventTimestamp(), window, mouseID, fAmount, 0.0f, SDL_MOUSEWHEEL_NORMAL); SDL_SendMouseWheel(WIN_GetEventTimestamp(), window, mouseID, fAmount, 0.0f, SDL_MOUSEWHEEL_NORMAL);
} }
@ -718,10 +721,6 @@ static void WIN_HandleRawKeyboardInput(Uint64 timestamp, SDL_VideoData *data, HA
{ {
SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)hDevice; SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)hDevice;
if (!data->raw_keyboard_enabled) {
return;
}
if (rawkeyboard->Flags & RI_KEY_E1) { if (rawkeyboard->Flags & RI_KEY_E1) {
// First key in a Ctrl+{key} sequence // First key in a Ctrl+{key} sequence
data->pending_E1_key_sequence = true; data->pending_E1_key_sequence = true;
@ -764,6 +763,13 @@ static void WIN_HandleRawKeyboardInput(Uint64 timestamp, SDL_VideoData *data, HA
} }
code = windows_scancode_table[index]; code = windows_scancode_table[index];
} }
SDL_SendRawKeyboardKey(timestamp, keyboardID, rawcode, code, down);
if (!data->raw_keyboard_enabled) {
return;
}
if (down) { if (down) {
SDL_Window *focus = SDL_GetKeyboardFocus(); SDL_Window *focus = SDL_GetKeyboardFocus();
if (!focus || focus->text_input_active) { if (!focus || focus->text_input_active) {

View file

@ -291,6 +291,7 @@ static void GAMEINPUT_InitialMouseReading(WIN_GameInputData *data, SDL_Window *w
for (int i = 0; i < MAX_GAMEINPUT_BUTTONS; ++i) { for (int i = 0; i < MAX_GAMEINPUT_BUTTONS; ++i) {
const GameInputMouseButtons mask = (1 << i); const GameInputMouseButtons mask = (1 << i);
bool down = ((state.buttons & mask) != 0); bool down = ((state.buttons & mask) != 0);
SDL_SendRawMouseButton(timestamp, mouseID, GAMEINPUT_button_map[i], down);
SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down); SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down);
} }
} }
@ -313,6 +314,10 @@ static void GAMEINPUT_HandleMouseDelta(WIN_GameInputData *data, SDL_Window *wind
delta.wheelY = (state.wheelY - last.wheelY); delta.wheelY = (state.wheelY - last.wheelY);
if (delta.positionX || delta.positionY) { if (delta.positionX || delta.positionY) {
// FIXME: Apply desktop mouse scale?
const float scale = 1.0f;
SDL_SendRawMouseMotion(timestamp, mouseID, delta.positionX, delta.positionY, scale, scale);
SDL_SendMouseMotion(timestamp, window, mouseID, true, (float)delta.positionX, (float)delta.positionY); SDL_SendMouseMotion(timestamp, window, mouseID, true, (float)delta.positionX, (float)delta.positionY);
} }
if (delta.buttons) { if (delta.buttons) {
@ -320,11 +325,15 @@ static void GAMEINPUT_HandleMouseDelta(WIN_GameInputData *data, SDL_Window *wind
const GameInputMouseButtons mask = (1 << i); const GameInputMouseButtons mask = (1 << i);
if (delta.buttons & mask) { if (delta.buttons & mask) {
bool down = ((state.buttons & mask) != 0); bool down = ((state.buttons & mask) != 0);
SDL_SendRawMouseButton(timestamp, mouseID, GAMEINPUT_button_map[i], down);
SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down); SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down);
} }
} }
} }
if (delta.wheelX || delta.wheelY) { if (delta.wheelX || delta.wheelY) {
const float scale = 1.0f / WHEEL_DELTA;
SDL_SendRawMouseWheel(timestamp, device->instance_id, delta.wheelX, delta.wheelY, scale, scale);
float fAmountX = (float)delta.wheelX / WHEEL_DELTA; float fAmountX = (float)delta.wheelX / WHEEL_DELTA;
float fAmountY = (float)delta.wheelY / WHEEL_DELTA; float fAmountY = (float)delta.wheelY / WHEEL_DELTA;
SDL_SendMouseWheel(timestamp, SDL_GetMouseFocus(), device->instance_id, fAmountX, fAmountY, SDL_MOUSEWHEEL_NORMAL); SDL_SendMouseWheel(timestamp, SDL_GetMouseFocus(), device->instance_id, fAmountX, fAmountY, SDL_MOUSEWHEEL_NORMAL);
@ -374,12 +383,14 @@ static void GAMEINPUT_InitialKeyboardReading(WIN_GameInputData *data, SDL_Window
const bool *keyboard_state = SDL_GetKeyboardState(&num_scancodes); const bool *keyboard_state = SDL_GetKeyboardState(&num_scancodes);
for (int i = 0; i < num_scancodes; ++i) { for (int i = 0; i < num_scancodes; ++i) {
if (keyboard_state[i] && !KeysHaveScancode(keys, num_keys, (SDL_Scancode)i)) { if (keyboard_state[i] && !KeysHaveScancode(keys, num_keys, (SDL_Scancode)i)) {
SDL_SendRawKeyboardKey(timestamp, keyboardID, keys[i].scanCode, (SDL_Scancode)i, false);
SDL_SendKeyboardKey(timestamp, keyboardID, keys[i].scanCode, (SDL_Scancode)i, false); SDL_SendKeyboardKey(timestamp, keyboardID, keys[i].scanCode, (SDL_Scancode)i, false);
} }
} }
// Go through and send key down events for any key that's held down // Go through and send key down events for any key that's held down
for (uint32_t i = 0; i < num_keys; ++i) { for (uint32_t i = 0; i < num_keys; ++i) {
SDL_SendRawKeyboardKey(timestamp, keyboardID, keys[i].scanCode, GetScancodeFromKeyState(&keys[i]), true);
SDL_SendKeyboardKey(timestamp, keyboardID, keys[i].scanCode, GetScancodeFromKeyState(&keys[i]), true); SDL_SendKeyboardKey(timestamp, keyboardID, keys[i].scanCode, GetScancodeFromKeyState(&keys[i]), true);
} }
} }
@ -425,15 +436,18 @@ static void GAMEINPUT_HandleKeyboardDelta(WIN_GameInputData *data, SDL_Window *w
++index_keys; ++index_keys;
} else { } else {
// This key was released // This key was released
SDL_SendRawKeyboardKey(timestamp, keyboardID, last[index_last].scanCode, GetScancodeFromKeyState(&last[index_last]), false);
SDL_SendKeyboardKey(timestamp, keyboardID, last[index_last].scanCode, GetScancodeFromKeyState(&last[index_last]), false); SDL_SendKeyboardKey(timestamp, keyboardID, last[index_last].scanCode, GetScancodeFromKeyState(&last[index_last]), false);
++index_last; ++index_last;
} }
} else if (index_last < num_last) { } else if (index_last < num_last) {
// This key was released // This key was released
SDL_SendRawKeyboardKey(timestamp, keyboardID, last[index_last].scanCode, GetScancodeFromKeyState(&last[index_last]), false);
SDL_SendKeyboardKey(timestamp, keyboardID, last[index_last].scanCode, GetScancodeFromKeyState(&last[index_last]), false); SDL_SendKeyboardKey(timestamp, keyboardID, last[index_last].scanCode, GetScancodeFromKeyState(&last[index_last]), false);
++index_last; ++index_last;
} else { } else {
// This key was pressed // This key was pressed
SDL_SendRawKeyboardKey(timestamp, keyboardID, keys[index_keys].scanCode, GetScancodeFromKeyState(&keys[index_keys]), true);
SDL_SendKeyboardKey(timestamp, keyboardID, keys[index_keys].scanCode, GetScancodeFromKeyState(&keys[index_keys]), true); SDL_SendKeyboardKey(timestamp, keyboardID, keys[index_keys].scanCode, GetScancodeFromKeyState(&keys[index_keys]), true);
++index_keys; ++index_keys;
} }

View file

@ -193,13 +193,11 @@ static bool WIN_UpdateRawInputEnabled(SDL_VideoDevice *_this)
{ {
SDL_VideoData *data = _this->internal; SDL_VideoData *data = _this->internal;
Uint32 flags = 0; Uint32 flags = 0;
if (SDL_EventEnabled(SDL_EVENT_MOUSE_RAW_MOTION) || const bool ENABLE_RAW_INPUT_EVENTS = true;
SDL_EventEnabled(SDL_EVENT_MOUSE_RAW_SCROLL) || if (data->raw_mouse_enabled || ENABLE_RAW_INPUT_EVENTS) {
SDL_EventEnabled(SDL_EVENT_MOUSE_RAW_BUTTON) ||
data->raw_mouse_enabled) {
flags |= ENABLE_RAW_MOUSE_INPUT; flags |= ENABLE_RAW_MOUSE_INPUT;
} }
if (data->raw_keyboard_enabled) { if (data->raw_keyboard_enabled || ENABLE_RAW_INPUT_EVENTS) {
flags |= ENABLE_RAW_KEYBOARD_INPUT; flags |= ENABLE_RAW_KEYBOARD_INPUT;
} }
if (flags != data->raw_input_enabled) { if (flags != data->raw_input_enabled) {
@ -248,11 +246,6 @@ bool WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, bool enabled)
return true; return true;
} }
bool WIN_RefreshRawInputEnabled(SDL_VideoDevice *_this)
{
return WIN_UpdateRawInputEnabled(_this);
}
#else #else
bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled) bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled)
@ -265,10 +258,6 @@ bool WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, bool enabled)
return SDL_Unsupported(); return SDL_Unsupported();
} }
bool WIN_RefreshRawInputEnabled(SDL_VideoDevice *_this)
{
return SDL_Unsupported();
}
#endif // !SDL_PLATFORM_XBOXONE && !SDL_PLATFORM_XBOXSERIES #endif // !SDL_PLATFORM_XBOXONE && !SDL_PLATFORM_XBOXSERIES
#endif // SDL_VIDEO_DRIVER_WINDOWS #endif // SDL_VIDEO_DRIVER_WINDOWS

View file

@ -246,7 +246,6 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
device->OnWindowEnter = WIN_OnWindowEnter; device->OnWindowEnter = WIN_OnWindowEnter;
device->SetWindowHitTest = WIN_SetWindowHitTest; device->SetWindowHitTest = WIN_SetWindowHitTest;
device->AcceptDragAndDrop = WIN_AcceptDragAndDrop; device->AcceptDragAndDrop = WIN_AcceptDragAndDrop;
device->RefreshRawInput = WIN_RefreshRawInputEnabled;
device->FlashWindow = WIN_FlashWindow; device->FlashWindow = WIN_FlashWindow;
device->ShowWindowSystemMenu = WIN_ShowWindowSystemMenu; device->ShowWindowSystemMenu = WIN_ShowWindowSystemMenu;
device->SetWindowFocusable = WIN_SetWindowFocusable; device->SetWindowFocusable = WIN_SetWindowFocusable;

View file

@ -795,6 +795,12 @@ SDL_WindowData *X11_FindWindow(SDL_VideoDevice *_this, Window window)
return NULL; return NULL;
} }
Uint64 X11_GetEventTimestamp(unsigned long time)
{
// FIXME: Get the event time in the SDL tick time base
return SDL_GetTicksNS();
}
void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_KeyboardID keyboardID, XEvent *xevent) void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_KeyboardID keyboardID, XEvent *xevent)
{ {
SDL_VideoData *videodata = (SDL_VideoData *)_this->internal; SDL_VideoData *videodata = (SDL_VideoData *)_this->internal;
@ -805,6 +811,7 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_
char text[64]; char text[64];
Status status = 0; Status status = 0;
bool handled_by_ime = false; bool handled_by_ime = false;
Uint64 timestamp = X11_GetEventTimestamp(xevent->xkey.time);
#ifdef DEBUG_XEVENTS #ifdef DEBUG_XEVENTS
SDL_Log("window 0x%lx %s (X11 keycode = 0x%X)\n", xevent->xany.window, (xevent->type == KeyPress ? "KeyPress" : "KeyRelease"), xevent->xkey.keycode); SDL_Log("window 0x%lx %s (X11 keycode = 0x%X)\n", xevent->xany.window, (xevent->type == KeyPress ? "KeyPress" : "KeyRelease"), xevent->xkey.keycode);
@ -820,6 +827,11 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_
} }
#endif // DEBUG SCANCODES #endif // DEBUG SCANCODES
if (keyboardID != SDL_GLOBAL_KEYBOARD_ID) {
const bool down = (xevent->type == KeyPress);
SDL_SendRawKeyboardKey(timestamp, keyboardID, keycode, videodata->key_layout[keycode], down);
}
text[0] = '\0'; text[0] = '\0';
if (SDL_TextInputActive(windowdata->window)) { if (SDL_TextInputActive(windowdata->window)) {
@ -846,9 +858,9 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_
videodata->filter_time = xevent->xkey.time; videodata->filter_time = xevent->xkey.time;
if (orig_event_type == KeyPress) { if (orig_event_type == KeyPress) {
SDL_SendKeyboardKey(0, keyboardID, orig_keycode, scancode, true); SDL_SendKeyboardKey(timestamp, keyboardID, orig_keycode, scancode, true);
} else { } else {
SDL_SendKeyboardKey(0, keyboardID, orig_keycode, scancode, false); SDL_SendKeyboardKey(timestamp, keyboardID, orig_keycode, scancode, false);
} }
#endif #endif
return; return;
@ -874,7 +886,7 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_
if (xevent->type == KeyPress) { if (xevent->type == KeyPress) {
// Don't send the key if it looks like a duplicate of a filtered key sent by an IME // Don't send the key if it looks like a duplicate of a filtered key sent by an IME
if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) { if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) {
SDL_SendKeyboardKey(0, keyboardID, keycode, videodata->key_layout[keycode], true); SDL_SendKeyboardKey(timestamp, keyboardID, keycode, videodata->key_layout[keycode], true);
} }
if (*text) { if (*text) {
text[text_length] = '\0'; text[text_length] = '\0';
@ -885,7 +897,7 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_
// We're about to get a repeated key down, ignore the key up // We're about to get a repeated key down, ignore the key up
return; return;
} }
SDL_SendKeyboardKey(0, keyboardID, keycode, videodata->key_layout[keycode], false); SDL_SendKeyboardKey(timestamp, keyboardID, keycode, videodata->key_layout[keycode], false);
} }
} }
@ -894,12 +906,14 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_
} }
} }
void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, const float x, const float y, const unsigned long time) void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time)
{ {
SDL_Window *window = windowdata->window; SDL_Window *window = windowdata->window;
const SDL_VideoData *videodata = (SDL_VideoData *)_this->internal; const SDL_VideoData *videodata = (SDL_VideoData *)_this->internal;
Display *display = videodata->display; Display *display = videodata->display;
int xticks = 0, yticks = 0; int xticks = 0, yticks = 0;
Uint64 timestamp = X11_GetEventTimestamp(time);
#ifdef DEBUG_XEVENTS #ifdef DEBUG_XEVENTS
SDL_Log("window 0x%lx: ButtonPress (X11 button = %d)\n", windowdata->xwindow, button); SDL_Log("window 0x%lx: ButtonPress (X11 button = %d)\n", windowdata->xwindow, button);
#endif #endif
@ -907,22 +921,30 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
SDL_Mouse *mouse = SDL_GetMouse(); SDL_Mouse *mouse = SDL_GetMouse();
if (!mouse->relative_mode && (x != mouse->x || y != mouse->y)) { if (!mouse->relative_mode && (x != mouse->x || y != mouse->y)) {
X11_ProcessHitTest(_this, windowdata, x, y, false); X11_ProcessHitTest(_this, windowdata, x, y, false);
SDL_SendMouseMotion(0, window, mouseID, false, x, y); SDL_SendMouseMotion(timestamp, window, mouseID, false, x, y);
} }
if (X11_IsWheelEvent(display, button, &xticks, &yticks)) { if (X11_IsWheelEvent(display, button, &xticks, &yticks)) {
SDL_SendMouseWheel(0, window, mouseID, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL); if (mouseID != SDL_GLOBAL_MOUSE_ID) {
const float scale = 1.0f;
SDL_SendRawMouseWheel(timestamp, mouseID, -xticks, yticks, scale, scale);
}
SDL_SendMouseWheel(timestamp, window, mouseID, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL);
} else { } else {
bool ignore_click = false; bool ignore_click = false;
if (button > 7) {
/* X button values 4-7 are used for scrolling, so X1 is 8, X2 is 9, ...
=> subtract (8-SDL_BUTTON_X1) to get value SDL expects */
button -= (8 - SDL_BUTTON_X1);
}
if (mouseID != SDL_GLOBAL_MOUSE_ID) {
SDL_SendRawMouseButton(timestamp, mouseID, button, true);
}
if (button == Button1) { if (button == Button1) {
if (X11_TriggerHitTestAction(_this, windowdata, x, y)) { if (X11_TriggerHitTestAction(_this, windowdata, x, y)) {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_HIT_TEST, 0, 0); SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_HIT_TEST, 0, 0);
return; // don't pass this event on to app. return; // don't pass this event on to app.
} }
} else if (button > 7) {
/* X button values 4-7 are used for scrolling, so X1 is 8, X2 is 9, ...
=> subtract (8-SDL_BUTTON_X1) to get value SDL expects */
button -= (8 - SDL_BUTTON_X1);
} }
if (windowdata->last_focus_event_time) { if (windowdata->last_focus_event_time) {
const int X11_FOCUS_CLICK_TIMEOUT = 10; const int X11_FOCUS_CLICK_TIMEOUT = 10;
@ -932,19 +954,21 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
windowdata->last_focus_event_time = 0; windowdata->last_focus_event_time = 0;
} }
if (!ignore_click) { if (!ignore_click) {
SDL_SendMouseButton(0, window, mouseID, button, true); SDL_SendMouseButton(timestamp, window, mouseID, button, true);
} }
} }
X11_UpdateUserTime(windowdata, time); X11_UpdateUserTime(windowdata, time);
} }
void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button) void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, unsigned long time)
{ {
SDL_Window *window = windowdata->window; SDL_Window *window = windowdata->window;
const SDL_VideoData *videodata = (SDL_VideoData *)_this->internal; const SDL_VideoData *videodata = (SDL_VideoData *)_this->internal;
Display *display = videodata->display; Display *display = videodata->display;
// The X server sends a Release event for each Press for wheels. Ignore them. // The X server sends a Release event for each Press for wheels. Ignore them.
int xticks = 0, yticks = 0; int xticks = 0, yticks = 0;
Uint64 timestamp = X11_GetEventTimestamp(time);
#ifdef DEBUG_XEVENTS #ifdef DEBUG_XEVENTS
SDL_Log("window 0x%lx: ButtonRelease (X11 button = %d)\n", windowdata->xwindow, button); SDL_Log("window 0x%lx: ButtonRelease (X11 button = %d)\n", windowdata->xwindow, button);
#endif #endif
@ -953,7 +977,10 @@ void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata,
// see explanation at case ButtonPress // see explanation at case ButtonPress
button -= (8 - SDL_BUTTON_X1); button -= (8 - SDL_BUTTON_X1);
} }
SDL_SendMouseButton(0, window, mouseID, button, false); if (mouseID != SDL_GLOBAL_MOUSE_ID) {
SDL_SendRawMouseButton(timestamp, mouseID, button, false);
}
SDL_SendMouseButton(timestamp, window, mouseID, button, false);
} }
} }
@ -1584,7 +1611,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
break; break;
} }
X11_HandleButtonRelease(_this, data, SDL_GLOBAL_MOUSE_ID, xevent->xbutton.button); X11_HandleButtonRelease(_this, data, SDL_GLOBAL_MOUSE_ID, xevent->xbutton.button, xevent->xbutton.time);
} break; } break;
case PropertyNotify: case PropertyNotify:

View file

@ -29,9 +29,10 @@ extern void X11_SendWakeupEvent(SDL_VideoDevice *_this, SDL_Window *window);
extern bool X11_SuspendScreenSaver(SDL_VideoDevice *_this); extern bool X11_SuspendScreenSaver(SDL_VideoDevice *_this);
extern void X11_ReconcileKeyboardState(SDL_VideoDevice *_this); extern void X11_ReconcileKeyboardState(SDL_VideoDevice *_this);
extern void X11_GetBorderValues(SDL_WindowData *data); extern void X11_GetBorderValues(SDL_WindowData *data);
extern Uint64 X11_GetEventTimestamp(unsigned long time);
extern void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_KeyboardID keyboardID, XEvent *xevent); extern void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_KeyboardID keyboardID, XEvent *xevent);
extern void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, const float x, const float y, const unsigned long time); extern void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time);
extern void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button); extern void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, unsigned long time);
extern SDL_WindowData *X11_FindWindow(SDL_VideoDevice *_this, Window window); extern SDL_WindowData *X11_FindWindow(SDL_VideoDevice *_this, Window window);
extern bool X11_ProcessHitTest(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y, bool force_new_result); extern bool X11_ProcessHitTest(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y, bool force_new_result);
extern bool X11_TriggerHitTestAction(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y); extern bool X11_TriggerHitTestAction(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y);

View file

@ -319,21 +319,13 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
double coords[2]; double coords[2];
double processed_coords[2]; double processed_coords[2];
int i; int i;
Uint64 timestamp = X11_GetEventTimestamp(rawev->time);
videodata->global_mouse_changed = true; videodata->global_mouse_changed = true;
if (is_pen) { if (is_pen) {
break; // Pens check for XI_Motion instead break; // Pens check for XI_Motion instead
} }
if (!mouse->relative_mode) {
break;
}
// Relative mouse motion is delivered to the window with keyboard focus
if (!SDL_GetKeyboardFocus()) {
break;
}
devinfo = xinput2_get_device_info(videodata, rawev->deviceid); devinfo = xinput2_get_device_info(videodata, rawev->deviceid);
if (!devinfo) { if (!devinfo) {
break; // oh well. break; // oh well.
@ -350,7 +342,16 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
} }
} }
SDL_SendMouseMotion(0, mouse->focus, (SDL_MouseID)rawev->sourceid, true, (float)processed_coords[0], (float)processed_coords[1]); // FIXME: Are the processed_coords always integral values?
// FIXME: Apply desktop mouse scale?
const float scale = 1.0f;
SDL_SendRawMouseMotion(timestamp, (SDL_MouseID)rawev->sourceid, (int)processed_coords[0], (int)processed_coords[1], scale, scale);
// Relative mouse motion is delivered to the window with keyboard focus
if (mouse->relative_mode && SDL_GetKeyboardFocus()) {
SDL_SendMouseMotion(timestamp, mouse->focus, (SDL_MouseID)rawev->sourceid, true, (float)processed_coords[0], (float)processed_coords[1]);
}
devinfo->prev_coords[0] = coords[0]; devinfo->prev_coords[0] = coords[0];
devinfo->prev_coords[1] = coords[1]; devinfo->prev_coords[1] = coords[1];
} break; } break;
@ -430,7 +431,7 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
X11_HandleButtonPress(_this, windowdata, (SDL_MouseID)xev->sourceid, button, X11_HandleButtonPress(_this, windowdata, (SDL_MouseID)xev->sourceid, button,
(float)xev->event_x, (float)xev->event_y, xev->time); (float)xev->event_x, (float)xev->event_y, xev->time);
} else { } else {
X11_HandleButtonRelease(_this, windowdata, (SDL_MouseID)xev->sourceid, button); X11_HandleButtonRelease(_this, windowdata, (SDL_MouseID)xev->sourceid, button, xev->time);
} }
} }
} break; } break;

View file

@ -103,10 +103,10 @@ static void loop(void)
} }
} }
} break; } break;
case SDL_EVENT_MOUSE_RAW_MOTION: case SDL_EVENT_RAW_MOUSE_MOTION:
{ {
rect.x += event.maxis.dx / event.maxis.ux; rect.x += event.raw_motion.dx * event.raw_motion.scale_x;
rect.y += event.maxis.dy / event.maxis.uy; rect.y += event.raw_motion.dy * event.raw_motion.scale_y;
} break; } break;
default: default:
break; break;
@ -212,9 +212,7 @@ int main(int argc, char *argv[])
} }
} }
if (raw) { SDL_SetEventEnabled(SDL_EVENT_RAW_MOUSE_MOTION, raw);
SDL_SetEventEnabled(SDL_EVENT_MOUSE_RAW_MOTION, true);
}
rect.x = DEFAULT_WINDOW_WIDTH / 2; rect.x = DEFAULT_WINDOW_WIDTH / 2;
rect.y = DEFAULT_WINDOW_HEIGHT / 2; rect.y = DEFAULT_WINDOW_HEIGHT / 2;