mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-13 23:34:16 +02:00
wayland: Add high-resolution event timestamp support
Add the protocol for high-resolution timestamp events and subscribe to them if available. Event timestamps are now handled natively in nanoseconds as much as possible to avoid error-prone conversions. Variables have been appended with _ms or _ns where appropriate, to avoid ambiguity.
This commit is contained in:
committed by
Sam Lantinga
parent
4a22ee7277
commit
8cafde5ecc
@@ -39,6 +39,7 @@
|
||||
#include "text-input-unstable-v3-client-protocol.h"
|
||||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
#include "primary-selection-unstable-v1-client-protocol.h"
|
||||
#include "input-timestamps-unstable-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
@@ -173,11 +174,10 @@ static struct wl_surface *touch_surface(SDL_TouchID id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Uint64 Wayland_GetEventTimestamp(Uint32 wayland_timestamp)
|
||||
Uint64 Wayland_GetEventTimestamp(Uint64 nsTimestamp)
|
||||
{
|
||||
static Uint32 last;
|
||||
static Uint64 last;
|
||||
static Uint64 timestamp_offset;
|
||||
Uint64 nsTimestamp = SDL_MS_TO_NS(wayland_timestamp);
|
||||
const Uint64 now = SDL_GetTicksNS();
|
||||
|
||||
if (!nsTimestamp) {
|
||||
@@ -203,19 +203,71 @@ Uint64 Wayland_GetEventTimestamp(Uint32 wayland_timestamp)
|
||||
return nsTimestamp;
|
||||
}
|
||||
|
||||
static void Wayland_input_timestamp_listener(void *data, struct zwp_input_timestamps_v1 *zwp_input_timestamps_v1,
|
||||
uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec)
|
||||
{
|
||||
*((Uint64 *)data) = ((((Uint64)tv_sec_hi << 32) | (Uint64)tv_sec_lo) * SDL_NS_PER_SECOND) + tv_nsec;
|
||||
}
|
||||
|
||||
static const struct zwp_input_timestamps_v1_listener timestamp_listener = {
|
||||
Wayland_input_timestamp_listener
|
||||
};
|
||||
|
||||
static Uint64 Wayland_GetKeyboardTimestamp(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms)
|
||||
{
|
||||
return Wayland_GetEventTimestamp(input->keyboard_timestamp_ns ? input->keyboard_timestamp_ns : SDL_MS_TO_NS(wl_timestamp_ms));
|
||||
}
|
||||
|
||||
static Uint64 Wayland_GetKeyboardTimestampRaw(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms)
|
||||
{
|
||||
return input->keyboard_timestamp_ns ? input->keyboard_timestamp_ns : SDL_MS_TO_NS(wl_timestamp_ms);
|
||||
}
|
||||
|
||||
static Uint64 Wayland_GetPointerTimestamp(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms)
|
||||
{
|
||||
return Wayland_GetEventTimestamp(input->pointer_timestamp_ns ? input->pointer_timestamp_ns : SDL_MS_TO_NS(wl_timestamp_ms));
|
||||
}
|
||||
|
||||
Uint64 Wayland_GetTouchTimestamp(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms)
|
||||
{
|
||||
return Wayland_GetEventTimestamp(input->touch_timestamp_ns ? input->touch_timestamp_ns : SDL_MS_TO_NS(wl_timestamp_ms));
|
||||
}
|
||||
|
||||
void Wayland_RegisterTimestampListeners(struct SDL_WaylandInput *input)
|
||||
{
|
||||
SDL_VideoData *viddata = input->display;
|
||||
|
||||
if (viddata->input_timestamps_manager) {
|
||||
if (input->keyboard && !input->keyboard_timestamps) {
|
||||
input->keyboard_timestamps = zwp_input_timestamps_manager_v1_get_keyboard_timestamps(viddata->input_timestamps_manager, input->keyboard);
|
||||
zwp_input_timestamps_v1_add_listener(input->keyboard_timestamps, ×tamp_listener, &input->keyboard_timestamp_ns);
|
||||
}
|
||||
|
||||
if (input->pointer && !input->pointer_timestamps) {
|
||||
input->pointer_timestamps = zwp_input_timestamps_manager_v1_get_pointer_timestamps(viddata->input_timestamps_manager, input->pointer);
|
||||
zwp_input_timestamps_v1_add_listener(input->pointer_timestamps, ×tamp_listener, &input->pointer_timestamp_ns);
|
||||
}
|
||||
|
||||
if (input->touch && !input->touch_timestamps) {
|
||||
input->touch_timestamps = zwp_input_timestamps_manager_v1_get_touch_timestamps(viddata->input_timestamps_manager, input->touch);
|
||||
zwp_input_timestamps_v1_add_listener(input->touch_timestamps, ×tamp_listener, &input->touch_timestamp_ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns SDL_TRUE if a key repeat event was due */
|
||||
static SDL_bool keyboard_repeat_handle(SDL_WaylandKeyboardRepeat *repeat_info, uint32_t elapsed)
|
||||
static SDL_bool keyboard_repeat_handle(SDL_WaylandKeyboardRepeat *repeat_info, Uint64 elapsed)
|
||||
{
|
||||
SDL_bool ret = SDL_FALSE;
|
||||
while ((elapsed - repeat_info->next_repeat_ms) < 0x80000000U) {
|
||||
while (elapsed >= repeat_info->next_repeat_ns) {
|
||||
if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) {
|
||||
const Uint32 timestamp = repeat_info->wl_press_time + repeat_info->next_repeat_ms;
|
||||
const Uint64 timestamp = repeat_info->wl_press_time_ns + repeat_info->next_repeat_ns;
|
||||
SDL_SendKeyboardKey(Wayland_GetEventTimestamp(timestamp), SDL_PRESSED, repeat_info->scancode);
|
||||
}
|
||||
if (repeat_info->text[0]) {
|
||||
SDL_SendKeyboardText(repeat_info->text);
|
||||
}
|
||||
repeat_info->next_repeat_ms += 1000 / repeat_info->repeat_rate;
|
||||
repeat_info->next_repeat_ns += SDL_NS_PER_SECOND / (Uint64)repeat_info->repeat_rate;
|
||||
ret = SDL_TRUE;
|
||||
}
|
||||
return ret;
|
||||
@@ -229,7 +281,7 @@ static void keyboard_repeat_clear(SDL_WaylandKeyboardRepeat *repeat_info)
|
||||
repeat_info->is_key_down = SDL_FALSE;
|
||||
}
|
||||
|
||||
static void keyboard_repeat_set(SDL_WaylandKeyboardRepeat *repeat_info, uint32_t key, uint32_t wl_press_time,
|
||||
static void keyboard_repeat_set(SDL_WaylandKeyboardRepeat *repeat_info, uint32_t key, Uint64 wl_press_time_ns,
|
||||
uint32_t scancode, SDL_bool has_text, char text[8])
|
||||
{
|
||||
if (!repeat_info->is_initialized || !repeat_info->repeat_rate) {
|
||||
@@ -237,9 +289,9 @@ static void keyboard_repeat_set(SDL_WaylandKeyboardRepeat *repeat_info, uint32_t
|
||||
}
|
||||
repeat_info->is_key_down = SDL_TRUE;
|
||||
repeat_info->key = key;
|
||||
repeat_info->wl_press_time = wl_press_time;
|
||||
repeat_info->sdl_press_time = SDL_GetTicks();
|
||||
repeat_info->next_repeat_ms = repeat_info->repeat_delay;
|
||||
repeat_info->wl_press_time_ns = wl_press_time_ns;
|
||||
repeat_info->sdl_press_time_ns = SDL_GetTicksNS();
|
||||
repeat_info->next_repeat_ns = SDL_MS_TO_NS(repeat_info->repeat_delay_ms);
|
||||
repeat_info->scancode = scancode;
|
||||
if (has_text) {
|
||||
SDL_memcpy(repeat_info->text, text, 8);
|
||||
@@ -317,16 +369,16 @@ int Wayland_WaitEventTimeout(_THIS, Sint64 timeoutNS)
|
||||
|
||||
/* If key repeat is active, we'll need to cap our maximum wait time to handle repeats */
|
||||
if (input && keyboard_repeat_is_set(&input->keyboard_repeat)) {
|
||||
uint32_t elapsed = (uint32_t)(SDL_GetTicks() - input->keyboard_repeat.sdl_press_time);
|
||||
const Uint64 elapsed = SDL_GetTicksNS() - input->keyboard_repeat.sdl_press_time_ns;
|
||||
if (keyboard_repeat_handle(&input->keyboard_repeat, elapsed)) {
|
||||
/* A repeat key event was already due */
|
||||
return 1;
|
||||
} else {
|
||||
uint32_t next_repeat_wait_time = (input->keyboard_repeat.next_repeat_ms - elapsed) + 1;
|
||||
const Uint64 next_repeat_wait_time = (input->keyboard_repeat.next_repeat_ns - elapsed) + 1;
|
||||
if (timeoutNS >= 0) {
|
||||
timeoutNS = SDL_min(timeoutNS, SDL_MS_TO_NS(next_repeat_wait_time));
|
||||
timeoutNS = SDL_min(timeoutNS, next_repeat_wait_time);
|
||||
} else {
|
||||
timeoutNS = SDL_MS_TO_NS(next_repeat_wait_time);
|
||||
timeoutNS = next_repeat_wait_time;
|
||||
}
|
||||
key_repeat_active = SDL_TRUE;
|
||||
}
|
||||
@@ -347,7 +399,7 @@ int Wayland_WaitEventTimeout(_THIS, Sint64 timeoutNS)
|
||||
|
||||
/* If key repeat is active, we might have woken up to generate a key event */
|
||||
if (key_repeat_active) {
|
||||
uint32_t elapsed = (uint32_t)(SDL_GetTicks() - input->keyboard_repeat.sdl_press_time);
|
||||
const Uint64 elapsed = SDL_GetTicksNS() - input->keyboard_repeat.sdl_press_time_ns;
|
||||
if (keyboard_repeat_handle(&input->keyboard_repeat, elapsed)) {
|
||||
return 1;
|
||||
}
|
||||
@@ -406,7 +458,7 @@ void Wayland_PumpEvents(_THIS)
|
||||
err = WAYLAND_wl_display_dispatch_pending(d->display);
|
||||
|
||||
if (input && keyboard_repeat_is_set(&input->keyboard_repeat)) {
|
||||
uint32_t elapsed = (uint32_t)(SDL_GetTicks() - input->keyboard_repeat.sdl_press_time);
|
||||
const Uint64 elapsed = SDL_GetTicksNS() - input->keyboard_repeat.sdl_press_time_ns;
|
||||
keyboard_repeat_handle(&input->keyboard_repeat, elapsed);
|
||||
}
|
||||
|
||||
@@ -440,7 +492,7 @@ static void pointer_handle_motion(void *data, struct wl_pointer *pointer,
|
||||
const float sy_f = (float)wl_fixed_to_double(sy_w);
|
||||
const int sx = (int)SDL_floorf(sx_f * window->pointer_scale_x);
|
||||
const int sy = (int)SDL_floorf(sy_f * window->pointer_scale_y);
|
||||
SDL_SendMouseMotion(Wayland_GetEventTimestamp(time), window->sdlwindow, 0, 0, sx, sy);
|
||||
SDL_SendMouseMotion(Wayland_GetPointerTimestamp(input, time), window->sdlwindow, 0, 0, sx, sy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,7 +686,7 @@ static void pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_
|
||||
Wayland_data_device_set_serial(input->data_device, serial);
|
||||
Wayland_primary_selection_device_set_serial(input->primary_selection_device, serial);
|
||||
|
||||
SDL_SendMouseButton(Wayland_GetEventTimestamp(time), window->sdlwindow, 0,
|
||||
SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, time), window->sdlwindow, 0,
|
||||
state ? SDL_PRESSED : SDL_RELEASED, sdl_button);
|
||||
}
|
||||
}
|
||||
@@ -671,7 +723,7 @@ static void pointer_handle_axis_common_v1(struct SDL_WaylandInput *input,
|
||||
x /= WAYLAND_WHEEL_AXIS_UNIT;
|
||||
y /= WAYLAND_WHEEL_AXIS_UNIT;
|
||||
|
||||
SDL_SendMouseWheel(Wayland_GetEventTimestamp(time), window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
|
||||
SDL_SendMouseWheel(Wayland_GetPointerTimestamp(input, time), window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,7 +806,7 @@ static void pointer_handle_axis(void *data, struct wl_pointer *pointer,
|
||||
struct SDL_WaylandInput *input = data;
|
||||
|
||||
if (wl_seat_get_version(input->seat) >= 5) {
|
||||
input->pointer_curr_axis_info.timestamp = time;
|
||||
input->pointer_curr_axis_info.timestamp_ns = Wayland_GetPointerTimestamp(input, time);
|
||||
pointer_handle_axis_common(input, AXIS_EVENT_CONTINUOUS, axis, value);
|
||||
} else {
|
||||
pointer_handle_axis_common_v1(input, time, axis, value);
|
||||
@@ -801,7 +853,7 @@ static void pointer_handle_frame(void *data, struct wl_pointer *pointer)
|
||||
SDL_memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info);
|
||||
|
||||
if (x != 0.0f || y != 0.0f) {
|
||||
SDL_SendMouseWheel(Wayland_GetEventTimestamp(input->pointer_curr_axis_info.timestamp),
|
||||
SDL_SendMouseWheel(input->pointer_curr_axis_info.timestamp_ns,
|
||||
window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
|
||||
}
|
||||
}
|
||||
@@ -851,6 +903,7 @@ static void touch_handler_down(void *data, struct wl_touch *touch, uint32_t seri
|
||||
uint32_t timestamp, struct wl_surface *surface,
|
||||
int id, wl_fixed_t fx, wl_fixed_t fy)
|
||||
{
|
||||
struct SDL_WaylandInput *input = (struct SDL_WaylandInput *)data;
|
||||
SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(surface);
|
||||
const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x;
|
||||
const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y;
|
||||
@@ -859,13 +912,14 @@ static void touch_handler_down(void *data, struct wl_touch *touch, uint32_t seri
|
||||
|
||||
touch_add(id, x, y, surface);
|
||||
|
||||
SDL_SendTouch(Wayland_GetEventTimestamp(timestamp), (SDL_TouchID)(intptr_t)touch,
|
||||
SDL_SendTouch(Wayland_GetTouchTimestamp(input, timestamp), (SDL_TouchID)(intptr_t)touch,
|
||||
(SDL_FingerID)id, window_data->sdlwindow, SDL_TRUE, x, y, 1.0f);
|
||||
}
|
||||
|
||||
static void touch_handler_up(void *data, struct wl_touch *touch, uint32_t serial,
|
||||
uint32_t timestamp, int id)
|
||||
{
|
||||
struct SDL_WaylandInput *input = (struct SDL_WaylandInput *)data;
|
||||
float x = 0, y = 0;
|
||||
struct wl_surface *surface = NULL;
|
||||
SDL_Window *window = NULL;
|
||||
@@ -877,13 +931,14 @@ static void touch_handler_up(void *data, struct wl_touch *touch, uint32_t serial
|
||||
window = window_data->sdlwindow;
|
||||
}
|
||||
|
||||
SDL_SendTouch(Wayland_GetEventTimestamp(timestamp), (SDL_TouchID)(intptr_t)touch,
|
||||
SDL_SendTouch(Wayland_GetTouchTimestamp(input, timestamp), (SDL_TouchID)(intptr_t)touch,
|
||||
(SDL_FingerID)id, window, SDL_FALSE, x, y, 0.0f);
|
||||
}
|
||||
|
||||
static void touch_handler_motion(void *data, struct wl_touch *touch, uint32_t timestamp,
|
||||
int id, wl_fixed_t fx, wl_fixed_t fy)
|
||||
{
|
||||
struct SDL_WaylandInput *input = (struct SDL_WaylandInput *)data;
|
||||
SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(touch_surface(id));
|
||||
const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x;
|
||||
const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y;
|
||||
@@ -891,7 +946,7 @@ static void touch_handler_motion(void *data, struct wl_touch *touch, uint32_t ti
|
||||
const float y = dbly / window_data->sdlwindow->h;
|
||||
|
||||
touch_update(id, x, y);
|
||||
SDL_SendTouchMotion(Wayland_GetEventTimestamp(timestamp), (SDL_TouchID)(intptr_t)touch,
|
||||
SDL_SendTouchMotion(Wayland_GetPointerTimestamp(input, timestamp), (SDL_TouchID)(intptr_t)touch,
|
||||
(SDL_FingerID)id, window_data->sdlwindow, x, y, 1.0f);
|
||||
}
|
||||
|
||||
@@ -1237,6 +1292,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
||||
char text[8];
|
||||
SDL_bool has_text = SDL_FALSE;
|
||||
SDL_bool handled_by_ime = SDL_FALSE;
|
||||
const Uint64 timestamp_raw_ns = Wayland_GetKeyboardTimestampRaw(input, time);
|
||||
|
||||
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
has_text = keyboard_input_get_text(text, input, key, SDL_PRESSED, &handled_by_ime);
|
||||
@@ -1247,7 +1303,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
||||
* Using SDL_GetTicks would be wrong, as it would report when the release event is processed,
|
||||
* which may be off if the application hasn't pumped events for a while.
|
||||
*/
|
||||
keyboard_repeat_handle(&input->keyboard_repeat, time - input->keyboard_repeat.wl_press_time);
|
||||
keyboard_repeat_handle(&input->keyboard_repeat, timestamp_raw_ns - input->keyboard_repeat.wl_press_time_ns);
|
||||
keyboard_repeat_clear(&input->keyboard_repeat);
|
||||
}
|
||||
keyboard_input_get_text(text, input, key, SDL_RELEASED, &handled_by_ime);
|
||||
@@ -1255,7 +1311,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
||||
|
||||
if (!handled_by_ime) {
|
||||
scancode = Wayland_get_scancode_from_key(input, key + 8);
|
||||
SDL_SendKeyboardKey(Wayland_GetEventTimestamp(time), state == WL_KEYBOARD_KEY_STATE_PRESSED ? SDL_PRESSED : SDL_RELEASED, scancode);
|
||||
SDL_SendKeyboardKey(Wayland_GetKeyboardTimestamp(input, time), state == WL_KEYBOARD_KEY_STATE_PRESSED ? SDL_PRESSED : SDL_RELEASED, scancode);
|
||||
}
|
||||
|
||||
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
@@ -1267,7 +1323,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
||||
}
|
||||
}
|
||||
if (input->xkb.keymap && WAYLAND_xkb_keymap_key_repeats(input->xkb.keymap, key + 8)) {
|
||||
keyboard_repeat_set(&input->keyboard_repeat, key, time, scancode, has_text, text);
|
||||
keyboard_repeat_set(&input->keyboard_repeat, key, timestamp_raw_ns, scancode, has_text, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1325,7 +1381,7 @@ static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keybo
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
input->keyboard_repeat.repeat_rate = SDL_clamp(rate, 0, 1000);
|
||||
input->keyboard_repeat.repeat_delay = delay;
|
||||
input->keyboard_repeat.repeat_delay_ms = delay;
|
||||
input->keyboard_repeat.is_initialized = SDL_TRUE;
|
||||
}
|
||||
|
||||
@@ -1377,6 +1433,8 @@ static void seat_handle_capabilities(void *data, struct wl_seat *seat,
|
||||
wl_keyboard_destroy(input->keyboard);
|
||||
input->keyboard = NULL;
|
||||
}
|
||||
|
||||
Wayland_RegisterTimestampListeners(input);
|
||||
}
|
||||
|
||||
static void seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name)
|
||||
@@ -2396,6 +2454,16 @@ void Wayland_display_destroy_input(SDL_VideoData *d)
|
||||
return;
|
||||
}
|
||||
|
||||
if (input->keyboard_timestamps) {
|
||||
zwp_input_timestamps_v1_destroy(input->keyboard_timestamps);
|
||||
}
|
||||
if (input->pointer_timestamps) {
|
||||
zwp_input_timestamps_v1_destroy(input->pointer_timestamps);
|
||||
}
|
||||
if (input->touch_timestamps) {
|
||||
zwp_input_timestamps_v1_destroy(input->touch_timestamps);
|
||||
}
|
||||
|
||||
if (input->data_device != NULL) {
|
||||
Wayland_data_device_clear_selection(input->data_device);
|
||||
if (input->data_device->selection_offer != NULL) {
|
||||
|
||||
@@ -68,16 +68,15 @@ struct SDL_WaylandTabletInput
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// repeat_rate in range of [1, 1000]
|
||||
int32_t repeat_rate;
|
||||
int32_t repeat_delay;
|
||||
int32_t repeat_rate; /* Repeat rate in range of [1, 1000] character(s) per second */
|
||||
int32_t repeat_delay_ms; /* Time to first repeat event in milliseconds */
|
||||
SDL_bool is_initialized;
|
||||
|
||||
SDL_bool is_key_down;
|
||||
uint32_t key;
|
||||
uint32_t wl_press_time; // Key press time as reported by the Wayland API
|
||||
Uint64 sdl_press_time; // Key press time expressed in SDL ticks
|
||||
uint32_t next_repeat_ms;
|
||||
Uint64 wl_press_time_ns; /* Key press time as reported by the Wayland API */
|
||||
Uint64 sdl_press_time_ns; /* Key press time expressed in SDL ticks */
|
||||
Uint64 next_repeat_ns; /* Next repeat event in nanoseconds */
|
||||
uint32_t scancode;
|
||||
char text[8];
|
||||
} SDL_WaylandKeyboardRepeat;
|
||||
@@ -93,10 +92,18 @@ struct SDL_WaylandInput
|
||||
SDL_WaylandPrimarySelectionDevice *primary_selection_device;
|
||||
SDL_WaylandTextInput *text_input;
|
||||
struct zwp_relative_pointer_v1 *relative_pointer;
|
||||
struct zwp_input_timestamps_v1 *keyboard_timestamps;
|
||||
struct zwp_input_timestamps_v1 *pointer_timestamps;
|
||||
struct zwp_input_timestamps_v1 *touch_timestamps;
|
||||
SDL_WindowData *pointer_focus;
|
||||
SDL_WindowData *keyboard_focus;
|
||||
uint32_t pointer_enter_serial;
|
||||
|
||||
/* High-resolution event timestamps */
|
||||
Uint64 keyboard_timestamp_ns;
|
||||
Uint64 pointer_timestamp_ns;
|
||||
Uint64 touch_timestamp_ns;
|
||||
|
||||
/* Last motion location */
|
||||
wl_fixed_t sx_w;
|
||||
wl_fixed_t sy_w;
|
||||
@@ -134,8 +141,8 @@ struct SDL_WaylandInput
|
||||
enum SDL_WaylandAxisEvent y_axis_type;
|
||||
float y;
|
||||
|
||||
/* Event timestamp in milliseconds */
|
||||
Uint32 timestamp;
|
||||
/* Event timestamp in nanoseconds */
|
||||
Uint64 timestamp_ns;
|
||||
} pointer_curr_axis_info;
|
||||
|
||||
SDL_WaylandKeyboardRepeat keyboard_repeat;
|
||||
@@ -149,7 +156,7 @@ struct SDL_WaylandInput
|
||||
SDL_bool keyboard_is_virtual;
|
||||
};
|
||||
|
||||
extern Uint64 Wayland_GetEventTimestamp(Uint32 wayland_timestamp);
|
||||
extern Uint64 Wayland_GetTouchTimestamp(struct SDL_WaylandInput *input, Uint32 wl_timestamp_ms);
|
||||
|
||||
extern void Wayland_PumpEvents(_THIS);
|
||||
extern void Wayland_SendWakeupEvent(_THIS, SDL_Window *window);
|
||||
@@ -180,6 +187,8 @@ extern int Wayland_input_ungrab_keyboard(SDL_Window *window);
|
||||
extern void Wayland_input_add_tablet(struct SDL_WaylandInput *input, struct SDL_WaylandTabletManager *tablet_manager);
|
||||
extern void Wayland_input_destroy_tablet(struct SDL_WaylandInput *input);
|
||||
|
||||
extern void Wayland_RegisterTimestampListeners(struct SDL_WaylandInput *input);
|
||||
|
||||
#endif /* SDL_waylandevents_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -71,6 +71,8 @@ static void touch_handle_touch(void *data,
|
||||
* (src/compositor/wayland_wrapper/qwltouch.cpp)
|
||||
**/
|
||||
|
||||
SDL_VideoData *viddata = (SDL_VideoData *)data;
|
||||
|
||||
float FIXED_TO_FLOAT = 1. / 10000.;
|
||||
float xf = FIXED_TO_FLOAT * normalized_x;
|
||||
float yf = FIXED_TO_FLOAT * normalized_y;
|
||||
@@ -105,13 +107,12 @@ static void touch_handle_touch(void *data,
|
||||
switch (touchState) {
|
||||
case QtWaylandTouchPointPressed:
|
||||
case QtWaylandTouchPointReleased:
|
||||
SDL_SendTouch(Wayland_GetEventTimestamp(time), deviceId, (SDL_FingerID)id, window,
|
||||
(touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE,
|
||||
xf, yf, pressuref);
|
||||
SDL_SendTouch(Wayland_GetTouchTimestamp(viddata->input, time), deviceId, (SDL_FingerID)id,
|
||||
window, (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE, xf, yf, pressuref);
|
||||
break;
|
||||
case QtWaylandTouchPointMoved:
|
||||
SDL_SendTouchMotion(Wayland_GetEventTimestamp(time), deviceId, (SDL_FingerID)id, window,
|
||||
xf, yf, pressuref);
|
||||
SDL_SendTouchMotion(Wayland_GetTouchTimestamp(viddata->input, time), deviceId, (SDL_FingerID)id,
|
||||
window, xf, yf, pressuref);
|
||||
break;
|
||||
default:
|
||||
/* Should not happen */
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "viewporter-client-protocol.h"
|
||||
#include "primary-selection-unstable-v1-client-protocol.h"
|
||||
#include "fractional-scale-v1-client-protocol.h"
|
||||
#include "input-timestamps-unstable-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
@@ -849,6 +850,11 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
|
||||
d->viewporter = wl_registry_bind(d->registry, id, &wp_viewporter_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "wp_fractional_scale_manager_v1") == 0) {
|
||||
d->fractional_scale_manager = wl_registry_bind(d->registry, id, &wp_fractional_scale_manager_v1_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "zwp_input_timestamps_manager_v1") == 0) {
|
||||
d->input_timestamps_manager = wl_registry_bind(d->registry, id, &zwp_input_timestamps_manager_v1_interface, 1);
|
||||
if (d->input) {
|
||||
Wayland_RegisterTimestampListeners(d->input);
|
||||
}
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
} else if (SDL_strcmp(interface, "qt_touch_extension") == 0) {
|
||||
Wayland_touch_create(d, id);
|
||||
@@ -1099,6 +1105,11 @@ static void Wayland_VideoCleanup(_THIS)
|
||||
data->fractional_scale_manager = NULL;
|
||||
}
|
||||
|
||||
if (data->input_timestamps_manager) {
|
||||
zwp_input_timestamps_manager_v1_destroy(data->input_timestamps_manager);
|
||||
data->input_timestamps_manager = NULL;
|
||||
}
|
||||
|
||||
if (data->compositor) {
|
||||
wl_compositor_destroy(data->compositor);
|
||||
data->compositor = NULL;
|
||||
|
||||
@@ -79,6 +79,7 @@ typedef struct
|
||||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||
struct wp_viewporter *viewporter;
|
||||
struct wp_fractional_scale_manager_v1 *fractional_scale_manager;
|
||||
struct zwp_input_timestamps_manager_v1 *input_timestamps_manager;
|
||||
|
||||
EGLDisplay edpy;
|
||||
EGLContext context;
|
||||
|
||||
Reference in New Issue
Block a user