devilhorns pushed a commit to branch master.
commit 6d0cc0d9bff55194a102f27f0472a9872715c183
Author: Chris Michael <[email protected]>
Date: Tue May 28 11:44:53 2013 +0100
Deprecate old dnd functions (useless, improperly named, etc)
Add shiny new Drag-N-Drop code ;)
Signed-off-by: Chris Michael <[email protected]>
---
src/lib/ecore_wayland/ecore_wl_dnd.c | 691 ++++++++++++++++++++++++-----------
1 file changed, 469 insertions(+), 222 deletions(-)
diff --git a/src/lib/ecore_wayland/ecore_wl_dnd.c
b/src/lib/ecore_wayland/ecore_wl_dnd.c
index 403e3b9..444e1e1 100644
--- a/src/lib/ecore_wayland/ecore_wl_dnd.c
+++ b/src/lib/ecore_wayland/ecore_wl_dnd.c
@@ -6,6 +6,7 @@
#include <sys/epoll.h>
#include "ecore_wl_private.h"
+/* local structures */
struct _dnd_task
{
void *data;
@@ -19,273 +20,486 @@ struct _dnd_read_ctx
};
/* local function prototypes */
-static void _ecore_wl_dnd_offer(void *data, struct wl_data_offer
*wl_data_offer EINA_UNUSED, const char *type);
-static void _ecore_wl_dnd_cb_enter_free(void *data EINA_UNUSED, void *event);
+static void _ecore_wl_dnd_selection_data_receive(Ecore_Wl_Dnd_Source *source,
const char *type);
+static Eina_Bool _ecore_wl_dnd_selection_data_read(void *data,
Ecore_Fd_Handler *fd_handler EINA_UNUSED);
+static void _ecore_wl_dnd_selection_data_ready_cb_free(void *data EINA_UNUSED,
void *event);
+static Eina_Bool _ecore_wl_dnd_selection_cb_idle(void *data);
-static void _ecore_wl_dnd_data_source_target(void *data, struct wl_data_source
*source, const char *mime_type);
-static void _ecore_wl_dnd_data_source_send(void *data, struct wl_data_source
*source, const char *mime_type, int32_t fd);
-static void _ecore_wl_dnd_data_source_cancelled(void *data, struct
wl_data_source *source);
-static void _ecore_wl_dnd_source_receive_data(Ecore_Wl_Dnd_Source *source,
const char *type);
+static void _ecore_wl_dnd_source_cb_target(void *data, struct wl_data_source
*source EINA_UNUSED, const char *mime_type EINA_UNUSED);
+static void _ecore_wl_dnd_source_cb_send(void *data, struct wl_data_source
*source EINA_UNUSED, const char *mime_type, int32_t fd);
+static void _ecore_wl_dnd_source_cb_send_free(void *data EINA_UNUSED, void
*event);
+static void _ecore_wl_dnd_source_cb_cancelled(void *data EINA_UNUSED, struct
wl_data_source *source);
-/* wayland listeners */
-static const struct wl_data_offer_listener _ecore_wl_data_offer_listener =
+static void _ecore_wl_dnd_offer_cb_offer(void *data, struct wl_data_offer
*data_offer EINA_UNUSED, const char *type);
+
+/* local wayland interfaces */
+static const struct wl_data_source_listener
+_ecore_wl_dnd_source_listener =
{
- _ecore_wl_dnd_offer,
+ _ecore_wl_dnd_source_cb_target,
+ _ecore_wl_dnd_source_cb_send,
+ _ecore_wl_dnd_source_cb_cancelled
};
-static const struct wl_data_source_listener _ecore_wl_data_source_listener =
+static const struct wl_data_offer_listener
+_ecore_wl_dnd_offer_listener =
{
- _ecore_wl_dnd_data_source_target,
- _ecore_wl_dnd_data_source_send,
- _ecore_wl_dnd_data_source_cancelled
+ _ecore_wl_dnd_offer_cb_offer
};
-extern Ecore_Wl_Dnd *glb_dnd;
+/**
+ * @deprecated use ecore_wl_dnd_selection_set
+ * @since 1.7
+*/
+EINA_DEPRECATED EAPI Eina_Bool
+ecore_wl_dnd_set_selection(Ecore_Wl_Dnd *dnd, const char **types_offered)
+{
+ return ecore_wl_dnd_selection_set(dnd->input, types_offered);
+}
+
+/**
+ * @deprecated use ecore_wl_dnd_selection_get
+ * @since 1.7
+*/
+EINA_DEPRECATED EAPI Eina_Bool
+ecore_wl_dnd_get_selection(Ecore_Wl_Dnd *dnd, const char *type)
+{
+ return ecore_wl_dnd_selection_get(dnd->input, type);
+}
-EAPI Ecore_Wl_Dnd *
-ecore_wl_dnd_get()
+/**
+ * @deprecated Do Not Use
+ * @since 1.7
+ */
+EINA_DEPRECATED EAPI Ecore_Wl_Dnd *
+ecore_wl_dnd_get(void)
{
- return glb_dnd;
+ return NULL;
}
-EAPI Eina_Bool
+/**
+ * @deprecated use ecore_wl_dnd_drag_start
+ * @since 1.7
+ */
+EINA_DEPRECATED EAPI Eina_Bool
ecore_wl_dnd_start_drag(Ecore_Wl_Dnd *dnd EINA_UNUSED)
{
- //TODO:
- return EINA_TRUE;
+ return EINA_FALSE;
}
-EAPI Eina_Bool
-ecore_wl_dnd_set_selection(Ecore_Wl_Dnd *dnd, const char **types_offered)
+/**
+ * @deprecated use ecore_wl_dnd_selection_owner_has
+ * @since 1.7
+ */
+EINA_DEPRECATED EAPI Eina_Bool
+ecore_wl_dnd_selection_has_owner(Ecore_Wl_Dnd *dnd)
+{
+ return ecore_wl_dnd_selection_owner_has(dnd->input);
+}
+
+/**
+ * @ingroup Ecore_Wl_Dnd_Group
+ * @since 1.8
+ */
+EAPI Eina_Bool
+ecore_wl_dnd_selection_set(Ecore_Wl_Input *input, const char **types_offered)
{
- char **p;
+ struct wl_data_device_manager *man;
const char **type;
+ char **t;
- dnd->data_source = _ecore_wl_create_data_source(dnd->ewd);
+ if (!input) return EINA_FALSE;
- /* free old types */
- if (dnd->types_offered.data)
+ man = input->display->wl.data_device_manager;
+
+ /* free any old types offered */
+ if (input->data_types.data)
{
- wl_array_for_each(p, &dnd->types_offered)
- free(*p);
- wl_array_release(&dnd->types_offered);
- wl_array_init(&dnd->types_offered);
+ wl_array_for_each(t, &input->data_types)
+ free(*t);
+ wl_array_release(&input->data_types);
+ wl_array_init(&input->data_types);
}
- for (type = types_offered; *type; type++)
+ /* destroy any existing data source */
+ if (input->data_source) wl_data_source_destroy(input->data_source);
+ input->data_source = NULL;
+
+ /* try to create a new data source */
+ if (!(input->data_source = wl_data_device_manager_create_data_source(man)))
+ return EINA_FALSE;
+
+ /* add these types to the data source */
+ for (type = types_offered; *type; type++)
{
- p = wl_array_add(&dnd->types_offered, sizeof(*p));
- *p = strdup(*type);
- wl_data_source_offer(dnd->data_source, *p);
+ t = wl_array_add(&input->data_types, sizeof(*t));
+ *t = strdup(*type);
+ wl_data_source_offer(input->data_source, *t);
}
- wl_data_source_add_listener(dnd->data_source,
&_ecore_wl_data_source_listener, dnd);
+ /* add a listener for data source events */
+ wl_data_source_add_listener(input->data_source,
+ &_ecore_wl_dnd_source_listener, input);
- _ecore_wl_input_set_selection(dnd->input, dnd->data_source);
+ /* set the selection */
+ wl_data_device_set_selection(input->data_device, input->data_source,
+ input->display->serial);
return EINA_TRUE;
}
-EAPI Eina_Bool
-ecore_wl_dnd_get_selection(Ecore_Wl_Dnd *dnd, const char *type)
+/**
+ * @ingroup Ecore_Wl_Dnd_Group
+ * @since 1.8
+ */
+EAPI Eina_Bool
+ecore_wl_dnd_selection_get(Ecore_Wl_Input *input, const char *type)
{
- char **p;
- Ecore_Wl_Input *input;
-
- input = dnd->input;
+ char **t;
- if (!input->selection_source) return EINA_FALSE;
+ /* check for valid input and selection source */
+ if ((!input) || (!input->selection_source)) return EINA_FALSE;
- wl_array_for_each(p, &input->selection_source->types)
- if (strcmp(type, *p) == 0) break;
+ wl_array_for_each(t, &input->selection_source->types)
+ if (!strcmp(type, *t)) break;
- if (!*p) return EINA_FALSE;
+ if (!*t) return EINA_FALSE;
- _ecore_wl_dnd_source_receive_data(input->selection_source, type);
+ _ecore_wl_dnd_selection_data_receive(input->selection_source, type);
return EINA_TRUE;
}
-EAPI Eina_Bool
-ecore_wl_dnd_selection_has_owner(Ecore_Wl_Dnd *dnd)
+/**
+ * @ingroup Ecore_Wl_Dnd_Group
+ * @since 1.8
+ */
+EAPI Eina_Bool
+ecore_wl_dnd_selection_owner_has(Ecore_Wl_Input *input)
{
- Ecore_Wl_Input *input;
-
- input = dnd->input;
+ if (!input) return EINA_FALSE;
return (input->selection_source != NULL);
}
-/* local functions */
-static void
-_ecore_wl_dnd_data_source_target(void *data EINA_UNUSED, struct wl_data_source
*source EINA_UNUSED, const char *mime_type EINA_UNUSED)
+/**
+ * @ingroup Ecore_Wl_Dnd_Group
+ * @since 1.8
+ */
+EAPI Eina_Bool
+ecore_wl_dnd_selection_clear(Ecore_Wl_Input *input)
{
- //TODO:
+ /* check for valid input */
+ if (!input) return EINA_FALSE;
+
+ /* set the selection to NULL */
+ wl_data_device_set_selection(input->data_device, NULL,
+ input->display->serial);
+
+ return EINA_TRUE;
}
-static void
-_ecore_wl_dnd_cb_data_source_send_free(void *data EINA_UNUSED, void *event)
+/**
+ * @ingroup Ecore_Wl_Dnd_Group
+ * @since 1.8
+ */
+EAPI void
+ecore_wl_dnd_drag_start(Ecore_Wl_Input *input, Ecore_Wl_Window *win,
Ecore_Wl_Window *dragwin, int x EINA_UNUSED, int y EINA_UNUSED, int w
EINA_UNUSED, int h EINA_UNUSED)
{
- Ecore_Wl_Event_Data_Source_Send *ev;
+ struct wl_surface *drag_surface;
+
+ /* check for valid input. if not, get the default one */
+ if (!input) input = _ecore_wl_disp->input;
+
+ /* check for valid data source */
+ if (!input->data_source) return;
+
+ /* get the surface from this drag window */
+ drag_surface = ecore_wl_window_surface_get(dragwin);
+
+ /* release any existing grabs */
+ ecore_wl_input_ungrab(input);
+
+ /* add a listener for data source events */
+ wl_data_source_add_listener(input->data_source,
+ &_ecore_wl_dnd_source_listener, input);
+
+ /* start the drag */
+ wl_data_device_start_drag(input->data_device, input->data_source,
+ ecore_wl_window_surface_get(win),
+ drag_surface, input->display->serial);
+
+ /* set pointer image */
+ ecore_wl_input_cursor_from_name_set(input, "move");
+
+ /* NB: Below code disabled for now
+ *
+ * This Was for adjusting the "drag icon" to be centered on the mouse
+ * based on the hotspot, but it crashes for some reason :(
+ */
+
+ /* struct wl_buffer *drag_buffer; */
+ /* struct wl_cursor_image *cursor; */
+ /* int cx = 0, cy = 0; */
+ /* drag_buffer = wl_surface_get_user_data(drag_surface); */
+ /* cursor = input->cursor->images[input->cursor_current_index]; */
+ /* cx = cursor->hotspot_x - x; */
+ /* cy = cursor->hotspot_y - y; */
+ /* wl_surface_attach(drag_surface, drag_buffer, cx, cy); */
+ /* wl_surface_damage(drag_surface, 0, 0, w, h); */
+ /* wl_surface_commit(drag_surface); */
+}
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+/**
+ * @ingroup Ecore_Wl_Dnd_Group
+ * @since 1.8
+ */
+EAPI void
+ecore_wl_dnd_drag_end(Ecore_Wl_Input *input)
+{
+ Ecore_Wl_Event_Dnd_End *ev;
- if (!(ev = event)) return;
+ /* check for valid input. if not, get the default one */
+ if (!input) input = _ecore_wl_disp->input;
- free(ev->type);
- free(ev);
+ if (input->data_types.data)
+ {
+ char **t;
+
+ wl_array_for_each(t, &input->data_types)
+ free(*t);
+ wl_array_release(&input->data_types);
+ wl_array_init(&input->data_types);
+ }
+
+ /* if (input->drag_source) _ecore_wl_dnd_del(input->drag_source); */
+ /* input->drag_source = NULL; */
+
+ /* destroy any existing data source */
+ if (input->data_source) wl_data_source_destroy(input->data_source);
+ input->data_source = NULL;
+
+ if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_End)))) return;
+
+ if (input->pointer_focus)
+ ev->win = input->pointer_focus->id;
+
+ if (input->keyboard_focus)
+ ev->source = input->keyboard_focus->id;
+
+ ecore_event_add(ECORE_WL_EVENT_DND_END, ev, NULL, NULL);
}
-static void
-_ecore_wl_dnd_data_source_send(void *data, struct wl_data_source *source
EINA_UNUSED, const char *mime_type, int32_t fd)
+/**
+ * @ingroup Ecore_Wl_Dnd_Group
+ * @since 1.8
+ */
+EAPI Eina_Bool
+ecore_wl_dnd_drag_get(Ecore_Wl_Input *input, const char *type)
{
- Ecore_Wl_Event_Data_Source_Send *event;
+ char **t;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ /* check for valid input and drag source */
+ if ((!input) || (!input->drag_source)) return EINA_FALSE;
- if (!data) return;
+ wl_array_for_each(t, &input->drag_source->types)
+ if (!strcmp(type, *t)) break;
- if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Data_Source_Send)))) return;
+ if (!*t) return EINA_FALSE;
- event->type = strdup(mime_type);
- event->fd = fd;
+ _ecore_wl_dnd_selection_data_receive(input->drag_source, type);
- ecore_event_add(ECORE_WL_EVENT_DATA_SOURCE_SEND, event,
_ecore_wl_dnd_cb_data_source_send_free, NULL);
+ return EINA_TRUE;
}
-static void
-_ecore_wl_dnd_data_source_cancelled(void *data EINA_UNUSED, struct
wl_data_source *source)
+/**
+ * @ingroup Ecore_Wl_Dnd_Group
+ * @since 1.8
+ */
+EAPI void
+ecore_wl_dnd_drag_types_set(Ecore_Wl_Input *input, const char **types_offered)
{
- wl_data_source_destroy(source);
+ struct wl_data_device_manager *man;
+ const char **type;
+ char **t;
+
+ /* check for valid input. if not, get the default one */
+ if (!input) input = _ecore_wl_disp->input;
+
+ man = input->display->wl.data_device_manager;
+
+ /* free any old types offered */
+ if (input->data_types.data)
+ {
+ wl_array_for_each(t, &input->data_types)
+ free(*t);
+ wl_array_release(&input->data_types);
+ wl_array_init(&input->data_types);
+ }
+
+ /* destroy any existing data source */
+ if (input->data_source) wl_data_source_destroy(input->data_source);
+ input->data_source = NULL;
+
+ /* try to create a new data source */
+ if (!(input->data_source = wl_data_device_manager_create_data_source(man)))
+ {
+ printf("Failed to create new data source for drag\n");
+ return;
+ }
+
+ /* add these types to the data source */
+ for (type = types_offered; *type; type++)
+ {
+ t = wl_array_add(&input->data_types, sizeof(*t));
+ *t = strdup(*type);
+ wl_data_source_offer(input->data_source, *t);
+ }
+}
+
+/**
+ * @ingroup Ecore_Wl_Dnd_Group
+ * @since 1.8
+ */
+EAPI struct wl_array *
+ecore_wl_dnd_drag_types_get(Ecore_Wl_Input *input)
+{
+ /* check for valid input. if not, get the default one */
+ if (!input) input = _ecore_wl_disp->input;
+
+ return &input->data_types;
}
+/* private functions */
void
_ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device
EINA_UNUSED, struct wl_data_offer *offer)
{
Ecore_Wl_Dnd_Source *source;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (!(source = malloc(sizeof(Ecore_Wl_Dnd_Source))))
+ return;
- if (!(source = malloc(sizeof(Ecore_Wl_Dnd_Source)))) return;
wl_array_init(&source->types);
source->refcount = 1;
source->input = input;
- source->offer = offer;
- wl_data_offer_add_listener(source->offer,
- &_ecore_wl_data_offer_listener, source);
+ source->data_offer = offer;
+
+ wl_data_offer_add_listener(source->data_offer,
+ &_ecore_wl_dnd_offer_listener, source);
}
void
-_ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device
EINA_UNUSED, unsigned int timestamp EINA_UNUSED, struct wl_surface *surface,
wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer)
+_ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device
EINA_UNUSED, unsigned int timestamp, struct wl_surface *surface, int x, int y,
struct wl_data_offer *offer)
{
- Ecore_Wl_Event_Dnd_Enter *event;
- Ecore_Wl_Input *input;
+ Ecore_Wl_Event_Dnd_Enter *ev;
Ecore_Wl_Window *win;
- char **p;
-
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
- if ((!(input = data)) || (!offer)) return;
+ Ecore_Wl_Input *input;
+ char **types;
+ int num = 0;
- if (!(input->drag_source = wl_data_offer_get_user_data(offer)))
- return;
+ if (!(input = data)) return;
- win = wl_surface_get_user_data(surface);
-// input->pointer_focus = win;
+ win = ecore_wl_window_surface_find(surface);
- p = wl_array_add(&input->drag_source->types, sizeof(*p));
- *p = NULL;
+ input->pointer_enter_serial = timestamp;
+ input->pointer_focus = win;
- if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Enter)))) return;
+ if (offer)
+ {
+ input->drag_source = wl_data_offer_get_user_data(offer);
- event->win = win->id;
- if (input->drag_source->input)
+ num = (input->drag_source->types.size / sizeof(char *));
+ types = input->drag_source->types.data;
+ }
+ else
{
- if (input->drag_source->input->keyboard_focus)
- event->source = input->drag_source->input->keyboard_focus->id;
+ input->drag_source = NULL;
+ types = NULL;
}
- event->position.x = wl_fixed_to_int(x);
- event->position.y = wl_fixed_to_int(y);
- event->num_types = input->drag_source->types.size;
- event->types = input->drag_source->types.data;
+ if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Enter)))) return;
+
+ if (win)
+ ev->win = win->id;
+
+ if (input->keyboard_focus)
+ ev->source = input->keyboard_focus->id;
+
+ ev->offer = offer;
+ ev->serial = timestamp;
+ ev->position.x = wl_fixed_to_int(x);
+ ev->position.y = wl_fixed_to_int(y);
+ ev->num_types = num;
+ ev->types = types;
- ecore_event_add(ECORE_WL_EVENT_DND_ENTER, event,
- _ecore_wl_dnd_cb_enter_free, NULL);
+ ecore_event_add(ECORE_WL_EVENT_DND_ENTER, ev, NULL, NULL);
}
void
_ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device EINA_UNUSED)
{
+ Ecore_Wl_Event_Dnd_Leave *ev;
Ecore_Wl_Input *input;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
if (!(input = data)) return;
- /* FIXME: NB: This MAY need to raise a wl_event_dnd_leave for the
- * source window */
- _ecore_wl_dnd_del(input->drag_source);
- input->drag_source = NULL;
+
+ if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Leave)))) return;
+
+ if (input->pointer_focus)
+ ev->win = input->pointer_focus->id;
+
+ if (input->keyboard_focus)
+ ev->source = input->keyboard_focus->id;
+
+ ecore_event_add(ECORE_WL_EVENT_DND_LEAVE, ev, NULL, NULL);
}
void
-_ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device
EINA_UNUSED, unsigned int timestamp EINA_UNUSED, wl_fixed_t x, wl_fixed_t y)
+_ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device
EINA_UNUSED, unsigned int timestamp EINA_UNUSED, int x, int y)
{
- Ecore_Wl_Event_Dnd_Position *event;
+ Ecore_Wl_Event_Dnd_Position *ev;
Ecore_Wl_Input *input;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
if (!(input = data)) return;
input->sx = wl_fixed_to_int(x);
input->sy = wl_fixed_to_int(y);
- if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return;
+ if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return;
- if (input->drag_source)
- {
- if (input->drag_source->input)
- {
- if (input->drag_source->input->pointer_focus)
- event->win = input->drag_source->input->pointer_focus->id;
- if (input->drag_source->input->keyboard_focus)
- event->source = input->drag_source->input->keyboard_focus->id;
- }
- }
+ if (input->pointer_focus)
+ ev->win = input->pointer_focus->id;
- event->position.x = input->sx;
- event->position.y = input->sy;
+ if (input->keyboard_focus)
+ ev->source = input->keyboard_focus->id;
- ecore_event_add(ECORE_WL_EVENT_DND_POSITION, event, NULL, NULL);
+ ev->position.x = input->sx;
+ ev->position.y = input->sy;
+
+ ecore_event_add(ECORE_WL_EVENT_DND_POSITION, ev, NULL, NULL);
}
void
_ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device EINA_UNUSED)
{
- Ecore_Wl_Event_Dnd_Drop *event;
+ Ecore_Wl_Event_Dnd_Drop *ev;
Ecore_Wl_Input *input;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
if (!(input = data)) return;
- if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Drop)))) return;
+ if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Drop)))) return;
if (input->drag_source)
{
- if (input->drag_source->input)
- {
- if (input->drag_source->input->pointer_focus)
- event->win = input->drag_source->input->pointer_focus->id;
- if (input->drag_source->input->keyboard_focus)
- event->source = input->drag_source->input->keyboard_focus->id;
- }
+ if (input->pointer_focus)
+ ev->win = input->pointer_focus->id;
+ if (input->keyboard_focus)
+ ev->source = input->keyboard_focus->id;
}
- event->position.x = input->sx;
- event->position.y = input->sy;
+ ev->position.x = input->sx;
+ ev->position.y = input->sy;
- ecore_event_add(ECORE_WL_EVENT_DND_DROP, event, NULL, NULL);
+ ecore_event_add(ECORE_WL_EVENT_DND_DROP, ev, NULL, NULL);
}
void
@@ -293,35 +507,30 @@ _ecore_wl_dnd_selection(void *data, struct wl_data_device
*data_device EINA_UNUS
{
Ecore_Wl_Input *input;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
if (!(input = data)) return;
+
if (input->selection_source) _ecore_wl_dnd_del(input->selection_source);
- input->selection_source = NULL;
+
if (offer)
{
- char **p;
+ char **t;
input->selection_source = wl_data_offer_get_user_data(offer);
- p = wl_array_add(&input->selection_source->types, sizeof(*p));
- *p = NULL;
+ t = wl_array_add(&input->selection_source->types, sizeof(*t));
+ *t = NULL;
}
+ else
+ input->selection_source = NULL;
}
void
_ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
-
if (!source) return;
source->refcount--;
if (source->refcount == 0)
{
- char **p;
-
- wl_data_offer_destroy(source->offer);
- for (p = source->types.data; *p; p++)
- free(*p);
+ wl_data_offer_destroy(source->data_offer);
wl_array_release(&source->types);
free(source);
}
@@ -329,47 +538,65 @@ _ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source)
/* local functions */
static void
-_ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer
EINA_UNUSED, const char *type)
+_ecore_wl_dnd_selection_data_receive(Ecore_Wl_Dnd_Source *source, const char
*type)
{
- Ecore_Wl_Dnd_Source *source;
- char **p;
+ int epoll_fd;
+ struct epoll_event *ep = NULL;
+ struct _dnd_task *task = NULL;
+ struct _dnd_read_ctx *read_ctx = NULL;
+ int p[2];
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ if (pipe2(p, O_CLOEXEC) == -1)
+ return;
- if (!(source = data)) return;
- p = wl_array_add(&source->types, sizeof(*p));
- *p = strdup(type);
-}
+ wl_data_offer_receive(source->data_offer, type, p[1]);
+ close(p[1]);
-static void
-_ecore_wl_dnd_cb_enter_free(void *data EINA_UNUSED, void *event)
-{
- Ecore_Wl_Event_Dnd_Enter *ev;
+ /* Due to http://trac.enlightenment.org/e/ticket/1208,
+ * use epoll and idle handler instead of ecore_main_fd_handler_add() */
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ ep = calloc(1, sizeof(struct epoll_event));
+ if (!ep) goto err;
- if (!(ev = event)) return;
- free(ev);
-}
+ task = calloc(1, sizeof(struct _dnd_task));
+ if (!task) goto err;
-static void
-_ecore_wl_dnd_cb_selection_data_ready_free(void *data EINA_UNUSED, void *event)
-{
- Ecore_Wl_Event_Selection_Data_Ready *ev;
+ read_ctx = calloc(1, sizeof(struct _dnd_read_ctx));
+ if (!read_ctx) goto err;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ epoll_fd = epoll_create1(0);
+ if (epoll_fd < 0) goto err;
- if (!(ev = event)) return;
+ task->data = source;
+ task->cb = _ecore_wl_dnd_selection_data_read;
+ ep->events = EPOLLIN;
+ ep->data.ptr = task;
- free(ev->data);
- free(ev);
+ if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, p[0], ep) < 0) goto err;
+
+ read_ctx->epoll_fd = epoll_fd;
+ read_ctx->ep = ep;
+
+ if (!ecore_idler_add(_ecore_wl_dnd_selection_cb_idle, read_ctx)) goto err;
+
+ source->refcount++;
+ source->fd = p[0];
+
+ return;
+
+err:
+ if (ep) free(ep);
+ if (task) free(task);
+ if (read_ctx) free(read_ctx);
+ close(p[0]);
+ return;
}
static Eina_Bool
-_ecore_wl_dnd_read_data(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
+_ecore_wl_dnd_selection_data_read(void *data, Ecore_Fd_Handler *fd_handler
EINA_UNUSED)
{
int len;
- char buffer[4096];
+ char buffer[PATH_MAX];
Ecore_Wl_Dnd_Source *source;
Ecore_Wl_Event_Selection_Data_Ready *event;
Eina_Bool ret;
@@ -402,13 +629,26 @@ _ecore_wl_dnd_read_data(void *data, Ecore_Fd_Handler
*fd_handler EINA_UNUSED)
}
ecore_event_add(ECORE_WL_EVENT_SELECTION_DATA_READY, event,
- _ecore_wl_dnd_cb_selection_data_ready_free, NULL);
+ _ecore_wl_dnd_selection_data_ready_cb_free, NULL);
+
return ret;
}
+static void
+_ecore_wl_dnd_selection_data_ready_cb_free(void *data EINA_UNUSED, void *event)
+{
+ Ecore_Wl_Event_Selection_Data_Ready *ev;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(ev = event)) return;
+
+ free(ev->data);
+ free(ev);
+}
static Eina_Bool
-_ecore_wl_dnd_idler_cb(void *data)
+_ecore_wl_dnd_selection_cb_idle(void *data)
{
struct _dnd_read_ctx *ctx;
struct _dnd_task *task;
@@ -430,56 +670,63 @@ _ecore_wl_dnd_idler_cb(void *data)
return ECORE_CALLBACK_RENEW;
}
-static void
-_ecore_wl_dnd_source_receive_data(Ecore_Wl_Dnd_Source *source, const char
*type)
+static void
+_ecore_wl_dnd_source_cb_target(void *data, struct wl_data_source *source
EINA_UNUSED, const char *mime_type EINA_UNUSED)
{
- int epoll_fd;
- struct epoll_event *ep = NULL;
- struct _dnd_task *task = NULL;
- struct _dnd_read_ctx *read_ctx = NULL;
- int p[2];
+ Ecore_Wl_Input *input;
- if (pipe2(p, O_CLOEXEC) == -1)
- return;
+ if (!(input = data)) return;
- wl_data_offer_receive(source->offer, type, p[1]);
- close(p[1]);
+ printf("Dnd Source Target\n");
+}
- /* Due to http://trac.enlightenment.org/e/ticket/1208,
- * use epoll and idle handler instead of ecore_main_fd_handler_add() */
+static void
+_ecore_wl_dnd_source_cb_send(void *data, struct wl_data_source *source
EINA_UNUSED, const char *mime_type, int32_t fd)
+{
+ Ecore_Wl_Event_Data_Source_Send *event;
+ Ecore_Wl_Input *input;
- ep = calloc(1, sizeof(struct epoll_event));
- if (!ep) goto err;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
- task = calloc(1, sizeof(struct _dnd_task));
- if (!task) goto err;
+ if (!(input = data)) return;
- read_ctx = calloc(1, sizeof(struct _dnd_read_ctx));
- if (!read_ctx) goto err;
+ if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Data_Source_Send)))) return;
- epoll_fd = epoll_create1(0);
- if (epoll_fd < 0) goto err;
+ event->type = strdup(mime_type);
+ event->fd = fd;
- task->data = source;
- task->cb = _ecore_wl_dnd_read_data;
- ep->events = EPOLLIN;
- ep->data.ptr = task;
+ ecore_event_add(ECORE_WL_EVENT_DATA_SOURCE_SEND, event,
+ _ecore_wl_dnd_source_cb_send_free, NULL);
+}
- if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, p[0], ep) < 0) goto err;
+static void
+_ecore_wl_dnd_source_cb_send_free(void *data EINA_UNUSED, void *event)
+{
+ Ecore_Wl_Event_Data_Source_Send *ev;
- read_ctx->epoll_fd = epoll_fd;
- read_ctx->ep = ep;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
- if (!ecore_idler_add(_ecore_wl_dnd_idler_cb, read_ctx)) goto err;
+ if (!(ev = event)) return;
- source->refcount++;
- source->fd = p[0];
- return;
+ free(ev->type);
+ free(ev);
+}
-err:
- if (ep) free(ep);
- if (task) free(task);
- if (read_ctx) free(read_ctx);
- close(p[0]);
- return;
+static void
+_ecore_wl_dnd_source_cb_cancelled(void *data EINA_UNUSED, struct
wl_data_source *source)
+{
+ /* FIXME: Raise an Ecore_Wl_Event here */
+ wl_data_source_destroy(source);
+}
+
+static void
+_ecore_wl_dnd_offer_cb_offer(void *data, struct wl_data_offer *data_offer
EINA_UNUSED, const char *type)
+{
+ Ecore_Wl_Dnd_Source *source;
+ char **t;
+
+ if (!(source = data)) return;
+
+ t = wl_array_add(&source->types, sizeof(*t));
+ *t = strdup(type);
}
--
------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may