mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-02-05 04:06:11 -05:00
input_timestamps: add support for input-timestamps-unstable-v1 protocol
This protocol specifies a way for a client to request and receive high-resolution timestamps for input events. Touch input event are unsupported as of now.
This commit is contained in:
parent
e617da0378
commit
ab3a760874
5 changed files with 499 additions and 21 deletions
|
|
@ -10,26 +10,27 @@ install_headers(
|
|||
'wlr_fullscreen_shell_v1.h',
|
||||
'wlr_gamma_control_v1.h',
|
||||
'wlr_gtk_primary_selection.h',
|
||||
'wlr_idle_inhibit_v1.h',
|
||||
'wlr_idle.h',
|
||||
'wlr_idle_inhibit_v1.h',
|
||||
'wlr_input_device.h',
|
||||
'wlr_input_inhibitor.h',
|
||||
'wlr_input_method_v2.h',
|
||||
'wlr_input_timestamps_v1.h',
|
||||
'wlr_keyboard.h',
|
||||
'wlr_layer_shell_v1.h',
|
||||
'wlr_linux_dmabuf_v1.h',
|
||||
'wlr_list.h',
|
||||
'wlr_matrix.h',
|
||||
'wlr_output.h',
|
||||
'wlr_output_damage.h',
|
||||
'wlr_output_layout.h',
|
||||
'wlr_output_management_v1.h',
|
||||
'wlr_output.h',
|
||||
'wlr_pointer.h',
|
||||
'wlr_pointer_constraints_v1.h',
|
||||
'wlr_pointer_gestures_v1.h',
|
||||
'wlr_pointer.h',
|
||||
'wlr_presentation_time.h',
|
||||
'wlr_primary_selection_v1.h',
|
||||
'wlr_primary_selection.h',
|
||||
'wlr_primary_selection_v1.h',
|
||||
'wlr_region.h',
|
||||
'wlr_relative_pointer_v1.h',
|
||||
'wlr_screencopy_v1.h',
|
||||
|
|
@ -46,7 +47,7 @@ install_headers(
|
|||
'wlr_xcursor_manager.h',
|
||||
'wlr_xdg_decoration_v1.h',
|
||||
'wlr_xdg_output_v1.h',
|
||||
'wlr_xdg_shell_v6.h',
|
||||
'wlr_xdg_shell.h',
|
||||
'wlr_xdg_shell_v6.h',
|
||||
subdir: 'wlr/types',
|
||||
)
|
||||
|
|
|
|||
110
include/wlr/types/wlr_input_timestamps_v1.h
Normal file
110
include/wlr/types/wlr_input_timestamps_v1.h
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* This an unstable interface of wlroots. No guarantees are made regarding the
|
||||
* future consistency of this API.
|
||||
*/
|
||||
#ifndef WLR_USE_UNSTABLE
|
||||
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
|
||||
#endif
|
||||
|
||||
#ifndef WLR_TYPES_WLR_INPUT_TIMESTAMPS_V1_H
|
||||
#define WLR_TYPES_WLR_INPUT_TIMESTAMPS_V1_H
|
||||
|
||||
#include <wayland-server.h>
|
||||
|
||||
/**
|
||||
* This protocol specifies a way for a client to request and receive
|
||||
* high-resolution timestamps for input events.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A global interface used for requesting high-resolution timestamps for
|
||||
* input events.
|
||||
*/
|
||||
struct wlr_input_timestamps_manager_v1 {
|
||||
struct wl_global *global;
|
||||
struct wl_list resources; // wl_resource_get_link()
|
||||
struct wl_list input_timestamps; // wlr_input_timestamps_v1::link
|
||||
|
||||
struct {
|
||||
struct wl_signal destroy;
|
||||
} events;
|
||||
|
||||
struct wl_listener display_destroy_listener;
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum used to specify the type of input device to provide event timestamps
|
||||
* for.
|
||||
*/
|
||||
enum wlr_input_timestamps_type {
|
||||
WLR_INPUT_TIMESTAMPS_KEYBOARD,
|
||||
WLR_INPUT_TIMESTAMPS_POINTER,
|
||||
WLR_INPUT_TIMESTAMPS_TOUCH,
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides high-resolution timestamp events for a set of subscribed input
|
||||
* events. The set of subscribed input events is determined by the
|
||||
* zwp_input_timestamps_manager_v1 request used to create this object.
|
||||
*/
|
||||
struct wlr_input_timestamps_v1 {
|
||||
struct wl_resource *resource;
|
||||
struct wl_resource *input_resource;
|
||||
struct wlr_seat *seat;
|
||||
struct wl_list link; // wlr_input_timestamps_manager_v1::input_timestamps
|
||||
|
||||
enum wlr_input_timestamps_type input_timestamps_type;
|
||||
|
||||
struct {
|
||||
struct wl_signal destroy;
|
||||
} events;
|
||||
|
||||
struct wl_listener seat_destroy;
|
||||
struct wl_listener input_destroy;
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Public creator and destructor functions.
|
||||
*/
|
||||
struct wlr_input_timestamps_manager_v1 *wlr_input_timestamps_manager_v1_create(
|
||||
struct wl_display *display);
|
||||
|
||||
void wlr_input_timestamps_manager_v1_destroy(
|
||||
struct wlr_input_timestamps_manager_v1 *manager);
|
||||
|
||||
/**
|
||||
* Public functions to send timestamps for a particular set of subscribed
|
||||
* events, depending on the type of input device.
|
||||
*
|
||||
* The timestamp event is associated with the first subsequent input event
|
||||
* carrying a timestamp which belongs to the set of input events this object is
|
||||
* subscribed to.
|
||||
*
|
||||
* The timestamp provided by this event is a high-resolution version of the
|
||||
* timestamp argument of the associated input event. The provided timestamp is
|
||||
* in the same clock domain and is at least as accurate as the associated input
|
||||
* event timestamp.
|
||||
*
|
||||
* The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples, each
|
||||
* component being an unsigned 32-bit value. Whole seconds are in tv_sec which
|
||||
* is a 64-bit value combined from tv_sec_hi and tv_sec_lo, and the additional
|
||||
* fractional part in tv_nsec as nanoseconds. Hence, for valid timestamps
|
||||
* tv_nsec must be in [0, 999999999].
|
||||
*/
|
||||
void wlr_input_timestamps_manager_v1_send_keyboard_timestamp(
|
||||
struct wlr_input_timestamps_manager_v1 *manager, struct wlr_seat *seat,
|
||||
uint64_t tv_sec, uint32_t tv_nsec);
|
||||
|
||||
void wlr_input_timestamps_manager_v1_send_pointer_timestamp(
|
||||
struct wlr_input_timestamps_manager_v1 *manager, struct wlr_seat *seat,
|
||||
uint64_t tv_sec, uint32_t tv_nsec);
|
||||
|
||||
void wlr_input_timestamps_manager_v1_send_touch_timestamp(
|
||||
struct wlr_input_timestamps_manager_v1 *manager, struct wlr_seat *seat,
|
||||
uint64_t tv_sec, uint32_t tv_nsec);
|
||||
|
||||
#endif
|
||||
|
|
@ -15,6 +15,7 @@ protocols = [
|
|||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||
[wl_protocol_dir, 'unstable/fullscreen-shell/fullscreen-shell-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/input-timestamps/input-timestamps-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml'],
|
||||
|
|
@ -43,6 +44,7 @@ protocols = [
|
|||
client_protocols = [
|
||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||
[wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/input-timestamps/input-timestamps-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/pointer-constraints/pointer-constraints-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/pointer-gestures/pointer-gestures-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/relative-pointer/relative-pointer-unstable-v1.xml'],
|
||||
|
|
|
|||
|
|
@ -5,24 +5,14 @@ lib_wlr_types = static_library(
|
|||
'data_device/wlr_data_offer.c',
|
||||
'data_device/wlr_data_source.c',
|
||||
'data_device/wlr_drag.c',
|
||||
'seat/wlr_seat.c',
|
||||
'seat/wlr_seat_keyboard.c',
|
||||
'seat/wlr_seat_pointer.c',
|
||||
'seat/wlr_seat_touch.c',
|
||||
'seat/wlr_seat.c',
|
||||
'tablet_v2/wlr_tablet_v2.c',
|
||||
'tablet_v2/wlr_tablet_v2_pad.c',
|
||||
'tablet_v2/wlr_tablet_v2_tablet.c',
|
||||
'tablet_v2/wlr_tablet_v2_tool.c',
|
||||
'tablet_v2/wlr_tablet_v2.c',
|
||||
'xdg_shell_v6/wlr_xdg_popup_v6.c',
|
||||
'xdg_shell_v6/wlr_xdg_positioner_v6.c',
|
||||
'xdg_shell_v6/wlr_xdg_shell_v6.c',
|
||||
'xdg_shell_v6/wlr_xdg_surface_v6.c',
|
||||
'xdg_shell_v6/wlr_xdg_toplevel_v6.c',
|
||||
'xdg_shell/wlr_xdg_popup.c',
|
||||
'xdg_shell/wlr_xdg_positioner.c',
|
||||
'xdg_shell/wlr_xdg_shell.c',
|
||||
'xdg_shell/wlr_xdg_surface.c',
|
||||
'xdg_shell/wlr_xdg_toplevel.c',
|
||||
'wlr_box.c',
|
||||
'wlr_buffer.c',
|
||||
'wlr_compositor.c',
|
||||
|
|
@ -33,26 +23,27 @@ lib_wlr_types = static_library(
|
|||
'wlr_fullscreen_shell_v1.c',
|
||||
'wlr_gamma_control_v1.c',
|
||||
'wlr_gtk_primary_selection.c',
|
||||
'wlr_idle_inhibit_v1.c',
|
||||
'wlr_idle.c',
|
||||
'wlr_idle_inhibit_v1.c',
|
||||
'wlr_input_device.c',
|
||||
'wlr_input_inhibitor.c',
|
||||
'wlr_input_method_v2.c',
|
||||
'wlr_input_timestamps_v1.c',
|
||||
'wlr_keyboard.c',
|
||||
'wlr_layer_shell_v1.c',
|
||||
'wlr_linux_dmabuf_v1.c',
|
||||
'wlr_list.c',
|
||||
'wlr_matrix.c',
|
||||
'wlr_output.c',
|
||||
'wlr_output_damage.c',
|
||||
'wlr_output_layout.c',
|
||||
'wlr_output_management_v1.c',
|
||||
'wlr_output.c',
|
||||
'wlr_pointer.c',
|
||||
'wlr_pointer_constraints_v1.c',
|
||||
'wlr_pointer_gestures_v1.c',
|
||||
'wlr_pointer.c',
|
||||
'wlr_presentation_time.c',
|
||||
'wlr_primary_selection_v1.c',
|
||||
'wlr_primary_selection.c',
|
||||
'wlr_primary_selection_v1.c',
|
||||
'wlr_region.c',
|
||||
'wlr_relative_pointer_v1.c',
|
||||
'wlr_screencopy_v1.c',
|
||||
|
|
@ -67,6 +58,16 @@ lib_wlr_types = static_library(
|
|||
'wlr_xcursor_manager.c',
|
||||
'wlr_xdg_decoration_v1.c',
|
||||
'wlr_xdg_output_v1.c',
|
||||
'xdg_shell/wlr_xdg_popup.c',
|
||||
'xdg_shell/wlr_xdg_positioner.c',
|
||||
'xdg_shell/wlr_xdg_shell.c',
|
||||
'xdg_shell/wlr_xdg_surface.c',
|
||||
'xdg_shell/wlr_xdg_toplevel.c',
|
||||
'xdg_shell_v6/wlr_xdg_popup_v6.c',
|
||||
'xdg_shell_v6/wlr_xdg_positioner_v6.c',
|
||||
'xdg_shell_v6/wlr_xdg_shell_v6.c',
|
||||
'xdg_shell_v6/wlr_xdg_surface_v6.c',
|
||||
'xdg_shell_v6/wlr_xdg_toplevel_v6.c',
|
||||
),
|
||||
include_directories: wlr_inc,
|
||||
dependencies: [
|
||||
|
|
|
|||
364
types/wlr_input_timestamps_v1.c
Normal file
364
types/wlr_input_timestamps_v1.c
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <util/signal.h>
|
||||
#include <wayland-server.h>
|
||||
#include <wayland-util.h>
|
||||
#include <wlr/types/wlr_input_timestamps_v1.h>
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "input-timestamps-unstable-v1-protocol.h"
|
||||
|
||||
#define INPUT_TIMESTAMPS_MANAGER_VERSION 1
|
||||
|
||||
static const struct zwp_input_timestamps_manager_v1_interface manager_impl;
|
||||
static const struct zwp_input_timestamps_v1_interface impl;
|
||||
|
||||
/**
|
||||
* helper functions
|
||||
*/
|
||||
|
||||
static struct wlr_input_timestamps_v1 *
|
||||
from_resource(struct wl_resource *resource) {
|
||||
assert(wl_resource_instance_of(resource,
|
||||
&zwp_input_timestamps_v1_interface,
|
||||
&impl));
|
||||
return wl_resource_get_user_data(resource);
|
||||
}
|
||||
|
||||
static struct wlr_input_timestamps_manager_v1 *
|
||||
manager_from_resource(struct wl_resource *resource) {
|
||||
assert(wl_resource_instance_of(resource,
|
||||
&zwp_input_timestamps_manager_v1_interface,
|
||||
&manager_impl));
|
||||
return wl_resource_get_user_data(resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* input_timestamps handler functions
|
||||
*/
|
||||
|
||||
static void destroy(struct wlr_input_timestamps_v1 *input_timestamps) {
|
||||
wlr_signal_emit_safe(&input_timestamps->events.destroy, input_timestamps);
|
||||
|
||||
wl_list_remove(&input_timestamps->link);
|
||||
wl_list_remove(&input_timestamps->seat_destroy.link);
|
||||
wl_list_remove(&input_timestamps->input_destroy.link);
|
||||
|
||||
wl_resource_set_user_data(input_timestamps->resource, NULL);
|
||||
free(input_timestamps);
|
||||
}
|
||||
|
||||
static void handle_resource_destroy(struct wl_resource *resource) {
|
||||
struct wlr_input_timestamps_v1 *input_timestamps =
|
||||
from_resource(resource);
|
||||
if (input_timestamps == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
destroy(input_timestamps);
|
||||
}
|
||||
|
||||
static void handle_destroy(struct wl_client *client, struct wl_resource *resource) {
|
||||
struct wlr_input_timestamps_v1 *input_timestamps =
|
||||
from_resource(resource);
|
||||
wlr_log(WLR_DEBUG, "input_timestamps_v1 %p released by client %p",
|
||||
input_timestamps, client);
|
||||
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
static void handle_seat_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_input_timestamps_v1 *input_timestamps =
|
||||
wl_container_of(listener, input_timestamps, seat_destroy);
|
||||
|
||||
destroy(input_timestamps);
|
||||
}
|
||||
|
||||
static void handle_input_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_input_timestamps_v1 *input_timestamps =
|
||||
wl_container_of(listener, input_timestamps, input_destroy);
|
||||
|
||||
destroy(input_timestamps);
|
||||
}
|
||||
|
||||
/**
|
||||
* input_timestamps_manager handler functions
|
||||
*/
|
||||
|
||||
static void manager_handle_resource_destroy(struct wl_resource *resource) {
|
||||
wl_list_remove(wl_resource_get_link(resource));
|
||||
}
|
||||
|
||||
static void manager_handle_destroy(struct wl_client *client, struct wl_resource *resource) {
|
||||
wl_resource_destroy(resource);
|
||||
|
||||
wlr_log(WLR_DEBUG,
|
||||
"input_timestamps_v1 manager unbound from client %p", client);
|
||||
}
|
||||
|
||||
static void manager_handle_get_input_timestamps(struct wl_client *client,
|
||||
struct wl_resource *resource, uint32_t id, struct wl_resource *input,
|
||||
enum wlr_input_timestamps_type input_timestamps_type) {
|
||||
struct wlr_input_timestamps_manager_v1 *manager =
|
||||
manager_from_resource(resource);
|
||||
assert(manager);
|
||||
|
||||
struct wlr_seat_client *seat_client = NULL;
|
||||
switch (input_timestamps_type) {
|
||||
case WLR_INPUT_TIMESTAMPS_KEYBOARD:
|
||||
seat_client = wlr_seat_client_from_keyboard_resource(input);
|
||||
break;
|
||||
case WLR_INPUT_TIMESTAMPS_POINTER:
|
||||
seat_client = wlr_seat_client_from_pointer_resource(input);
|
||||
break;
|
||||
case WLR_INPUT_TIMESTAMPS_TOUCH:
|
||||
seat_client = wlr_seat_client_from_touch_resource(input);
|
||||
break;
|
||||
}
|
||||
|
||||
struct wlr_input_timestamps_v1 *input_timestamps =
|
||||
calloc(1, sizeof(struct wlr_input_timestamps_v1));
|
||||
if (input_timestamps == NULL) {
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
|
||||
struct wl_resource *input_timestamps_resource = wl_resource_create(client,
|
||||
&zwp_input_timestamps_v1_interface, wl_resource_get_version(resource), id);
|
||||
if (input_timestamps_resource == NULL) {
|
||||
free(input_timestamps);
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
|
||||
input_timestamps->resource = input_timestamps_resource;
|
||||
input_timestamps->input_resource = input;
|
||||
input_timestamps->seat = seat_client->seat;
|
||||
|
||||
wl_list_insert(&manager->input_timestamps, &input_timestamps->link);
|
||||
|
||||
input_timestamps->input_timestamps_type = input_timestamps_type;
|
||||
|
||||
wl_signal_init(&input_timestamps->events.destroy);
|
||||
|
||||
wl_signal_add(&input_timestamps->seat->events.destroy,
|
||||
&input_timestamps->seat_destroy);
|
||||
input_timestamps->seat_destroy.notify = handle_seat_destroy;
|
||||
|
||||
wl_resource_add_destroy_listener(input_timestamps->input_resource,
|
||||
&input_timestamps->input_destroy);
|
||||
input_timestamps->input_destroy.notify = handle_input_destroy;
|
||||
|
||||
wl_resource_set_implementation(input_timestamps_resource, &impl,
|
||||
input_timestamps, handle_resource_destroy);
|
||||
|
||||
switch (input_timestamps_type) {
|
||||
case WLR_INPUT_TIMESTAMPS_KEYBOARD:
|
||||
wlr_log(WLR_DEBUG,
|
||||
"input_timestamps_v1 %p created for client %p for keyboard events",
|
||||
input_timestamps, client);
|
||||
break;
|
||||
case WLR_INPUT_TIMESTAMPS_POINTER:
|
||||
wlr_log(WLR_DEBUG,
|
||||
"input_timestamps_v1 %p created for client %p for pointer events",
|
||||
input_timestamps, client);
|
||||
break;
|
||||
case WLR_INPUT_TIMESTAMPS_TOUCH:
|
||||
wlr_log(WLR_DEBUG,
|
||||
"input_timestamps_v1 %p created for client %p for touch events",
|
||||
input_timestamps, client);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void manager_handle_get_keyboard_timestamps(struct wl_client *client,
|
||||
struct wl_resource *resource, uint32_t id, struct wl_resource *keyboard) {
|
||||
manager_handle_get_input_timestamps(client, resource, id, keyboard,
|
||||
WLR_INPUT_TIMESTAMPS_KEYBOARD);
|
||||
}
|
||||
|
||||
static void manager_handle_get_pointer_timestamps(struct wl_client *client,
|
||||
struct wl_resource *resource, uint32_t id, struct wl_resource *pointer) {
|
||||
manager_handle_get_input_timestamps(client, resource, id, pointer,
|
||||
WLR_INPUT_TIMESTAMPS_POINTER);
|
||||
}
|
||||
|
||||
static void manager_handle_get_touch_timestamps(struct wl_client *client,
|
||||
struct wl_resource *resource, uint32_t id, struct wl_resource *touch) {
|
||||
manager_handle_get_input_timestamps(client, resource, id, touch,
|
||||
WLR_INPUT_TIMESTAMPS_TOUCH);
|
||||
}
|
||||
|
||||
static void manager_bind(struct wl_client *wl_client, void *data,
|
||||
uint32_t version, uint32_t id) {
|
||||
struct wlr_input_timestamps_manager_v1 *manager = data;
|
||||
|
||||
struct wl_resource *manager_resource = wl_resource_create(wl_client,
|
||||
&zwp_input_timestamps_manager_v1_interface, version, id);
|
||||
|
||||
if (manager_resource == NULL) {
|
||||
wl_client_post_no_memory(wl_client);
|
||||
return;
|
||||
}
|
||||
|
||||
wl_list_insert(&manager->resources, wl_resource_get_link(manager_resource));
|
||||
|
||||
wl_resource_set_implementation(manager_resource, &manager_impl,
|
||||
manager, manager_handle_resource_destroy);
|
||||
|
||||
wlr_log(WLR_DEBUG, "input_timestamps_v1 manager bound to client %p",
|
||||
wl_client);
|
||||
}
|
||||
|
||||
static void manager_handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_input_timestamps_manager_v1 *manager =
|
||||
wl_container_of(listener, manager, display_destroy_listener);
|
||||
wlr_input_timestamps_manager_v1_destroy(manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementations
|
||||
*/
|
||||
|
||||
static const struct zwp_input_timestamps_manager_v1_interface manager_impl = {
|
||||
.destroy = manager_handle_destroy,
|
||||
.get_keyboard_timestamps = manager_handle_get_keyboard_timestamps,
|
||||
.get_pointer_timestamps = manager_handle_get_pointer_timestamps,
|
||||
.get_touch_timestamps = manager_handle_get_touch_timestamps,
|
||||
};
|
||||
|
||||
static const struct zwp_input_timestamps_v1_interface impl = {
|
||||
.destroy = handle_destroy,
|
||||
};
|
||||
|
||||
/**
|
||||
* Public functions
|
||||
*/
|
||||
|
||||
struct wlr_input_timestamps_manager_v1 *wlr_input_timestamps_manager_v1_create(struct wl_display *display) {
|
||||
struct wlr_input_timestamps_manager_v1 *manager =
|
||||
calloc(1, sizeof(struct wlr_input_timestamps_manager_v1));
|
||||
|
||||
if (manager == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wl_list_init(&manager->resources);
|
||||
wl_list_init(&manager->input_timestamps);
|
||||
|
||||
manager->global = wl_global_create(display,
|
||||
&zwp_input_timestamps_manager_v1_interface, INPUT_TIMESTAMPS_MANAGER_VERSION,
|
||||
manager, manager_bind);
|
||||
|
||||
if (manager->global == NULL) {
|
||||
free(manager);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wl_signal_init(&manager->events.destroy);
|
||||
|
||||
manager->display_destroy_listener.notify = manager_handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &manager->display_destroy_listener);
|
||||
|
||||
wlr_log(WLR_DEBUG, "input_timestamps_v1 manager created");
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
void wlr_input_timestamps_manager_v1_destroy(struct wlr_input_timestamps_manager_v1 *manager) {
|
||||
if (manager == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_signal_emit_safe(&manager->events.destroy, manager);
|
||||
wl_list_remove(&manager->display_destroy_listener.link);
|
||||
|
||||
struct wlr_input_timestamps_v1 *object, *tmp_object;
|
||||
wl_list_for_each_safe(object, tmp_object, &manager->input_timestamps, link) {
|
||||
wl_resource_destroy(object->resource);
|
||||
}
|
||||
|
||||
struct wl_resource *resource, *tmp_resource;
|
||||
wl_resource_for_each_safe(resource, tmp_resource, &manager->resources) {
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
wl_global_destroy(manager->global);
|
||||
free(manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends input event timestamps in nanosecond accuracy depending on
|
||||
* input_timestamps object type.
|
||||
*/
|
||||
static void manager_send_timestamp(struct wlr_input_timestamps_manager_v1 *manager,
|
||||
struct wlr_seat *seat, uint64_t tv_sec, uint32_t tv_nsec,
|
||||
enum wlr_input_timestamps_type input_timestamps_type) {
|
||||
struct wlr_seat_client *focused_client = NULL;
|
||||
switch (input_timestamps_type) {
|
||||
case WLR_INPUT_TIMESTAMPS_KEYBOARD:
|
||||
focused_client = seat->keyboard_state.focused_client;
|
||||
break;
|
||||
case WLR_INPUT_TIMESTAMPS_POINTER:
|
||||
focused_client = seat->pointer_state.focused_client;
|
||||
break;
|
||||
case WLR_INPUT_TIMESTAMPS_TOUCH:
|
||||
// TODO: add support for touch input events
|
||||
focused_client = NULL;
|
||||
break;
|
||||
}
|
||||
if (focused_client == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_seat_client *seat_client = NULL;
|
||||
struct wlr_input_timestamps_v1 *input_timestamps;
|
||||
wl_list_for_each(input_timestamps, &manager->input_timestamps, link) {
|
||||
if (input_timestamps_type != input_timestamps->input_timestamps_type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (input_timestamps_type) {
|
||||
case WLR_INPUT_TIMESTAMPS_KEYBOARD:
|
||||
seat_client = wlr_seat_client_from_keyboard_resource(
|
||||
input_timestamps->input_resource);
|
||||
break;
|
||||
case WLR_INPUT_TIMESTAMPS_POINTER:
|
||||
seat_client = wlr_seat_client_from_pointer_resource(
|
||||
input_timestamps->input_resource);
|
||||
break;
|
||||
case WLR_INPUT_TIMESTAMPS_TOUCH:
|
||||
seat_client = wlr_seat_client_from_touch_resource(
|
||||
input_timestamps->input_resource);
|
||||
break;
|
||||
}
|
||||
if (seat != input_timestamps->seat || focused_client != seat_client) {
|
||||
continue;
|
||||
}
|
||||
|
||||
zwp_input_timestamps_v1_send_timestamp(input_timestamps->resource,
|
||||
(uint32_t)(tv_sec >> 32), (uint32_t)tv_sec, (uint32_t)tv_nsec);
|
||||
}
|
||||
}
|
||||
|
||||
void wlr_input_timestamps_manager_v1_send_keyboard_timestamp(
|
||||
struct wlr_input_timestamps_manager_v1 *manager, struct wlr_seat *seat,
|
||||
uint64_t tv_sec, uint32_t tv_nsec) {
|
||||
manager_send_timestamp(manager, seat, tv_sec, tv_nsec,
|
||||
WLR_INPUT_TIMESTAMPS_KEYBOARD);
|
||||
}
|
||||
|
||||
void wlr_input_timestamps_manager_v1_send_pointer_timestamp(
|
||||
struct wlr_input_timestamps_manager_v1 *manager, struct wlr_seat *seat,
|
||||
uint64_t tv_sec, uint32_t tv_nsec) {
|
||||
manager_send_timestamp(manager, seat, tv_sec, tv_nsec,
|
||||
WLR_INPUT_TIMESTAMPS_POINTER);
|
||||
}
|
||||
|
||||
void wlr_input_timestamps_manager_v1_send_touch_timestamp(
|
||||
struct wlr_input_timestamps_manager_v1 *manager, struct wlr_seat *seat,
|
||||
uint64_t tv_sec, uint32_t tv_nsec) {
|
||||
manager_send_timestamp(manager, seat, tv_sec, tv_nsec,
|
||||
WLR_INPUT_TIMESTAMPS_TOUCH);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue