mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-02-09 10:06:44 -05:00
backend, virtual_keyboard: set the time_nsec field of relevant events
Backends modified: libinput (with microsecond precision), X11 (with millisecond precision), RDP (with millisecond precision), and Wayland (with nanosecond precision if the host server supports the input-timestamps protocol, otherwise millisecond precision); and virtual-keyboard protocol (with millisecond precision).
This commit is contained in:
parent
79ed410be4
commit
e617da0378
9 changed files with 172 additions and 38 deletions
|
|
@ -65,8 +65,9 @@ void handle_keyboard_key(struct libinput_event *event,
|
|||
struct libinput_event_keyboard *kbevent =
|
||||
libinput_event_get_keyboard_event(event);
|
||||
struct wlr_event_keyboard_key wlr_event = { 0 };
|
||||
wlr_event.time_msec =
|
||||
usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent));
|
||||
uint64_t event_time = libinput_event_keyboard_get_time_usec(kbevent);
|
||||
wlr_event.time_msec = usec_to_msec(event_time);
|
||||
wlr_event.time_nsec = event_time * 1000;
|
||||
wlr_event.keycode = libinput_event_keyboard_get_key(kbevent);
|
||||
enum libinput_key_state state =
|
||||
libinput_event_keyboard_get_key_state(kbevent);
|
||||
|
|
|
|||
|
|
@ -32,8 +32,9 @@ void handle_pointer_motion(struct libinput_event *event,
|
|||
libinput_event_get_pointer_event(event);
|
||||
struct wlr_event_pointer_motion wlr_event = { 0 };
|
||||
wlr_event.device = wlr_dev;
|
||||
wlr_event.time_msec =
|
||||
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
||||
uint64_t event_time = libinput_event_pointer_get_time_usec(pevent);
|
||||
wlr_event.time_msec = usec_to_msec(event_time);
|
||||
wlr_event.time_nsec = event_time * 1000;
|
||||
wlr_event.delta_x = libinput_event_pointer_get_dx(pevent);
|
||||
wlr_event.delta_y = libinput_event_pointer_get_dy(pevent);
|
||||
wlr_event.unaccel_dx = libinput_event_pointer_get_dx_unaccelerated(pevent);
|
||||
|
|
@ -54,8 +55,9 @@ void handle_pointer_motion_abs(struct libinput_event *event,
|
|||
libinput_event_get_pointer_event(event);
|
||||
struct wlr_event_pointer_motion_absolute wlr_event = { 0 };
|
||||
wlr_event.device = wlr_dev;
|
||||
wlr_event.time_msec =
|
||||
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
||||
uint64_t event_time = libinput_event_pointer_get_time_usec(pevent);
|
||||
wlr_event.time_msec = usec_to_msec(event_time);
|
||||
wlr_event.time_nsec = event_time * 1000;
|
||||
wlr_event.x = libinput_event_pointer_get_absolute_x_transformed(pevent, 1);
|
||||
wlr_event.y = libinput_event_pointer_get_absolute_y_transformed(pevent, 1);
|
||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.motion_absolute, &wlr_event);
|
||||
|
|
@ -74,8 +76,9 @@ void handle_pointer_button(struct libinput_event *event,
|
|||
libinput_event_get_pointer_event(event);
|
||||
struct wlr_event_pointer_button wlr_event = { 0 };
|
||||
wlr_event.device = wlr_dev;
|
||||
wlr_event.time_msec =
|
||||
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
||||
uint64_t event_time = libinput_event_pointer_get_time_usec(pevent);
|
||||
wlr_event.time_msec = usec_to_msec(event_time);
|
||||
wlr_event.time_nsec = event_time * 1000;
|
||||
wlr_event.button = libinput_event_pointer_get_button(pevent);
|
||||
switch (libinput_event_pointer_get_button_state(pevent)) {
|
||||
case LIBINPUT_BUTTON_STATE_PRESSED:
|
||||
|
|
@ -101,8 +104,9 @@ void handle_pointer_axis(struct libinput_event *event,
|
|||
libinput_event_get_pointer_event(event);
|
||||
struct wlr_event_pointer_axis wlr_event = { 0 };
|
||||
wlr_event.device = wlr_dev;
|
||||
wlr_event.time_msec =
|
||||
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
||||
uint64_t event_time = libinput_event_pointer_get_time_usec(pevent);
|
||||
wlr_event.time_msec = usec_to_msec(event_time);
|
||||
wlr_event.time_nsec = event_time * 1000;
|
||||
switch (libinput_event_pointer_get_axis_source(pevent)) {
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
|
||||
wlr_event.source = WLR_AXIS_SOURCE_WHEEL;
|
||||
|
|
|
|||
|
|
@ -32,8 +32,9 @@ void handle_touch_down(struct libinput_event *event,
|
|||
libinput_event_get_touch_event(event);
|
||||
struct wlr_event_touch_down wlr_event = { 0 };
|
||||
wlr_event.device = wlr_dev;
|
||||
wlr_event.time_msec =
|
||||
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
||||
uint64_t event_time = libinput_event_touch_get_time_usec(tevent);
|
||||
wlr_event.time_msec = usec_to_msec(event_time);
|
||||
wlr_event.time_nsec = event_time * 1000;
|
||||
wlr_event.touch_id = libinput_event_touch_get_slot(tevent);
|
||||
wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1);
|
||||
wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1);
|
||||
|
|
@ -52,8 +53,9 @@ void handle_touch_up(struct libinput_event *event,
|
|||
libinput_event_get_touch_event(event);
|
||||
struct wlr_event_touch_up wlr_event = { 0 };
|
||||
wlr_event.device = wlr_dev;
|
||||
wlr_event.time_msec =
|
||||
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
||||
uint64_t event_time = libinput_event_touch_get_time_usec(tevent);
|
||||
wlr_event.time_msec = usec_to_msec(event_time);
|
||||
wlr_event.time_nsec = event_time * 1000;
|
||||
wlr_event.touch_id = libinput_event_touch_get_slot(tevent);
|
||||
wlr_signal_emit_safe(&wlr_dev->touch->events.up, &wlr_event);
|
||||
}
|
||||
|
|
@ -70,8 +72,9 @@ void handle_touch_motion(struct libinput_event *event,
|
|||
libinput_event_get_touch_event(event);
|
||||
struct wlr_event_touch_motion wlr_event = { 0 };
|
||||
wlr_event.device = wlr_dev;
|
||||
wlr_event.time_msec =
|
||||
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
||||
uint64_t event_time = libinput_event_touch_get_time_usec(tevent);
|
||||
wlr_event.time_msec = usec_to_msec(event_time);
|
||||
wlr_event.time_nsec = event_time * 1000;
|
||||
wlr_event.touch_id = libinput_event_touch_get_slot(tevent);
|
||||
wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1);
|
||||
wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1);
|
||||
|
|
@ -90,8 +93,9 @@ void handle_touch_cancel(struct libinput_event *event,
|
|||
libinput_event_get_touch_event(event);
|
||||
struct wlr_event_touch_cancel wlr_event = { 0 };
|
||||
wlr_event.device = wlr_dev;
|
||||
wlr_event.time_msec =
|
||||
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
||||
uint64_t event_time = libinput_event_touch_get_time_usec(tevent);
|
||||
wlr_event.time_msec = usec_to_msec(event_time);
|
||||
wlr_event.time_nsec = event_time * 1000;
|
||||
wlr_event.touch_id = libinput_event_touch_get_slot(tevent);
|
||||
wlr_signal_emit_safe(&wlr_dev->touch->events.cancel, &wlr_event);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,8 +87,11 @@ static int xf_input_synchronize_event(rdpInput *input, UINT32 flags) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline int64_t timespec_to_msec(const struct timespec *a) {
|
||||
return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
|
||||
static inline uint32_t timespec_to_msec(const struct timespec *a) {
|
||||
return (uint32_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
|
||||
}
|
||||
static inline uint64_t timespec_to_nsec(const struct timespec *a) {
|
||||
return (uint64_t)a->tv_sec * 1000000000 + a->tv_nsec;
|
||||
}
|
||||
|
||||
static int xf_input_mouse_event(rdpInput *input,
|
||||
|
|
@ -105,6 +108,7 @@ static int xf_input_mouse_event(rdpInput *input,
|
|||
struct wlr_event_pointer_motion_absolute event = { 0 };
|
||||
event.device = wlr_device;
|
||||
event.time_msec = timespec_to_msec(&now);
|
||||
event.time_nsec = timespec_to_nsec(&now);
|
||||
event.x = x / (double)context->output->wlr_output.width;
|
||||
event.y = y / (double)context->output->wlr_output.height;
|
||||
wlr_signal_emit_safe(&pointer->events.motion_absolute, &event);
|
||||
|
|
@ -124,6 +128,7 @@ static int xf_input_mouse_event(rdpInput *input,
|
|||
struct wlr_event_pointer_button event = { 0 };
|
||||
event.device = wlr_device;
|
||||
event.time_msec = timespec_to_msec(&now);
|
||||
event.time_nsec = timespec_to_nsec(&now);
|
||||
event.button = button;
|
||||
event.state = (flags & PTR_FLAGS_DOWN) ?
|
||||
WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED;
|
||||
|
|
@ -139,6 +144,7 @@ static int xf_input_mouse_event(rdpInput *input,
|
|||
struct wlr_event_pointer_axis event = { 0 };
|
||||
event.device = &context->pointer->wlr_input_device;
|
||||
event.time_msec = timespec_to_msec(&now);
|
||||
event.time_nsec = timespec_to_nsec(&now);
|
||||
event.source = WLR_AXIS_SOURCE_WHEEL;
|
||||
event.orientation = WLR_AXIS_ORIENTATION_VERTICAL;
|
||||
event.delta = value;
|
||||
|
|
@ -165,6 +171,7 @@ static int xf_input_extended_mouse_event(
|
|||
struct wlr_event_pointer_motion_absolute event = { 0 };
|
||||
event.device = wlr_device;
|
||||
event.time_msec = timespec_to_msec(&now);
|
||||
event.time_nsec = timespec_to_nsec(&now);
|
||||
event.x = x / (double)context->output->wlr_output.width;
|
||||
event.y = y / (double)context->output->wlr_output.height;
|
||||
wlr_signal_emit_safe(&pointer->events.motion_absolute, &event);
|
||||
|
|
@ -207,6 +214,7 @@ static int xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code) {
|
|||
vk_code, KEYCODE_TYPE_EVDEV);
|
||||
struct wlr_event_keyboard_key event = { 0 };
|
||||
event.time_msec = timespec_to_msec(&now);
|
||||
event.time_nsec = timespec_to_nsec(&now);
|
||||
event.keycode = scan_code - 8;
|
||||
event.state = state;
|
||||
event.update_state = true;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "backend/wayland.h"
|
||||
#include "util/signal.h"
|
||||
#include "input-timestamps-unstable-v1-client-protocol.h"
|
||||
#include "xdg-decoration-unstable-v1-client-protocol.h"
|
||||
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
|
|
@ -81,6 +82,9 @@ static void registry_global(void *data, struct wl_registry *registry,
|
|||
} else if (strcmp(iface, zwp_pointer_gestures_v1_interface.name) == 0) {
|
||||
wl->zwp_pointer_gestures_v1 = wl_registry_bind(registry, name,
|
||||
&zwp_pointer_gestures_v1_interface, 1);
|
||||
} else if (strcmp(iface, zwp_input_timestamps_manager_v1_interface.name) == 0) {
|
||||
wl->input_timestamps.manager = wl_registry_bind(registry, name,
|
||||
&zwp_input_timestamps_manager_v1_interface, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -227,6 +231,11 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display,
|
|||
goto error_registry;
|
||||
}
|
||||
|
||||
if (!wl->input_timestamps.manager) {
|
||||
wlr_log(WLR_INFO,
|
||||
"Remote Wayland compositor does not support input-timestamps");
|
||||
}
|
||||
|
||||
struct wl_event_loop *loop = wl_display_get_event_loop(wl->local_display);
|
||||
int fd = wl_display_get_fd(wl->remote_display);
|
||||
int events = WL_EVENT_READABLE | WL_EVENT_ERROR | WL_EVENT_HANGUP;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
@ -18,6 +19,7 @@
|
|||
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||
#include "backend/wayland.h"
|
||||
#include "util/signal.h"
|
||||
#include "input-timestamps-unstable-v1-client-protocol.h"
|
||||
|
||||
static struct wlr_wl_pointer *output_get_pointer(struct wlr_wl_output *output) {
|
||||
struct wlr_input_device *wlr_dev;
|
||||
|
|
@ -34,6 +36,15 @@ static struct wlr_wl_pointer *output_get_pointer(struct wlr_wl_output *output) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline uint32_t timespec_to_msec(const struct timespec *a) {
|
||||
assert((unsigned long)a->tv_sec < UINT32_MAX / 1000 &&
|
||||
"struct timespec value too big");
|
||||
return (uint32_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
|
||||
}
|
||||
static inline uint64_t timespec_to_nsec(const struct timespec *a) {
|
||||
return (uint64_t)a->tv_sec * 1000000000 + a->tv_nsec;
|
||||
}
|
||||
|
||||
static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
|
||||
uint32_t serial, struct wl_surface *surface, wl_fixed_t sx,
|
||||
wl_fixed_t sy) {
|
||||
|
|
@ -78,10 +89,19 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
|
|||
return;
|
||||
}
|
||||
|
||||
uint64_t time_nsec;
|
||||
if (backend->input_timestamps.manager &&
|
||||
backend->input_timestamps.pointer.tv_sec == time / 1000) {
|
||||
time_nsec = timespec_to_nsec(&backend->input_timestamps.pointer);
|
||||
} else {
|
||||
time_nsec = (time % 1000) * 1000000;
|
||||
}
|
||||
|
||||
struct wlr_output *wlr_output = &pointer->output->wlr_output;
|
||||
struct wlr_event_pointer_motion_absolute event = {
|
||||
.device = &pointer->input_device->wlr_input_device,
|
||||
.time_msec = time,
|
||||
.time_nsec = time_nsec,
|
||||
.x = wl_fixed_to_double(sx) / wlr_output->width,
|
||||
.y = wl_fixed_to_double(sy) / wlr_output->height,
|
||||
};
|
||||
|
|
@ -96,11 +116,20 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
|
|||
return;
|
||||
}
|
||||
|
||||
uint64_t time_nsec;
|
||||
if (backend->input_timestamps.manager &&
|
||||
backend->input_timestamps.pointer.tv_sec == time / 1000) {
|
||||
time_nsec = timespec_to_nsec(&backend->input_timestamps.pointer);
|
||||
} else {
|
||||
time_nsec = (time % 1000) * 1000000;
|
||||
}
|
||||
|
||||
struct wlr_event_pointer_button event = {
|
||||
.device = &pointer->input_device->wlr_input_device,
|
||||
.button = button,
|
||||
.state = state,
|
||||
.time_msec = time,
|
||||
.time_nsec = time_nsec,
|
||||
};
|
||||
wlr_signal_emit_safe(&pointer->wlr_pointer.events.button, &event);
|
||||
}
|
||||
|
|
@ -113,12 +142,21 @@ static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
|
|||
return;
|
||||
}
|
||||
|
||||
uint64_t time_nsec;
|
||||
if (backend->input_timestamps.manager &&
|
||||
backend->input_timestamps.pointer.tv_sec == time / 1000) {
|
||||
time_nsec = timespec_to_nsec(&backend->input_timestamps.pointer);
|
||||
} else {
|
||||
time_nsec = (time % 1000) * 1000000;
|
||||
}
|
||||
|
||||
struct wlr_event_pointer_axis event = {
|
||||
.device = &pointer->input_device->wlr_input_device,
|
||||
.delta = wl_fixed_to_double(value),
|
||||
.delta_discrete = pointer->axis_discrete,
|
||||
.orientation = axis,
|
||||
.time_msec = time,
|
||||
.time_nsec = time_nsec,
|
||||
.source = pointer->axis_source,
|
||||
};
|
||||
wlr_signal_emit_safe(&pointer->wlr_pointer.events.axis, &event);
|
||||
|
|
@ -156,12 +194,21 @@ static void pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer,
|
|||
return;
|
||||
}
|
||||
|
||||
uint64_t time_nsec;
|
||||
if (backend->input_timestamps.manager &&
|
||||
backend->input_timestamps.pointer.tv_sec == time / 1000) {
|
||||
time_nsec = timespec_to_nsec(&backend->input_timestamps.pointer);
|
||||
} else {
|
||||
time_nsec = (time % 1000) * 1000000;
|
||||
}
|
||||
|
||||
struct wlr_event_pointer_axis event = {
|
||||
.device = &pointer->input_device->wlr_input_device,
|
||||
.delta = 0,
|
||||
.delta_discrete = 0,
|
||||
.orientation = axis,
|
||||
.time_msec = time,
|
||||
.time_nsec = time_nsec,
|
||||
.source = pointer->axis_source,
|
||||
};
|
||||
wlr_signal_emit_safe(&pointer->wlr_pointer.events.axis, &event);
|
||||
|
|
@ -195,24 +242,23 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
|||
// TODO: set keymap
|
||||
}
|
||||
|
||||
static uint32_t get_current_time_msec(void) {
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
return now.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t serial, struct wl_surface *surface, struct wl_array *keys) {
|
||||
struct wlr_input_device *dev = data;
|
||||
struct wlr_wl_input_device *wl_dev = data;
|
||||
struct wlr_input_device *dev = &wl_dev->wlr_input_device;
|
||||
|
||||
uint32_t time = get_current_time_msec();
|
||||
assert(dev && dev->keyboard);
|
||||
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
uint32_t *keycode_ptr;
|
||||
wl_array_for_each(keycode_ptr, keys) {
|
||||
struct wlr_event_keyboard_key event = {
|
||||
.keycode = *keycode_ptr,
|
||||
.state = WLR_KEY_PRESSED,
|
||||
.time_msec = time,
|
||||
.time_msec = timespec_to_msec(&now),
|
||||
.time_nsec = timespec_to_nsec(&now),
|
||||
.update_state = false,
|
||||
};
|
||||
wlr_keyboard_notify_key(dev->keyboard, &event);
|
||||
|
|
@ -221,9 +267,13 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard,
|
|||
|
||||
static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t serial, struct wl_surface *surface) {
|
||||
struct wlr_input_device *dev = data;
|
||||
struct wlr_wl_input_device *wl_dev = data;
|
||||
struct wlr_input_device *dev = &wl_dev->wlr_input_device;
|
||||
|
||||
uint32_t time = get_current_time_msec();
|
||||
assert(dev && dev->keyboard);
|
||||
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
uint32_t pressed[dev->keyboard->num_keycodes + 1];
|
||||
memcpy(pressed, dev->keyboard->keycodes,
|
||||
|
|
@ -235,7 +285,8 @@ static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
|
|||
struct wlr_event_keyboard_key event = {
|
||||
.keycode = keycode,
|
||||
.state = WLR_KEY_RELEASED,
|
||||
.time_msec = time,
|
||||
.time_msec = timespec_to_msec(&now),
|
||||
.time_nsec = timespec_to_nsec(&now),
|
||||
.update_state = false,
|
||||
};
|
||||
wlr_keyboard_notify_key(dev->keyboard, &event);
|
||||
|
|
@ -244,13 +295,25 @@ static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
|
|||
|
||||
static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
|
||||
struct wlr_input_device *dev = data;
|
||||
struct wlr_wl_input_device *wl_dev = data;
|
||||
struct wlr_input_device *dev = &wl_dev->wlr_input_device;
|
||||
|
||||
assert(dev && dev->keyboard);
|
||||
|
||||
uint64_t time_nsec;
|
||||
if (wl_dev->backend->input_timestamps.manager &&
|
||||
wl_dev->backend->input_timestamps.keyboard.tv_sec == time / 1000) {
|
||||
time_nsec =
|
||||
timespec_to_nsec(&wl_dev->backend->input_timestamps.keyboard);
|
||||
} else {
|
||||
time_nsec = (time % 1000) * 1000000;
|
||||
}
|
||||
|
||||
struct wlr_event_keyboard_key wlr_event = {
|
||||
.keycode = key,
|
||||
.state = state,
|
||||
.time_msec = time,
|
||||
.time_nsec = time_nsec,
|
||||
.update_state = false,
|
||||
};
|
||||
wlr_keyboard_notify_key(dev->keyboard, &wlr_event);
|
||||
|
|
@ -259,15 +322,18 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
|
|||
static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
|
||||
uint32_t mods_locked, uint32_t group) {
|
||||
struct wlr_input_device *dev = data;
|
||||
struct wlr_wl_input_device *wl_dev = data;
|
||||
struct wlr_input_device *dev = &wl_dev->wlr_input_device;
|
||||
|
||||
assert(dev && dev->keyboard);
|
||||
wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched,
|
||||
mods_locked, group);
|
||||
|
||||
wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed,
|
||||
mods_latched, mods_locked, group);
|
||||
}
|
||||
|
||||
static void keyboard_handle_repeat_info(void *data,
|
||||
struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay) {
|
||||
// This space is intentionally left blank
|
||||
/* This space is intentionally left blank */
|
||||
}
|
||||
|
||||
static struct wl_keyboard_listener keyboard_listener = {
|
||||
|
|
@ -521,11 +587,27 @@ void create_wl_keyboard(struct wl_keyboard *wl_keyboard, struct wlr_wl_backend *
|
|||
}
|
||||
wlr_keyboard_init(wlr_dev->keyboard, NULL);
|
||||
|
||||
wl_keyboard_add_listener(wl_keyboard, &keyboard_listener, wlr_dev);
|
||||
wl_keyboard_add_listener(wl_keyboard, &keyboard_listener, dev);
|
||||
dev->resource = wl_keyboard;
|
||||
wlr_signal_emit_safe(&wl->backend.events.new_input, wlr_dev);
|
||||
}
|
||||
|
||||
static void input_timestamps_handle_timestamp(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) {
|
||||
struct timespec *timestamp = data;
|
||||
|
||||
uint64_t tv_sec = ((uint64_t)tv_sec_hi << 32) + tv_sec_lo;
|
||||
assert(tv_sec < (uint64_t)LONG_MAX && "input-timestamps value is too big");
|
||||
|
||||
timestamp->tv_sec = tv_sec;
|
||||
timestamp->tv_nsec = tv_nsec;
|
||||
}
|
||||
|
||||
static const struct zwp_input_timestamps_v1_listener input_timestamps_listener = {
|
||||
.timestamp = input_timestamps_handle_timestamp,
|
||||
};
|
||||
|
||||
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
||||
enum wl_seat_capability caps) {
|
||||
struct wlr_wl_backend *backend = data;
|
||||
|
|
@ -543,6 +625,14 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
|||
}
|
||||
|
||||
wl_pointer_add_listener(wl_pointer, &pointer_listener, backend);
|
||||
|
||||
if (backend->input_timestamps.manager) {
|
||||
struct zwp_input_timestamps_v1 *pointer_input_timestamps =
|
||||
zwp_input_timestamps_manager_v1_get_pointer_timestamps(
|
||||
backend->input_timestamps.manager, wl_pointer);
|
||||
zwp_input_timestamps_v1_add_listener(pointer_input_timestamps,
|
||||
&input_timestamps_listener, &backend->input_timestamps.pointer);
|
||||
}
|
||||
}
|
||||
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
|
||||
wlr_log(WLR_DEBUG, "seat %p offered keyboard", (void*) wl_seat);
|
||||
|
|
@ -553,6 +643,14 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
|||
if (backend->started) {
|
||||
create_wl_keyboard(wl_keyboard, backend);
|
||||
}
|
||||
|
||||
if (backend->input_timestamps.manager) {
|
||||
struct zwp_input_timestamps_v1 *keyboard_input_timestamps =
|
||||
zwp_input_timestamps_manager_v1_get_keyboard_timestamps(
|
||||
backend->input_timestamps.manager, wl_keyboard);
|
||||
zwp_input_timestamps_v1_add_listener(keyboard_input_timestamps,
|
||||
&input_timestamps_listener, &backend->input_timestamps.keyboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ static void send_key_event(struct wlr_x11_backend *x11, uint32_t key,
|
|||
enum wlr_key_state st, xcb_timestamp_t time) {
|
||||
struct wlr_event_keyboard_key ev = {
|
||||
.time_msec = time,
|
||||
.time_nsec = time * 1000000,
|
||||
.keycode = key,
|
||||
.state = st,
|
||||
.update_state = true,
|
||||
|
|
@ -32,6 +33,7 @@ static void send_button_event(struct wlr_x11_output *output, uint32_t key,
|
|||
struct wlr_event_pointer_button ev = {
|
||||
.device = &output->pointer_dev,
|
||||
.time_msec = time,
|
||||
.time_nsec = time * 1000000,
|
||||
.button = key,
|
||||
.state = st,
|
||||
};
|
||||
|
|
@ -44,6 +46,7 @@ static void send_axis_event(struct wlr_x11_output *output, int32_t delta,
|
|||
struct wlr_event_pointer_axis ev = {
|
||||
.device = &output->pointer_dev,
|
||||
.time_msec = time,
|
||||
.time_nsec = time * 1000000,
|
||||
.source = WLR_AXIS_SOURCE_WHEEL,
|
||||
.orientation = WLR_AXIS_ORIENTATION_VERTICAL,
|
||||
// 15 is a typical value libinput sends for one scroll
|
||||
|
|
@ -59,6 +62,7 @@ static void send_pointer_position_event(struct wlr_x11_output *output,
|
|||
struct wlr_event_pointer_motion_absolute ev = {
|
||||
.device = &output->pointer_dev,
|
||||
.time_msec = time,
|
||||
.time_nsec = time * 1000000,
|
||||
.x = (double)x / output->wlr_output.width,
|
||||
.y = (double)y / output->wlr_output.height,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@ struct wlr_wl_backend {
|
|||
struct wl_keyboard *keyboard;
|
||||
struct wlr_wl_pointer *current_pointer;
|
||||
char *seat_name;
|
||||
struct {
|
||||
struct zwp_input_timestamps_manager_v1 *manager;
|
||||
struct timespec keyboard;
|
||||
struct timespec pointer;
|
||||
} input_timestamps;
|
||||
};
|
||||
|
||||
struct wlr_wl_output {
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ static void virtual_keyboard_key(struct wl_client *client,
|
|||
}
|
||||
struct wlr_event_keyboard_key event = {
|
||||
.time_msec = time,
|
||||
.time_nsec = time * 1000000,
|
||||
.keycode = key,
|
||||
.update_state = false,
|
||||
.state = state,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue