Abstract wlr_primary_selection_source

This commit is contained in:
emersion 2017-12-29 23:23:00 +01:00
parent 062809723a
commit b20aed66d6
No known key found for this signature in database
GPG key ID: 0FDE7BE0E88F5E48
3 changed files with 121 additions and 101 deletions

View file

@ -15,16 +15,18 @@ struct wlr_primary_selection_device_manager {
struct wlr_primary_selection_offer; struct wlr_primary_selection_offer;
struct wlr_primary_selection_source { struct wlr_primary_selection_source {
struct wl_resource *resource; // source metadata
struct wlr_primary_selection_offer *offer;
struct wlr_seat_client *seat_client;
struct wl_array mime_types; struct wl_array mime_types;
// source implementation
void (*send)(struct wlr_primary_selection_source *source, void (*send)(struct wlr_primary_selection_source *source,
const char *mime_type, int32_t fd); const char *mime_type, int32_t fd);
void (*cancel)(struct wlr_primary_selection_source *source); void (*cancel)(struct wlr_primary_selection_source *source);
// source status
struct wlr_primary_selection_offer *offer;
struct wlr_seat_client *seat_client;
struct { struct {
struct wl_signal destroy; struct wl_signal destroy;
} events; } events;

View file

@ -75,58 +75,6 @@ static void data_offer_update_action(struct wlr_data_offer *offer) {
} }
} }
struct client_data_source {
struct wlr_data_source source;
struct wl_resource *resource;
};
static void client_data_source_accept(struct wlr_data_source *wlr_source,
uint32_t serial, const char *mime_type) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
wl_data_source_send_target(source->resource, mime_type);
}
static void client_data_source_send(struct wlr_data_source *wlr_source,
const char *mime_type, int32_t fd) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
wl_data_source_send_send(source->resource, mime_type, fd);
close(fd);
}
static void client_data_source_cancel(struct wlr_data_source *wlr_source) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
wl_data_source_send_cancelled(source->resource);
}
static void client_data_source_dnd_drop(struct wlr_data_source *wlr_source) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
assert(wl_resource_get_version(source->resource) >=
WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION);
wl_data_source_send_dnd_drop_performed(source->resource);
}
static void client_data_source_dnd_finish(struct wlr_data_source *wlr_source) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
assert(wl_resource_get_version(source->resource) >=
WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION);
wl_data_source_send_dnd_finished(source->resource);
}
static void client_data_source_dnd_action(struct wlr_data_source *wlr_source,
enum wl_data_device_manager_dnd_action action) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
assert(wl_resource_get_version(source->resource) >=
WL_DATA_SOURCE_ACTION_SINCE_VERSION);
wl_data_source_send_action(source->resource, action);
}
static void client_data_source_resource_destroy(struct wl_resource *resource) {
struct client_data_source *source = wl_resource_get_user_data(resource);
wlr_data_source_finish(&source->source);
free(source);
}
static void data_offer_accept(struct wl_client *client, static void data_offer_accept(struct wl_client *client,
struct wl_resource *resource, uint32_t serial, const char *mime_type) { struct wl_resource *resource, uint32_t serial, const char *mime_type) {
struct wlr_data_offer *offer = wl_resource_get_user_data(resource); struct wlr_data_offer *offer = wl_resource_get_user_data(resource);
@ -343,8 +291,11 @@ static void seat_client_selection_data_source_destroy(
void wlr_seat_set_selection(struct wlr_seat *seat, void wlr_seat_set_selection(struct wlr_seat *seat,
struct wlr_data_source *source, uint32_t serial) { struct wlr_data_source *source, uint32_t serial) {
if (source) {
assert(source->send); assert(source->send);
assert(source->cancel); assert(source->cancel);
}
if (seat->selection_source && if (seat->selection_source &&
seat->selection_serial - serial < UINT32_MAX / 2) { seat->selection_serial - serial < UINT32_MAX / 2) {
return; return;
@ -861,22 +812,50 @@ static void data_device_destroy(struct wl_resource *resource) {
wl_list_remove(wl_resource_get_link(resource)); wl_list_remove(wl_resource_get_link(resource));
} }
void data_device_manager_get_data_device(struct wl_client *client,
struct wl_resource *manager_resource, uint32_t id,
struct wl_resource *seat_resource) {
struct wlr_seat_client *seat_client =
wl_resource_get_user_data(seat_resource);
struct wl_resource *resource = wl_resource_create(client, struct client_data_source {
&wl_data_device_interface, wl_resource_get_version(manager_resource), struct wlr_data_source source;
id); struct wl_resource *resource;
if (resource == NULL) { };
wl_resource_post_no_memory(manager_resource);
return; static void client_data_source_accept(struct wlr_data_source *wlr_source,
uint32_t serial, const char *mime_type) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
wl_data_source_send_target(source->resource, mime_type);
} }
wl_resource_set_implementation(resource, &data_device_impl, seat_client,
&data_device_destroy); static void client_data_source_send(struct wlr_data_source *wlr_source,
wl_list_insert(&seat_client->data_devices, wl_resource_get_link(resource)); const char *mime_type, int32_t fd) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
wl_data_source_send_send(source->resource, mime_type, fd);
close(fd);
}
static void client_data_source_cancel(struct wlr_data_source *wlr_source) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
wl_data_source_send_cancelled(source->resource);
}
static void client_data_source_dnd_drop(struct wlr_data_source *wlr_source) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
assert(wl_resource_get_version(source->resource) >=
WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION);
wl_data_source_send_dnd_drop_performed(source->resource);
}
static void client_data_source_dnd_finish(struct wlr_data_source *wlr_source) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
assert(wl_resource_get_version(source->resource) >=
WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION);
wl_data_source_send_dnd_finished(source->resource);
}
static void client_data_source_dnd_action(struct wlr_data_source *wlr_source,
enum wl_data_device_manager_dnd_action action) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
assert(wl_resource_get_version(source->resource) >=
WL_DATA_SOURCE_ACTION_SINCE_VERSION);
wl_data_source_send_action(source->resource, action);
} }
static void data_source_destroy(struct wl_client *client, static void data_source_destroy(struct wl_client *client,
@ -936,6 +915,12 @@ static struct wl_data_source_interface data_source_impl = {
.set_actions = data_source_set_actions, .set_actions = data_source_set_actions,
}; };
static void data_source_resource_handle_destroy(struct wl_resource *resource) {
struct client_data_source *source = wl_resource_get_user_data(resource);
wlr_data_source_finish(&source->source);
free(source);
}
void wlr_data_source_init(struct wlr_data_source *source) { void wlr_data_source_init(struct wlr_data_source *source) {
wl_array_init(&source->mime_types); wl_array_init(&source->mime_types);
wl_signal_init(&source->events.destroy); wl_signal_init(&source->events.destroy);
@ -956,6 +941,25 @@ void wlr_data_source_finish(struct wlr_data_source *source) {
wl_array_release(&source->mime_types); wl_array_release(&source->mime_types);
} }
void data_device_manager_get_data_device(struct wl_client *client,
struct wl_resource *manager_resource, uint32_t id,
struct wl_resource *seat_resource) {
struct wlr_seat_client *seat_client =
wl_resource_get_user_data(seat_resource);
struct wl_resource *resource = wl_resource_create(client,
&wl_data_device_interface, wl_resource_get_version(manager_resource),
id);
if (resource == NULL) {
wl_resource_post_no_memory(manager_resource);
return;
}
wl_resource_set_implementation(resource, &data_device_impl, seat_client,
&data_device_destroy);
wl_list_insert(&seat_client->data_devices, wl_resource_get_link(resource));
}
static void data_device_manager_create_data_source(struct wl_client *client, static void data_device_manager_create_data_source(struct wl_client *client,
struct wl_resource *resource, uint32_t id) { struct wl_resource *resource, uint32_t id) {
struct client_data_source *source = struct client_data_source *source =
@ -974,7 +978,7 @@ static void data_device_manager_create_data_source(struct wl_client *client,
return; return;
} }
wl_resource_set_implementation(source->resource, &data_source_impl, wl_resource_set_implementation(source->resource, &data_source_impl,
source, client_data_source_resource_destroy); source, data_source_resource_handle_destroy);
source->source.accept = client_data_source_accept; source->source.accept = client_data_source_accept;
source->source.send = client_data_source_send; source->source.send = client_data_source_send;
@ -1019,6 +1023,7 @@ void wlr_data_device_manager_destroy(struct wlr_data_device_manager *manager) {
return; return;
} }
wl_list_remove(&manager->display_destroy.link); wl_list_remove(&manager->display_destroy.link);
// TODO: free wl_resources
wl_global_destroy(manager->global); wl_global_destroy(manager->global);
free(manager); free(manager);
} }

