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

Reply via email to