ecore_wl2: buffer reading of the data
authorMarcel Hollerbach <marcel-hollerbach@t-online.de>
Wed, 6 Jul 2016 12:48:46 +0000 (14:48 +0200)
committerMarcel Hollerbach <marcel-hollerbach@t-online.de>
Mon, 11 Jul 2016 09:02:52 +0000 (11:02 +0200)
Otherwise callbacks can go out even if the selection data is not ready
to read.

src/lib/ecore_wl2/Ecore_Wl2.h
src/lib/ecore_wl2/ecore_wl2_dnd.c
src/lib/ecore_wl2/ecore_wl2_private.h
src/lib/elementary/elm_cnp.c

index fef28a6..615d728 100644 (file)
@@ -146,7 +146,6 @@ typedef struct _Ecore_Wl2_Event_Selection_Data_Ready
 {
    char *data;
    int len;
-   Eina_Bool done;
    Ecore_Wl2_Selection_Type sel_type;
 } Ecore_Wl2_Event_Selection_Data_Ready;
 
index d093d0b..2c63ff2 100644 (file)
@@ -227,7 +227,6 @@ _selection_data_read(void *data, Ecore_Fd_Handler *fdh)
    char buffer[PATH_MAX];
    Ecore_Wl2_Dnd_Source *source = data;
    Ecore_Wl2_Event_Selection_Data_Ready *event;
-   Eina_Bool ret;
 
    fd = ecore_main_fd_handler_fd_get(fdh);
    if (fd >= 0)
@@ -254,29 +253,31 @@ _selection_data_read(void *data, Ecore_Fd_Handler *fdh)
         ecore_main_fd_handler_del(source->fdh);
         source->fdh = NULL;
 
-        event->done = EINA_TRUE;
-        event->data = NULL;
-        event->len = 0;
-        ret = ECORE_CALLBACK_CANCEL;
+        event->data = source->read_data;
+        event->len = source->len;
+        ecore_event_add(ECORE_WL2_EVENT_SELECTION_DATA_READY, event,
+                        _selection_data_ready_cb_free, NULL);
+
+        return ECORE_CALLBACK_CANCEL;
      }
    else
      {
-        event->data = malloc(len);
-        if (!event->data)
+        int old_len = source->len;
+
+        if (!source->read_data)
           {
-             free(event);
-             return ECORE_CALLBACK_CANCEL;
+             source->read_data = malloc(len);
+             source->len = len;
           }
-        memcpy(event->data, buffer, len);
-        event->len = len;
-        event->done = EINA_FALSE;
-        ret = ECORE_CALLBACK_RENEW;
-     }
-
-   ecore_event_add(ECORE_WL2_EVENT_SELECTION_DATA_READY, event,
-                   _selection_data_ready_cb_free, NULL);
+        else
+          {
+             source->len += len;
+               source->read_data = realloc(source->read_data, source->len);
+            }
 
-   return ret;
+        memcpy(((char*)source->read_data) + old_len, buffer, len);
+        return ECORE_CALLBACK_RENEW;
+     }
 }
 
 static void
index 1cfae47..1d27f60 100644 (file)
@@ -195,6 +195,8 @@ typedef struct _Ecore_Wl2_Dnd_Source
    uint32_t source_actions;
    Ecore_Wl2_Selection_Type sel_type;
    Eina_Bool active_read;
+   void *read_data;
+   unsigned int len;
 } Ecore_Wl2_Dnd_Source;
 
 