View file

@ -2,23 +2,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <assert.h>
#include <gtk-primary-selection-protocol.h> #include <gtk-primary-selection-protocol.h>
#include <wlr/types/wlr_primary_selection.h> #include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_seat.h> #include <wlr/types/wlr_seat.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
static void client_source_send(struct wlr_primary_selection_source *source,
const char *mime_type, int32_t fd) {
gtk_primary_selection_source_send_send(source->resource, mime_type, fd);
close(fd);
}
static void client_source_cancel(
struct wlr_primary_selection_source *source) {
gtk_primary_selection_source_send_cancelled(source->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 = struct wlr_primary_selection_offer *offer =
@ -55,8 +44,8 @@ static void offer_resource_handle_destroy(struct wl_resource *resource) {
goto out; goto out;
} }
if (offer->source->resource) { if (offer->source->cancel) {
gtk_primary_selection_source_send_cancelled(offer->source->resource); offer->source->cancel(offer->source);
} }
offer->source->offer = NULL; offer->source->offer = NULL;
@ -73,6 +62,24 @@ static void offer_handle_source_destroy(struct wl_listener *listener,
} }
struct client_data_source {
struct wlr_primary_selection_source source;
struct wl_resource *resource;
};
static void client_source_send(struct wlr_primary_selection_source *wlr_source,
const char *mime_type, int32_t fd) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
gtk_primary_selection_source_send_send(source->resource, mime_type, fd);
close(fd);
}
static void client_source_cancel(
struct wlr_primary_selection_source *wlr_source) {
struct client_data_source *source = (struct client_data_source *)wlr_source;
gtk_primary_selection_source_send_cancelled(source->resource);
}
static struct wlr_primary_selection_offer *source_send_offer( static struct wlr_primary_selection_offer *source_send_offer(
struct wlr_primary_selection_source *source, struct wlr_primary_selection_source *source,
struct wlr_seat_client *target) { struct wlr_seat_client *target) {
@ -119,16 +126,15 @@ static struct wlr_primary_selection_offer *source_send_offer(
static void source_handle_offer(struct wl_client *client, static void source_handle_offer(struct wl_client *client,
struct wl_resource *resource, const char *mime_type) { struct wl_resource *resource, const char *mime_type) {
struct wlr_primary_selection_source *source = struct client_data_source *source = wl_resource_get_user_data(resource);
wl_resource_get_user_data(resource);
char **p = wl_array_add(&source->mime_types, sizeof(*p)); char **p = wl_array_add(&source->source.mime_types, sizeof(*p));
if (p) { if (p) {
*p = strdup(mime_type); *p = strdup(mime_type);
} }
if (p == NULL || *p == NULL) { if (p == NULL || *p == NULL) {
if (p) { if (p) {
source->mime_types.size -= sizeof(*p); source->source.mime_types.size -= sizeof(*p);
} }
wl_resource_post_no_memory(resource); wl_resource_post_no_memory(resource);
} }
@ -145,9 +151,9 @@ static const struct gtk_primary_selection_source_interface source_impl = {
}; };
static void source_resource_handle_destroy(struct wl_resource *resource) { static void source_resource_handle_destroy(struct wl_resource *resource) {
struct wlr_primary_selection_source *source = struct client_data_source *source =
wl_resource_get_user_data(resource); wl_resource_get_user_data(resource);
wlr_primary_selection_source_finish(source); wlr_primary_selection_source_finish(&source->source);
free(source); free(source);
} }
@ -197,6 +203,11 @@ static void seat_client_primary_selection_source_destroy(
void wlr_seat_set_primary_selection(struct wlr_seat *seat, 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) {
if (source) {
assert(source->send);
assert(source->cancel);
}
if (seat->primary_selection_source && if (seat->primary_selection_source &&
seat->primary_selection_serial - serial < UINT32_MAX / 2) { seat->primary_selection_serial - serial < UINT32_MAX / 2) {
return; return;
@ -230,7 +241,7 @@ void wlr_seat_set_primary_selection(struct wlr_seat *seat,
static void device_handle_set_selection(struct wl_client *client, static void device_handle_set_selection(struct wl_client *client,
struct wl_resource *resource, struct wl_resource *source_resource, struct wl_resource *resource, struct wl_resource *source_resource,
uint32_t serial) { uint32_t serial) {
struct wlr_primary_selection_source *source = NULL; struct client_data_source *source = NULL;
if (source_resource != NULL) { if (source_resource != NULL) {
source = wl_resource_get_user_data(source_resource); source = wl_resource_get_user_data(source_resource);
} }
@ -239,7 +250,9 @@ static void device_handle_set_selection(struct wl_client *client,
wl_resource_get_user_data(resource); wl_resource_get_user_data(resource);
// TODO: store serial and check against incoming serial here // TODO: store serial and check against incoming serial here
wlr_seat_set_primary_selection(seat_client->seat, source, serial); struct wlr_primary_selection_source *wlr_source =
(struct wlr_primary_selection_source *)source;
wlr_seat_set_primary_selection(seat_client->seat, wlr_source, serial);
} }
static void device_handle_destroy(struct wl_client *client, static void device_handle_destroy(struct wl_client *client,
@ -280,13 +293,13 @@ void wlr_primary_selection_source_finish(
static void device_manager_handle_create_source(struct wl_client *client, static void device_manager_handle_create_source(struct wl_client *client,
struct wl_resource *manager_resource, uint32_t id) { struct wl_resource *manager_resource, uint32_t id) {
struct wlr_primary_selection_source *source = struct client_data_source *source =
calloc(1, sizeof(struct wlr_primary_selection_source)); calloc(1, sizeof(struct client_data_source));
if (source == NULL) { if (source == NULL) {
wl_client_post_no_memory(client); wl_client_post_no_memory(client);
return; return;
} }
wlr_primary_selection_source_init(source); wlr_primary_selection_source_init(&source->source);
int version = wl_resource_get_version(manager_resource); int version = wl_resource_get_version(manager_resource);
source->resource = wl_resource_create(client, source->resource = wl_resource_create(client,
@ -299,8 +312,8 @@ static void device_manager_handle_create_source(struct wl_client *client,
wl_resource_set_implementation(source->resource, &source_impl, source, wl_resource_set_implementation(source->resource, &source_impl, source,
source_resource_handle_destroy); source_resource_handle_destroy);
source->send = client_source_send; source->source.send = client_source_send;
source->cancel = client_source_cancel; source->source.cancel = client_source_cancel;
} }
void device_manager_handle_get_device(struct wl_client *client, void device_manager_handle_get_device(struct wl_client *client,