static void data_handle_client_iface_send(struct ds_data_source *source,
const char *mime_type, int32_t fd);
static void data_source_client_iface_destroy(struct ds_data_source *source);
+static void data_source_client_iface_dnd_drop(
+ struct ds_data_source *ds_source);
+static void data_source_client_iface_dnd_finish(
+ struct ds_data_source *ds_source);
+static void data_source_client_iface_dnd_action(
+ struct ds_data_source *ds_source,
+ enum wl_data_device_manager_dnd_action action);
struct ds_data_source_client *
create_data_source_client(struct wl_client *client, uint32_t version,
source->iface.send = data_handle_client_iface_send;
source->iface.destroy = data_source_client_iface_destroy;
+ if (wl_resource_get_version(source->resource) >=
+ WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION) {
+ source->iface.dnd_drop = data_source_client_iface_dnd_drop;
+ }
+
+ if (wl_resource_get_version(source->resource) >=
+ WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION) {
+ source->iface.dnd_finish = data_source_client_iface_dnd_finish;
+ }
+
+ if (wl_resource_get_version(source->resource) >=
+ WL_DATA_SOURCE_ACTION_SINCE_VERSION) {
+ source->iface.dnd_action = data_source_client_iface_dnd_action;
+ }
+
ds_data_source_init(&source->base, &source->iface);
return source;
if (!source)
return;
- // TODO
+ if (source->base.actions >= 0) {
+ wl_resource_post_error(source->resource,
+ WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
+ "cannot set actions more than once");
+ return;
+ }
+
+ if (dnd_actions & ~DATA_DEVICE_ALL_ACTIONS) {
+ wl_resource_post_error(source->resource,
+ WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
+ "invalid action mask %x", dnd_actions);
+ return;
+ }
+
+ if (source->finalized) {
+ wl_resource_post_error(source->resource,
+ WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
+ "invalid action change after wl_data_device.start_drag");
+ return;
+ }
+
+ source->base.actions = dnd_actions;
}
static const struct wl_data_source_interface wl_data_source_iface = {
wl_resource_set_user_data(source->resource, NULL);
free(source);
}
+
+static void
+data_source_client_iface_dnd_drop(struct ds_data_source *ds_source)
+{
+ struct ds_data_source_client *source;
+
+ source = data_source_client_from_data_source(ds_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
+data_source_client_iface_dnd_finish(struct ds_data_source *ds_source)
+{
+ struct ds_data_source_client *source;
+
+ source = data_source_client_from_data_source(ds_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
+data_source_client_iface_dnd_action(struct ds_data_source *ds_source,
+ enum wl_data_device_manager_dnd_action action)
+{
+ struct ds_data_source_client *source;
+
+ source = data_source_client_from_data_source(ds_source);
+ assert(wl_resource_get_version(source->resource) >=
+ WL_DATA_SOURCE_ACTION_SINCE_VERSION);
+ wl_data_source_send_dnd_finished(source->resource);
+}