From c3006783916d893ba5dc80115cbeaf0d0cc0f52f Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 6 Jul 2016 14:48:46 +0200 Subject: [PATCH] ecore_wl2: buffer reading of the data Otherwise callbacks can go out even if the selection data is not ready to read. --- src/lib/ecore_wl2/Ecore_Wl2.h | 1 - src/lib/ecore_wl2/ecore_wl2_dnd.c | 37 +++++---- src/lib/ecore_wl2/ecore_wl2_private.h | 2 + src/lib/elementary/elm_cnp.c | 115 ++++++++++++-------------- 4 files changed, 73 insertions(+), 82 deletions(-) diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index fef28a6604..615d7285cf 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -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; diff --git a/src/lib/ecore_wl2/ecore_wl2_dnd.c b/src/lib/ecore_wl2/ecore_wl2_dnd.c index d093d0b0fe..2c63ff24fc 100644 --- a/src/lib/ecore_wl2/ecore_wl2_dnd.c +++ b/src/lib/ecore_wl2/ecore_wl2_dnd.c @@ -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; + else + { + source->len += len; + source->read_data = realloc(source->read_data, source->len); + } + + memcpy(((char*)source->read_data) + old_len, buffer, len); + return ECORE_CALLBACK_RENEW; } - - ecore_event_add(ECORE_WL2_EVENT_SELECTION_DATA_READY, event, - _selection_data_ready_cb_free, NULL); - - return ret; } static void diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index 1cfae47466..1d27f60257 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -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; diff --git a/src/lib/elementary/elm_cnp.c b/src/lib/elementary/elm_cnp.c index 23d9753ab8..1a5ce93e4e 100644 --- a/src/lib/elementary/elm_cnp.c +++ b/src/lib/elementary/elm_cnp.c @@ -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) { - 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); - - goto end; - } + 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;