From 6dffaa7bb79b88253f5fb9c6f106b19554a68b23 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 25 Dec 2017 16:10:16 +0100 Subject: Implement xwayland primary selection sync --- include/wlr/types/wlr_data_device.h | 3 +++ include/wlr/types/wlr_primary_selection.h | 5 ++++- include/wlr/xwm.h | 37 +++++++++++++++++++------------ 3 files changed, 30 insertions(+), 15 deletions(-) (limited to 'include/wlr') diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h index 70d79a19..fa5a7834 100644 --- a/include/wlr/types/wlr_data_device.h +++ b/include/wlr/types/wlr_data_device.h @@ -34,6 +34,7 @@ struct wlr_data_source { struct wl_resource *resource; struct wlr_data_offer *offer; struct wlr_seat_client *seat_client; + struct wl_array mime_types; bool accepted; @@ -123,4 +124,6 @@ void wlr_seat_client_send_selection(struct wlr_seat_client *seat_client); void wlr_seat_set_selection(struct wlr_seat *seat, struct wlr_data_source *source, uint32_t serial); +void wlr_data_source_init(struct wlr_data_source *source); + #endif diff --git a/include/wlr/types/wlr_primary_selection.h b/include/wlr/types/wlr_primary_selection.h index a639b913..94309b57 100644 --- a/include/wlr/types/wlr_primary_selection.h +++ b/include/wlr/types/wlr_primary_selection.h @@ -48,6 +48,9 @@ void wlr_primary_selection_device_manager_destroy( void wlr_seat_client_send_primary_selection(struct wlr_seat_client *seat_client); void wlr_seat_set_primary_selection(struct wlr_seat *seat, - struct wlr_primary_selection_source *source, uint32_t serial); + struct wlr_primary_selection_source *source, uint32_t serial); + +void wlr_primary_selection_source_init( + struct wlr_primary_selection_source *source); #endif diff --git a/include/wlr/xwm.h b/include/wlr/xwm.h index 47e674c0..cbc2f132 100644 --- a/include/wlr/xwm.h +++ b/include/wlr/xwm.h @@ -32,6 +32,7 @@ enum atom_name { _NET_WM_STATE_MAXIMIZED_HORZ, WM_STATE, CLIPBOARD, + PRIMARY, WL_SELECTION, TARGETS, CLIPBOARD_MANAGER, @@ -49,6 +50,24 @@ enum net_wm_state_action { NET_WM_STATE_TOGGLE = 2, }; +struct wlr_xwm_selection { + struct wlr_xwm *xwm; + xcb_atom_t atom; + xcb_window_t window; + xcb_selection_request_event_t request; + xcb_window_t owner; + xcb_timestamp_t timestamp; + int incr; + int source_fd; + int property_start; + xcb_get_property_reply_t *property_reply; + struct wl_event_source *property_source; + int flush_property_on_delete; + struct wl_array source_data; + xcb_atom_t target; + bool property_set; +}; + struct wlr_xwm { struct wlr_xwayland *xwayland; struct wl_event_source *event_source; @@ -63,20 +82,9 @@ struct wlr_xwm { xcb_render_pictformat_t render_format_id; xcb_cursor_t cursor; - // selection properties xcb_window_t selection_window; - xcb_selection_request_event_t selection_request; - xcb_window_t selection_owner; - xcb_timestamp_t selection_timestamp; - int incr; - int data_source_fd; - int property_start; - xcb_get_property_reply_t *property_reply; - struct wl_event_source *property_source; - int flush_property_on_delete; - struct wl_array source_data; - xcb_atom_t selection_target; - bool selection_property_set; + struct wlr_xwm_selection clipboard_selection; + struct wlr_xwm_selection primary_selection; struct wlr_xwayland_surface *focus_surface; @@ -86,7 +94,8 @@ struct wlr_xwm { const xcb_query_extension_reply_t *xfixes; struct wl_listener compositor_surface_create; - struct wl_listener seat_selection_change; + struct wl_listener seat_selection; + struct wl_listener seat_primary_selection; }; struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland); -- cgit v1.2.3 From 4a11609b7634356978e48b8b6976922777cf9e61 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 25 Dec 2017 18:18:26 +0100 Subject: Fix use-after-free when destroying selection sources --- include/wlr/types/wlr_data_device.h | 2 ++ include/wlr/types/wlr_primary_selection.h | 2 ++ types/wlr_data_device.c | 25 +++++++++++++++---------- types/wlr_primary_selection.c | 25 ++++++++++++++++--------- xwayland/selection.c | 2 ++ 5 files changed, 37 insertions(+), 19 deletions(-) (limited to 'include/wlr') diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h index fa5a7834..4893bbf4 100644 --- a/include/wlr/types/wlr_data_device.h +++ b/include/wlr/types/wlr_data_device.h @@ -126,4 +126,6 @@ void wlr_seat_set_selection(struct wlr_seat *seat, void wlr_data_source_init(struct wlr_data_source *source); +void wlr_data_source_finish(struct wlr_data_source *source); + #endif diff --git a/include/wlr/types/wlr_primary_selection.h b/include/wlr/types/wlr_primary_selection.h index 94309b57..b4eceb78 100644 --- a/include/wlr/types/wlr_primary_selection.h +++ b/include/wlr/types/wlr_primary_selection.h @@ -52,5 +52,7 @@ void wlr_seat_set_primary_selection(struct wlr_seat *seat, void wlr_primary_selection_source_init( struct wlr_primary_selection_source *source); +void wlr_primary_selection_source_finish( + struct wlr_primary_selection_source *source); #endif diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index eb1b4e0f..51789047 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -856,16 +856,7 @@ void data_device_manager_get_data_device(struct wl_client *client, static void data_source_resource_destroy(struct wl_resource *resource) { struct wlr_data_source *source = wl_resource_get_user_data(resource); - char **p; - - wl_signal_emit(&source->events.destroy, source); - - wl_array_for_each(p, &source->mime_types) { - free(*p); - } - - wl_array_release(&source->mime_types); - + wlr_data_source_finish(source); free(source); } @@ -932,6 +923,20 @@ void wlr_data_source_init(struct wlr_data_source *source) { wl_signal_init(&source->events.destroy); } +void wlr_data_source_finish(struct wlr_data_source *source) { + if (source == NULL) { + return; + } + + wl_signal_emit(&source->events.destroy, source); + + char **p; + wl_array_for_each(p, &source->mime_types) { + free(*p); + } + wl_array_release(&source->mime_types); +} + static void data_device_manager_create_data_source(struct wl_client *client, struct wl_resource *resource, uint32_t id) { struct wlr_data_source *source = calloc(1, sizeof(struct wlr_data_source)); diff --git a/types/wlr_primary_selection.c b/types/wlr_primary_selection.c index 5af90121..8163d2e5 100644 --- a/types/wlr_primary_selection.c +++ b/types/wlr_primary_selection.c @@ -144,15 +144,7 @@ static const struct gtk_primary_selection_source_interface source_impl = { static void source_resource_handle_destroy(struct wl_resource *resource) { struct wlr_primary_selection_source *source = wl_resource_get_user_data(resource); - - wl_signal_emit(&source->events.destroy, source); - - char **p; - wl_array_for_each(p, &source->mime_types) { - free(*p); - } - wl_array_release(&source->mime_types); - + wlr_primary_selection_source_finish(source); free(source); } @@ -268,6 +260,21 @@ void wlr_primary_selection_source_init( wl_signal_init(&source->events.destroy); } +void wlr_primary_selection_source_finish( + struct wlr_primary_selection_source *source) { + if (source == NULL) { + return; + } + + wl_signal_emit(&source->events.destroy, source); + + char **p; + wl_array_for_each(p, &source->mime_types) { + free(*p); + } + wl_array_release(&source->mime_types); +} + static void device_manager_handle_create_source(struct wl_client *client, struct wl_resource *manager_resource, uint32_t id) { struct wlr_primary_selection_source *source = diff --git a/xwayland/selection.c b/xwayland/selection.c index be803599..e59bc4e6 100644 --- a/xwayland/selection.c +++ b/xwayland/selection.c @@ -508,6 +508,7 @@ static void data_source_send(struct wlr_data_source *base, static void data_source_cancel(struct wlr_data_source *base) { struct x11_data_source *source = (struct x11_data_source *)base; + wlr_data_source_finish(&source->base); wl_array_release(&source->mime_types_atoms); free(source); } @@ -533,6 +534,7 @@ static void primary_selection_source_cancel( struct wlr_primary_selection_source *base) { struct x11_primary_selection_source *source = (struct x11_primary_selection_source *)base; + wlr_primary_selection_source_finish(&source->base); wl_array_release(&source->mime_types_atoms); free(source); } -- cgit v1.2.3