@ -9,6 +9,8 @@
# include "gtk-primary-selection-protocol.h"
# include "gtk-primary-selection-protocol.h"
# include "util/signal.h"
# include "util/signal.h"
# define DEVICE_MANAGER_VERSION 1
static const struct gtk_primary_selection_offer_interface offer_impl ;
static const struct gtk_primary_selection_offer_interface offer_impl ;
static struct wlr_primary_selection_offer * offer_from_resource (
static struct wlr_primary_selection_offer * offer_from_resource (
@ -21,12 +23,12 @@ static struct wlr_primary_selection_offer *offer_from_resource(
static void offer_handle_receive ( struct wl_client * client ,
static void offer_handle_receive ( struct wl_client * client ,
struct wl_resource * resource , const char * mime_type , int32_t fd ) {
struct wl_resource * resource , const char * mime_type , int32_t fd ) {
struct wlr_primary_selection_offer * offer = offer_from_resource ( resource ) ;
struct wlr_primary_selection_offer * offer = offer_from_resource ( resource ) ;
if ( offer = = NULL ) {
if ( offer - > source & & offer = = offer - > source - > offer ) {
offer - > source - > send ( offer - > source , mime_type , fd ) ;
} else {
close ( fd ) ;
close ( fd ) ;
return ;
}
}
offer - > source - > send ( offer - > source , mime_type , fd ) ;
}
}
static void offer_handle_destroy ( struct wl_client * client ,
static void offer_handle_destroy ( struct wl_client * client ,
@ -39,31 +41,26 @@ static const struct gtk_primary_selection_offer_interface offer_impl = {
. destroy = offer_handle_destroy ,
. destroy = offer_handle_destroy ,
} ;
} ;
static void offer_resource_handle_destroy ( struct wl_resource * resource ) {
static void offer_destroy ( struct wlr_primary_selection_offer * offer ) {
struct wlr_primary_selection_offer * offer = offer_from_resource ( resource ) ;
if ( offer = = NULL ) {
return ;
if ( ! offer - > source ) {
goto out ;
}
}
// Make resource inert
wl_resource_set_user_data ( offer - > resource , NULL ) ;
wl_list_remove ( & offer - > source_destroy . link ) ;
wl_list_remove ( & offer - > source_destroy . link ) ;
free ( offer ) ;
if ( offer - > source - > offer ! = offer ) {
goto out ;
}
}
offer - > source - > offer = NULL ;
static void offer_handle_resource_destroy ( struct wl_resource * resource ) {
struct wlr_primary_selection_offer * offer = offer_from_resource ( resource ) ;
out :
offer_destroy ( offer ) ;
free ( offer ) ;
}
}
static void offer_handle_source_destroy ( struct wl_listener * listener ,
static void offer_handle_source_destroy ( struct wl_listener * listener ,
void * data ) {
void * data ) {
struct wlr_primary_selection_offer * offer =
struct wlr_primary_selection_offer * offer =
wl_container_of ( listener , offer , source_destroy ) ;
wl_container_of ( listener , offer , source_destroy ) ;
offer_destroy ( offer ) ;
offer - > source = NULL ;
}
}
@ -85,38 +82,32 @@ static void client_source_cancel(
gtk_primary_selection_source_send_cancelled ( source - > resource ) ;
gtk_primary_selection_source_send_cancelled ( source - > resource ) ;
}
}
static struct wlr_primary_selection_offer * source_send_offer (
static void source_send_offer ( struct wlr_primary_selection_source * source ,
struct wlr_primary_selection_source * source ,
struct wl_resource * device_resource ) {
struct wlr_seat_client * target ) {
if ( wl_list_empty ( & target - > primary_selection_devices ) ) {
return NULL ;
}
struct wlr_primary_selection_offer * offer =
struct wlr_primary_selection_offer * offer =
calloc ( 1 , sizeof ( struct wlr_primary_selection_offer ) ) ;
calloc ( 1 , sizeof ( struct wlr_primary_selection_offer ) ) ;
if ( offer = = NULL ) {
if ( offer = = NULL ) {
return NULL ;
wl_resource_post_no_memory ( device_resource ) ;
return ;
}
}
uint32_t version = wl_resource_get_version (
struct wl_client * client = wl_resource_get_client ( device_resource ) ;
wl_resource_from_link ( target - > primary_selection_devices . next ) ) ;
uint32_t version = wl_resource_get_version ( device_resource ) ;
offer - > resource = wl_resource_create ( target- > client,
offer - > resource = wl_resource_create ( client,
& gtk_primary_selection_offer_interface , version , 0 ) ;
& gtk_primary_selection_offer_interface , version , 0 ) ;
if ( offer - > resource = = NULL ) {
if ( offer - > resource = = NULL ) {
free ( offer ) ;
free ( offer ) ;
return NULL ;
wl_resource_post_no_memory ( device_resource ) ;
return ;
}
}
wl_resource_set_implementation ( offer - > resource , & offer_impl , offer ,
wl_resource_set_implementation ( offer - > resource , & offer_impl , offer ,
offer_ resource_handl e_destroy) ;
offer_ handle_ resource_destroy) ;
offer - > source_destroy . notify = offer_handle_source_destroy ;
offer - > source_destroy . notify = offer_handle_source_destroy ;
wl_signal_add ( & source - > events . destroy , & offer - > source_destroy ) ;
wl_signal_add ( & source - > events . destroy , & offer - > source_destroy ) ;
struct wl_resource * target_resource ;
gtk_primary_selection_device_send_data_offer ( device_resource ,
wl_resource_for_each ( target_resource , & target - > primary_selection_devices ) {
gtk_primary_selection_device_send_data_offer ( target_resource ,
offer - > resource ) ;
offer - > resource ) ;
}
char * * p ;
char * * p ;
wl_array_for_each ( p , & source - > mime_types ) {
wl_array_for_each ( p , & source - > mime_types ) {
@ -124,9 +115,9 @@ static struct wlr_primary_selection_offer *source_send_offer(
}
}
offer - > source = source ;
offer - > source = source ;
source - > offer = offer ;
return offer ;
gtk_primary_selection_device_send_selection ( device_resource ,
offer - > resource ) ;
}
}
static const struct gtk_primary_selection_source_interface source_impl ;
static const struct gtk_primary_selection_source_interface source_impl ;
@ -179,20 +170,13 @@ void wlr_seat_client_send_primary_selection(
return ;
return ;
}
}
if ( seat_client - > seat - > primary_selection_source ) {
struct wlr_primary_selection_source * source =
struct wlr_primary_selection_offer * offer = source_send_offer (
seat_client - > seat - > primary_selection_source ;
seat_client - > seat - > primary_selection_source , seat_client ) ;
if ( offer = = NULL ) {
return ;
}
struct wl_resource * resource ;
struct wl_resource * resource ;
wl_resource_for_each ( resource , & seat_client - > primary_selection_devices ) {
wl_resource_for_each ( resource , & seat_client - > primary_selection_devices ) {
gtk_primary_selection_device_send_selection ( resource , offer - > resource ) ;
if ( source ) {
}
source_send_offer ( source , resource ) ;
} else {
} else {
struct wl_resource * resource ;
wl_resource_for_each ( resource , & seat_client - > primary_selection_devices ) {
gtk_primary_selection_device_send_selection ( resource , NULL ) ;
gtk_primary_selection_device_send_selection ( resource , NULL ) ;
}
}
}
}
@ -401,8 +385,8 @@ struct wlr_primary_selection_device_manager *
return NULL ;
return NULL ;
}
}
manager - > global = wl_global_create ( display ,
manager - > global = wl_global_create ( display ,
& gtk_primary_selection_device_manager_interface , 1 , manager ,
& gtk_primary_selection_device_manager_interface , DEVICE_MANAGER_VERSION ,
primary_selection_device_manager_bind) ;
manager, primary_selection_device_manager_bind) ;
if ( manager - > global = = NULL ) {
if ( manager - > global = = NULL ) {
free ( manager ) ;
free ( manager ) ;
return NULL ;
return NULL ;