From caa2df9856530e9544f1e7f7e7e342cec1da5a31 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Mon, 1 Aug 2022 18:07:27 +0900 Subject: [PATCH] seat: Add implementation for selection source This functionality will be used by ds_data_device_manager in future patches. Change-Id: Id1863f243ab718fff2aeee7cfa515a4c96e66b4d --- include/libds/seat.h | 4 +++ src/seat.h | 10 ++++++ src/seat/seat.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++ src/seat/seat_private.h | 7 ++++ 4 files changed, 106 insertions(+) diff --git a/include/libds/seat.h b/include/libds/seat.h index 8790bf9..aced712 100644 --- a/include/libds/seat.h +++ b/include/libds/seat.h @@ -7,6 +7,7 @@ #include #include #include +#include struct ds_seat; @@ -201,4 +202,7 @@ void ds_seat_touch_end_grab(struct ds_seat *seat); void ds_seat_touch_add_grab_start_listener(struct ds_seat *seat, struct wl_listener *listener); +void ds_seat_set_selection(struct ds_seat *seat, struct ds_data_source *source, + uint32_t serial); + #endif diff --git a/src/seat.h b/src/seat.h index 94275f5..59a1d10 100644 --- a/src/seat.h +++ b/src/seat.h @@ -31,6 +31,16 @@ struct ds_seat_touch_grab void *data; }; +void ds_seat_add_set_selection_listener(struct ds_seat *seat, + struct wl_listener *listener); + +struct ds_data_source *ds_seat_get_selection(struct ds_seat *seat); + +struct ds_seat_client *ds_seat_client_from_resource( + struct wl_resource *resource); + +struct ds_seat *ds_seat_client_get_seat(struct ds_seat_client *seat_client); + void ds_seat_pointer_enter(struct ds_seat *seat, struct ds_surface *surface, double sx, double sy); diff --git a/src/seat/seat.c b/src/seat/seat.c index 36ed366..52a0d8d 100644 --- a/src/seat/seat.c +++ b/src/seat/seat.c @@ -1,5 +1,6 @@ #include "config.h" +#include #define _POSIX_C_SOURCE 200809L #include #include @@ -10,10 +11,14 @@ #define SEAT_VERSION 7 +static const struct wl_seat_interface seat_impl; + static void seat_handle_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id); static void seat_handle_display_destroy(struct wl_listener *listener, void *data); +static void seat_handle_selection_source_destroy(struct wl_listener *listener, + void *data); static void seat_destroy(struct ds_seat *seat); static struct ds_seat_client *seat_client_create(struct ds_seat *seat, struct wl_client *wl_client); @@ -65,6 +70,7 @@ ds_seat_create(struct wl_display *display, const char *name) wl_signal_init(&seat->events.keyboard_grab_end); wl_signal_init(&seat->events.touch_grab_begin); wl_signal_init(&seat->events.touch_grab_end); + wl_signal_init(&seat->events.set_selection); seat->display_destroy.notify = seat_handle_display_destroy; wl_display_add_destroy_listener(display, &seat->display_destroy); @@ -149,6 +155,13 @@ ds_seat_client_for_wl_client(struct ds_seat *seat, struct wl_client *wl_client) return seat_client_for_wl_client(seat, wl_client); } +WL_EXPORT struct ds_seat_client * +ds_seat_client_from_resource(struct wl_resource *resource) +{ + assert(wl_resource_instance_of(resource, &wl_seat_interface, &seat_impl)); + return wl_resource_get_user_data(resource); +} + WL_EXPORT void ds_seat_client_add_destroy_listener(struct ds_seat_client *seat_client, struct wl_listener *listener) @@ -156,6 +169,64 @@ ds_seat_client_add_destroy_listener(struct ds_seat_client *seat_client, wl_signal_add(&seat_client->events.destroy, listener); } +WL_EXPORT void +ds_seat_set_selection(struct ds_seat *seat, struct ds_data_source *source, + uint32_t serial) +{ + if (seat->selection_source && + seat->selection_serial - serial < UINT32_MAX / 2) { + ds_dbg("Rejecting set selection selection_serial(%d) serial(%d)", + seat->selection_serial, serial); + return; + } + + seat->selection_serial = serial; + + if (seat->selection_source == source) + return; + + if (seat->selection_source) { + /* TODO + wl_list_remove(&seat->selection_source_destroy.link); + ds_data_source_destroy(seat->selection_source); + */ + seat->selection_source = NULL; + + } + + if (source) { + /* TODO + seat->selection_source_destroy.notify = + seat_handle_selection_source_destroy; + wl_signal_add(&source->events.destroy, + &seat->selection_source_destroy); + */ + + seat->selection_source = source; + } + + wl_signal_emit(&seat->events.set_selection, seat); +} + +struct ds_data_source * +ds_seat_get_selection(struct ds_seat *seat) +{ + return seat->selection_source; +} + +struct ds_seat * +ds_seat_client_get_seat(struct ds_seat_client *seat_client) +{ + return seat_client->seat; +} + +void +ds_seat_add_set_selection_listener(struct ds_seat *seat, + struct wl_listener *listener) +{ + wl_signal_add(&seat->events.set_selection, listener); +} + struct ds_seat_client * seat_client_for_wl_client(struct ds_seat *seat, struct wl_client *wl_client) { @@ -339,6 +410,20 @@ seat_handle_display_destroy(struct wl_listener *listener, void *data) } static void +seat_handle_selection_source_destroy(struct wl_listener *listener, + void *data) +{ + struct ds_seat *seat; + + seat = wl_container_of(listener, seat, selection_source_destroy); + + wl_list_remove(&seat->selection_source_destroy.link); + seat->selection_source = NULL; + + wl_signal_emit(&seat->events.set_selection, seat); +} + +static void seat_destroy(struct ds_seat *seat) { struct ds_seat_client *seat_client, *tmp; diff --git a/src/seat/seat_private.h b/src/seat/seat_private.h index 0211a72..4c6833d 100644 --- a/src/seat/seat_private.h +++ b/src/seat/seat_private.h @@ -120,6 +120,9 @@ struct ds_seat struct wl_display *display; struct wl_global *global; + struct ds_data_source *selection_source; + uint32_t selection_serial; + struct wl_list clients; // ds_seat_client::link struct ds_seat_pointer pointer; @@ -127,6 +130,7 @@ struct ds_seat struct ds_seat_touch touch; struct wl_listener display_destroy; + struct wl_listener selection_source_destroy; struct { struct wl_signal destroy; @@ -139,6 +143,9 @@ struct ds_seat struct wl_signal touch_grab_begin; struct wl_signal touch_grab_end; + + struct wl_signal set_selection; + struct wl_signal start_drag; } events; }; -- 2.7.4