index 23d9753..1a5ce93 100644 (file)
@@ -3121,74 +3121,68 @@ _wl_selection_receive(void *udata, int type EINA_UNUSED, void *event)
 
    if (sel->requestwidget)
      {
-        if (!ev->done)
+        if (sel->seltype == ELM_SEL_TYPE_XDND)
           {
-             if (sel->seltype == ELM_SEL_TYPE_XDND)
-               {
-                  Elm_Selection_Data sdata;
-                  Eina_List *l;
-                  Dropable *dropable;
-
-                  EINA_LIST_FOREACH(drops, l, dropable)
-                    {
-                       if (dropable->obj == sel->requestwidget) break;
-                       dropable = NULL;
-                    }
-
-                  if (dropable)
-                    {
-                       Dropable_Cbs *cbs;
-
-                       sdata.x = savedtypes.x;
-                       sdata.y = savedtypes.y;
-                       sdata.format = ELM_SEL_FORMAT_TEXT;
-                       sdata.data = ev->data;
-                       sdata.len = ev->len;
-                       sdata.action = sel->action;
-
-                       EINA_INLIST_FOREACH(dropable->cbs_list, cbs)
-                         if (cbs->dropcb)
-                           cbs->dropcb(cbs->dropdata, dropable->obj, &sdata);
+             Elm_Selection_Data sdata;
+             Eina_List *l;
+             Dropable *dropable;
 
-                       goto end;
-                    }
+             EINA_LIST_FOREACH(drops, l, dropable)
+               {
+                  if (dropable->obj == sel->requestwidget) break;
+                  dropable = NULL;
                }
 
-             if (sel->datacb)
+             if (dropable)
                {
-                  Elm_Selection_Data sdata;
+                  Dropable_Cbs *cbs;
 
-                  sdata.x = sdata.y = 0;
+                  sdata.x = savedtypes.x;
+                  sdata.y = savedtypes.y;
                   sdata.format = ELM_SEL_FORMAT_TEXT;
                   sdata.data = ev->data;
                   sdata.len = ev->len;
                   sdata.action = sel->action;
-                  sel->datacb(sel->udata,
-                              sel->requestwidget,
-                              &sdata);
-               }
-             else
-               {
-                  char *stripstr, *mkupstr;
-
-                  stripstr = malloc(ev->len + 1);
-                  if (!stripstr) goto end;
-                  strncpy(stripstr, (char *)ev->data, ev->len);
-                  stripstr[ev->len] = '\0';
-                  mkupstr = _elm_util_text_to_mkup((const char *)stripstr);
-                  /* TODO BUG: should never NEVER assume it's an elm_entry! */
-                  _elm_entry_entry_paste(sel->requestwidget, mkupstr);
-                  free(stripstr);
-                  free(mkupstr);
+
+                  EINA_INLIST_FOREACH(dropable->cbs_list, cbs)
+                    if (cbs->dropcb)
+                      cbs->dropcb(cbs->dropdata, dropable->obj, &sdata);
+
+                  goto end;
                }
           }
+
+        if (sel->datacb)
+          {
+             Elm_Selection_Data sdata;
+
+             sdata.x = sdata.y = 0;
+             sdata.format = ELM_SEL_FORMAT_TEXT;
+             sdata.data = ev->data;
+             sdata.len = ev->len;
+             sdata.action = sel->action;
+             sel->datacb(sel->udata,
+                          sel->requestwidget,
+                          &sdata);
+          }
         else
           {
-             evas_object_event_callback_del_full(sel->requestwidget,
-                                                 EVAS_CALLBACK_DEL,
-                                                 _wl_sel_obj_del2, sel);
-             sel->requestwidget = NULL;
+             char *stripstr, *mkupstr;
+
+             stripstr = malloc(ev->len + 1);
+             if (!stripstr) goto end;
+             strncpy(stripstr, (char *)ev->data, ev->len);
+             stripstr[ev->len] = '\0';
+             mkupstr = _elm_util_text_to_mkup((const char *)stripstr);
+             /* TODO BUG: should never NEVER assume it's an elm_entry! */
+             _elm_entry_entry_paste(sel->requestwidget, mkupstr);
+             free(stripstr);
+             free(mkupstr);
           }
+        evas_object_event_callback_del_full(sel->requestwidget,
+                                            EVAS_CALLBACK_DEL,
+                                            _wl_sel_obj_del2, sel);
+        sel->requestwidget = NULL;
      }
 
 end:
@@ -3689,17 +3683,12 @@ _wl_dnd_receive(void *data, int type EINA_UNUSED, void *event)
 
    if (sel->requestwidget)
      {
-        if (!ev->done)
-          {
-             _wl_dropable_data_handle(sel, ev);
-          }
-        else
-          {
-             evas_object_event_callback_del_full(sel->requestwidget,
-                                                 EVAS_CALLBACK_DEL,
-                                                 _wl_sel_obj_del2, sel);
-             sel->requestwidget = NULL;
-          }
+           _wl_dropable_data_handle(sel, ev);
+           evas_object_event_callback_del_full(sel->requestwidget,
+                                               EVAS_CALLBACK_DEL,
+                                               _wl_sel_obj_del2, sel);
+           sel->requestwidget = NULL;
+
      }
 
    return ECORE_CALLBACK_PASS_ON;