diff options
author | Marcel Hollerbach <marcel-hollerbach@t-online.de> | 2016-09-22 09:13:48 +0200 |
---|---|---|
committer | Marcel Hollerbach <marcel-hollerbach@t-online.de> | 2016-09-23 11:15:14 +0200 |
commit | 5884bba09694626a04c9de56229353fd76d3d945 (patch) | |
tree | d8695534031b515d56229212de09fe3348d00649 | |
parent | 7d6fd1052353c113340fd9f7891cf9d301bf1e73 (diff) | |
download | efl-5884bba09694626a04c9de56229353fd76d3d945.tar.gz |
ecore_wl2: introduce offer api
This commits adds api to deal with wayland offers.
It also ports elm_cnp to use the new api.
The selection_get and dnd_drag_get calls are replaced by simply receive
data from the offer.
The Offer object is now also emitted in every Enter,Motion,Drop and
Leave event, so a potential user can prefetch data and display it.
To finish a dnd operation positiv, the user has to call the finish call
before the offer is destroyed
-rw-r--r-- | src/lib/ecore_wl2/Ecore_Wl2.h | 126 | ||||
-rw-r--r-- | src/lib/ecore_wl2/ecore_wl2.c | 9 | ||||
-rw-r--r-- | src/lib/ecore_wl2/ecore_wl2_dnd.c | 576 | ||||
-rw-r--r-- | src/lib/ecore_wl2/ecore_wl2_input.c | 4 | ||||
-rw-r--r-- | src/lib/ecore_wl2/ecore_wl2_private.h | 7 | ||||
-rw-r--r-- | src/lib/elementary/elm_cnp.c | 295 |
6 files changed, 597 insertions, 420 deletions
diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index 29f48258cc..34d6fff5b5 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -43,7 +43,7 @@ typedef struct _Ecore_Wl2_Seat Ecore_Wl2_Seat; typedef struct _Ecore_Wl2_Pointer Ecore_Wl2_Pointer; typedef struct _Ecore_Wl2_Keyboard Ecore_Wl2_Keyboard; typedef struct _Ecore_Wl2_Touch Ecore_Wl2_Touch; - +typedef struct _Ecore_Wl2_Offer Ecore_Wl2_Offer; /* matches protocol values */ typedef enum { @@ -51,6 +51,7 @@ typedef enum ECORE_WL2_DRAG_ACTION_COPY = 1, ECORE_WL2_DRAG_ACTION_MOVE = 2, ECORE_WL2_DRAG_ACTION_ASK = 4, + ECORE_WL2_DRAG_ACTION_LAST = 5, } Ecore_Wl2_Drag_Action; struct _Ecore_Wl2_Event_Connection @@ -87,20 +88,21 @@ typedef struct _Ecore_Wl2_Event_Focus_Out typedef struct _Ecore_Wl2_Event_Dnd_Enter { - unsigned int win, source, serial; - char **types; - int num_types, x, y; - struct wl_data_offer *offer; + unsigned int win, source; + Ecore_Wl2_Offer *offer; + int x, y; } Ecore_Wl2_Event_Dnd_Enter; typedef struct _Ecore_Wl2_Event_Dnd_Leave { unsigned int win, source; + Ecore_Wl2_Offer *offer; } Ecore_Wl2_Event_Dnd_Leave; typedef struct _Ecore_Wl2_Event_Dnd_Motion { - unsigned int win, source, serial; + unsigned int win, source; + Ecore_Wl2_Offer *offer; int x, y; } Ecore_Wl2_Event_Dnd_Motion; @@ -108,6 +110,7 @@ typedef struct _Ecore_Wl2_Event_Dnd_Drop { unsigned int win, source; int x, y; + Ecore_Wl2_Offer *offer; } Ecore_Wl2_Event_Dnd_Drop; typedef struct _Ecore_Wl2_Event_Dnd_End @@ -142,13 +145,6 @@ typedef enum ECORE_WL2_SELECTION_DND } Ecore_Wl2_Selection_Type; -typedef struct _Ecore_Wl2_Event_Selection_Data_Ready -{ - char *data; - int len; - Ecore_Wl2_Selection_Type sel_type; -} Ecore_Wl2_Event_Selection_Data_Ready; - typedef enum { ECORE_WL2_WINDOW_STATE_NONE = 0, @@ -168,6 +164,12 @@ typedef struct _Ecore_Wl2_Event_Sync_Done Ecore_Wl2_Display *display; } Ecore_Wl2_Event_Sync_Done; +typedef struct _Ecore_Wl2_Event_Offer_Data_Ready{ + Ecore_Wl2_Offer *offer; + char *data; + int len; +} Ecore_Wl2_Event_Offer_Data_Ready; + typedef enum _Ecore_Wl2_Window_Type { ECORE_WL2_WINDOW_TYPE_NONE, @@ -192,16 +194,14 @@ EAPI extern int ECORE_WL2_EVENT_DND_LEAVE; /** @since 1.17 */ EAPI extern int ECORE_WL2_EVENT_DND_MOTION; /** @since 1.17 */ EAPI extern int ECORE_WL2_EVENT_DND_DROP; /** @since 1.17 */ EAPI extern int ECORE_WL2_EVENT_DND_END; /** @since 1.17 */ -EAPI extern int ECORE_WL2_EVENT_DND_DATA_READY; /** @since 1.18 */ EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_END; /** @since 1.18 */ EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_DROP; /** @since 1.18 */ EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_ACTION; /** @since 1.18 */ EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_TARGET; /** @since 1.17 */ EAPI extern int ECORE_WL2_EVENT_DATA_SOURCE_SEND; /** @since 1.17 */ -EAPI extern int ECORE_WL2_EVENT_CNP_DATA_READY; /** @since 1.18 */ EAPI extern int ECORE_WL2_EVENT_WINDOW_CONFIGURE; /** @since 1.17 */ EAPI extern int ECORE_WL2_EVENT_SYNC_DONE; /** @since 1.17 */ - +EAPI extern int ECORE_WL2_EVENT_OFFER_DATA_READY; /** @since 1.19 */ /** * @file * @brief Ecore functions for dealing with the Wayland display protocol @@ -869,15 +869,11 @@ EAPI void ecore_wl2_dnd_drag_start(Ecore_Wl2_Input *input, Ecore_Wl2_Window *win /* TODO: doxy */ /** @since 1.17 */ -EAPI Eina_Bool ecore_wl2_dnd_drag_get(Ecore_Wl2_Input *input, const char *type); - -/* TODO: doxy */ -/** @since 1.17 */ EAPI void ecore_wl2_dnd_drag_end(Ecore_Wl2_Input *input); /* TODO: doxy */ /** @since 1.17 */ -EAPI Eina_Bool ecore_wl2_dnd_selection_owner_has(Ecore_Wl2_Input *input); +EAPI Ecore_Wl2_Offer* ecore_wl2_dnd_selection_get(Ecore_Wl2_Input *input); /* TODO: doxy */ /** @since 1.17 */ @@ -885,10 +881,6 @@ EAPI Eina_Bool ecore_wl2_dnd_selection_set(Ecore_Wl2_Input *input, const char ** /* TODO: doxy */ /** @since 1.17 */ -EAPI Eina_Bool ecore_wl2_dnd_selection_get(Ecore_Wl2_Input *input, const char *type); - -/* TODO: doxy */ -/** @since 1.17 */ EAPI Eina_Bool ecore_wl2_dnd_selection_clear(Ecore_Wl2_Input *input); /** @@ -1111,6 +1103,90 @@ EAPI Ecore_Wl2_Display *ecore_wl2_window_display_get(const Ecore_Wl2_Window *win /* # ifdef __cplusplus */ /* } */ /* # endif */ +/** + * Get the actions available from the data source + * + * @param offer Offer object to use + * + * @return or´ed values from Ecore_Wl2_Drag_Action which are describing the available actions + * @since 1.19 + */ +EAPI Ecore_Wl2_Drag_Action ecore_wl2_offer_actions_get(Ecore_Wl2_Offer *offer); + +/** + * Set the actions which are supported by you + * + * @param offer Offer object to use + * @param actions A or´ed value of mutliple Ecore_Wl2_Drag_Action values + * @param action the preffered action out of the actions + * + * @since 1.19 + */ +EAPI void ecore_wl2_offer_actions_set(Ecore_Wl2_Offer *offer, Ecore_Wl2_Drag_Action actions, Ecore_Wl2_Drag_Action action); + +/** + * Get action which is set by either the data source or in the last call of actions_set + * + * @param offer Offer object to use + * + * @return the prefered action + * + * @since 1.19 + */ +EAPI Ecore_Wl2_Drag_Action ecore_wl2_offer_action_get(Ecore_Wl2_Offer *offer); + +/** + * Get the mime types which are given by the source + * + * @param offer the offer to query + * + * @return a eina array of strdup´ed strings, this array must NOT be changed or freed + */ +EAPI Eina_Array* ecore_wl2_offer_mimes_get(Ecore_Wl2_Offer *offer); + +/** + * Set mimetypes you are accepting under this offer + * + * @param offer the offer to use + * + * @since 1.19 + */ +EAPI void ecore_wl2_offer_mimes_set(Ecore_Wl2_Offer *offer, Eina_Array *mimes); + +/** + * Request the data from this offer. + * The event ECORE_WL2_EVENT_OFFER_DATA_READY is called when the data is available. + * There offer will be not destroyed as long as requested data is not emitted by the event. + * + * @param offer the offer to use + * @param mime the mimetype to receive + * + * @since 1.19 + */ +EAPI Eina_Bool ecore_wl2_offer_receive(Ecore_Wl2_Offer *offer, char *mime); + +/** + * Check if the given offer supports the given mimetype + * + * @param offer the offer to use + * @param mime the mimetype to check + * + * @return Returns true if the mimetype is supported by this offer, false if not + * + * @since 1.19 + */ +EAPI Eina_Bool ecore_wl2_offer_supprts_mime(Ecore_Wl2_Offer *offer, const char *mime); + +/** + * Mark this offer as finished + * This will call the dnd_finished event on the source of the sender. + * + * @param offer the offer to use + * + * @since 1.19 + */ +EAPI void ecore_wl2_offer_finish(Ecore_Wl2_Offer *offer); + # endif diff --git a/src/lib/ecore_wl2/ecore_wl2.c b/src/lib/ecore_wl2/ecore_wl2.c index 0f8850ffa0..f62dacaa42 100644 --- a/src/lib/ecore_wl2/ecore_wl2.c +++ b/src/lib/ecore_wl2/ecore_wl2.c @@ -28,10 +28,9 @@ EAPI int ECORE_WL2_EVENT_DATA_SOURCE_DROP = 0; EAPI int ECORE_WL2_EVENT_DATA_SOURCE_ACTION = 0; EAPI int ECORE_WL2_EVENT_DATA_SOURCE_TARGET = 0; EAPI int ECORE_WL2_EVENT_DATA_SOURCE_SEND = 0; -EAPI int ECORE_WL2_EVENT_CNP_DATA_READY = 0; -EAPI int ECORE_WL2_EVENT_DND_DATA_READY = 0; EAPI int ECORE_WL2_EVENT_WINDOW_CONFIGURE = 0; EAPI int ECORE_WL2_EVENT_SYNC_DONE = 0; +EAPI int ECORE_WL2_EVENT_OFFER_DATA_READY = 0; EAPI int _ecore_wl2_event_window_www = -1; EAPI int _ecore_wl2_event_window_www_drag = -1; @@ -87,10 +86,9 @@ ecore_wl2_init(void) ECORE_WL2_EVENT_DATA_SOURCE_ACTION = ecore_event_type_new(); ECORE_WL2_EVENT_DATA_SOURCE_TARGET = ecore_event_type_new(); ECORE_WL2_EVENT_DATA_SOURCE_SEND = ecore_event_type_new(); - ECORE_WL2_EVENT_CNP_DATA_READY = ecore_event_type_new(); - ECORE_WL2_EVENT_DND_DATA_READY = ecore_event_type_new(); ECORE_WL2_EVENT_WINDOW_CONFIGURE = ecore_event_type_new(); ECORE_WL2_EVENT_SYNC_DONE = ecore_event_type_new(); + ECORE_WL2_EVENT_OFFER_DATA_READY = ecore_event_type_new(); _ecore_wl2_event_window_www = ecore_event_type_new(); _ecore_wl2_event_window_www_drag = ecore_event_type_new(); } @@ -138,10 +136,9 @@ ecore_wl2_shutdown(void) ECORE_WL2_EVENT_DATA_SOURCE_ACTION = 0; ECORE_WL2_EVENT_DATA_SOURCE_TARGET = 0; ECORE_WL2_EVENT_DATA_SOURCE_SEND = 0; - ECORE_WL2_EVENT_DND_DATA_READY = 0; - ECORE_WL2_EVENT_CNP_DATA_READY = 0; ECORE_WL2_EVENT_WINDOW_CONFIGURE = 0; ECORE_WL2_EVENT_SYNC_DONE = 0; + ECORE_WL2_EVENT_OFFER_DATA_READY = 0; /* shutdown Ecore_Event */ ecore_event_shutdown(); diff --git a/src/lib/ecore_wl2/ecore_wl2_dnd.c b/src/lib/ecore_wl2/ecore_wl2_dnd.c index 74299f3295..31669a73e7 100644 --- a/src/lib/ecore_wl2/ecore_wl2_dnd.c +++ b/src/lib/ecore_wl2/ecore_wl2_dnd.c @@ -43,37 +43,16 @@ struct _dnd_read_ctx struct epoll_event *ep; }; -static void -data_offer_offer(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, const char *type) +struct _Ecore_Wl2_Offer { - Ecore_Wl2_Dnd_Source *source = data; - char **p; - - p = wl_array_add(&source->types, sizeof *p); - *p = strdup(type); -} - -static void -data_offer_source_actions(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, uint32_t source_actions) -{ - Ecore_Wl2_Dnd_Source *source = data; - - source->source_actions = source_actions; -} - -static void -data_offer_action(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, uint32_t dnd_action) -{ - Ecore_Wl2_Dnd_Source *source = data; - - source->dnd_action = dnd_action; -} - -static const struct wl_data_offer_listener _offer_listener = -{ - data_offer_offer, - data_offer_source_actions, - data_offer_action + Ecore_Wl2_Input *input; + struct wl_data_offer *offer; + Eina_Array *mimetypes; + Ecore_Wl2_Drag_Action actions; + Ecore_Wl2_Drag_Action action; + uint32_t serial; + Ecore_Fd_Handler *read; + int ref; }; static void @@ -207,118 +186,14 @@ static const struct wl_data_source_listener _source_listener = }; static void -_selection_data_ready_cb_free(void *data EINA_UNUSED, void *event) -{ - Ecore_Wl2_Event_Selection_Data_Ready *ev; - - ev = event; - if (!ev) return; - - free(ev->data); - free(ev); -} - -static Eina_Bool -_selection_data_read(void *data, Ecore_Fd_Handler *fdh) -{ - int len = 0, fd; - char buffer[PATH_MAX]; - Ecore_Wl2_Dnd_Source *source = data; - Ecore_Wl2_Event_Selection_Data_Ready *event; - - fd = ecore_main_fd_handler_fd_get(fdh); - if (fd >= 0) - len = read(fd, buffer, sizeof buffer); - else - return ECORE_CALLBACK_RENEW; - - event = calloc(1, sizeof(Ecore_Wl2_Event_Selection_Data_Ready)); - if (!event) return ECORE_CALLBACK_CANCEL; - - event->sel_type = source->sel_type; - if (len <= 0) - { - if (source->input->drag.source) - { - if (source->input->display->wl.data_device_manager_version >= - WL_DATA_OFFER_FINISH_SINCE_VERSION) - { - wl_data_offer_finish(source->offer); - } - wl_data_offer_destroy(source->offer); - source->offer = NULL; - } - - fd = ecore_main_fd_handler_fd_get(source->fdh); - if (fd >= 0) close(fd); - ecore_main_fd_handler_del(source->fdh); - source->fdh = NULL; - - event->data = source->read_data; - source->read_data = NULL; - event->len = source->len; - source->len = 0; - if (source->input->drag.source) - ecore_event_add(ECORE_WL2_EVENT_DND_DATA_READY, event, - _selection_data_ready_cb_free, NULL); - else - ecore_event_add(ECORE_WL2_EVENT_CNP_DATA_READY, event, - _selection_data_ready_cb_free, NULL); - - return ECORE_CALLBACK_CANCEL; - } - else - { - int old_len = source->len; - - if (!source->read_data) - { - source->read_data = malloc(len); - source->len = len; - } - else - { - source->len += len; - source->read_data = realloc(source->read_data, source->len); - } - - memcpy(((char*)source->read_data) + old_len, buffer, len); - free(event); - return ECORE_CALLBACK_RENEW; - } -} - -static void -_selection_data_receive(Ecore_Wl2_Dnd_Source *source, const char *type) +_unset_serial(void *user_data, void *event) { - int p[2]; - - source->active_read = EINA_TRUE; - - if (pipe2(p, O_CLOEXEC) == -1) - return; - - wl_data_offer_receive(source->offer, type, p[1]); - close(p[1]); - - source->fdh = - ecore_main_fd_handler_file_add(p[0], ECORE_FD_READ | ECORE_FD_ERROR, - _selection_data_read, source, NULL, NULL); -} + Ecore_Wl2_Offer *offer = user_data; -void -_ecore_wl2_dnd_add(Ecore_Wl2_Input *input, struct wl_data_offer *offer) -{ - Ecore_Wl2_Dnd_Source *source; - - source = calloc(1, sizeof(Ecore_Wl2_Dnd_Source)); - if (!source) return; - - wl_array_init(&source->types); - source->input = input; - source->offer = offer; + if (offer) + offer->serial = 0; - wl_data_offer_add_listener(source->offer, &_offer_listener, source); + free(event); } void @@ -326,32 +201,36 @@ _ecore_wl2_dnd_enter(Ecore_Wl2_Input *input, struct wl_data_offer *offer, struct { Ecore_Wl2_Window *window; Ecore_Wl2_Event_Dnd_Enter *ev; - char **types; - int num = 0; window = _ecore_wl2_display_window_surface_find(input->display, surface); if (!window) return; if (offer) { - input->drag.source = wl_data_offer_get_user_data(offer); - input->drag.source->dnd_action = - WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; - num = (input->drag.source->types.size / sizeof(char *)); - types = input->drag.source->types.data; + input->drag = wl_data_offer_get_user_data(offer); + + if (!input->drag) + { + ERR("Userdata of offer not found"); + goto emit; + } + + input->drag->serial = serial; + if (input->display->wl.data_device_manager_version >= WL_DATA_OFFER_SET_ACTIONS_SINCE_VERSION) - wl_data_offer_set_actions(offer, - WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | - WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE, - WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE); + { + ecore_wl2_offer_actions_set(input->drag, + ECORE_WL2_DRAG_ACTION_MOVE | ECORE_WL2_DRAG_ACTION_COPY, + ECORE_WL2_DRAG_ACTION_MOVE); + } } else { - input->drag.source = NULL; - types = NULL; + input->drag = NULL; } +emit: ev = calloc(1, sizeof(Ecore_Wl2_Event_Dnd_Enter)); if (!ev) return; @@ -364,27 +243,18 @@ _ecore_wl2_dnd_enter(Ecore_Wl2_Input *input, struct wl_data_offer *offer, struct ev->x = x; ev->y = y; - ev->offer = offer; - ev->serial = serial; - ev->num_types = num; - ev->types = types; + ev->offer = input->drag; - ecore_event_add(ECORE_WL2_EVENT_DND_ENTER, ev, NULL, NULL); + ecore_event_add(ECORE_WL2_EVENT_DND_ENTER, ev, _unset_serial, input->drag); } static void _delay_offer_destroy(void *user_data, void *event) { - Ecore_Wl2_Dnd_Source *source; + Ecore_Wl2_Offer *offer = user_data; - source = user_data; - - if (source && source->offer - && !source->active_read) - { - wl_data_offer_destroy(source->offer); - source->offer = NULL; - } + if (offer) + _ecore_wl2_offer_unref(offer); free(event); } @@ -406,7 +276,11 @@ _ecore_wl2_dnd_leave(Ecore_Wl2_Input *input) if (!ev->win) ev->win = ev->source; - ecore_event_add(ECORE_WL2_EVENT_DND_LEAVE, ev, _delay_offer_destroy, input->drag.source); + ev->offer = input->drag; + ev->offer->ref++; + + ecore_event_add(ECORE_WL2_EVENT_DND_LEAVE, ev, _delay_offer_destroy, ev->offer); + input->drag = NULL; } void @@ -420,6 +294,8 @@ _ecore_wl2_dnd_motion(Ecore_Wl2_Input *input, int x, int y, uint32_t serial) ev = calloc(1, sizeof(Ecore_Wl2_Event_Dnd_Motion)); if (!ev) return; + input->drag->serial = serial; + if (input->focus.pointer) ev->win = input->focus.pointer->id; else if (input->focus.prev_pointer) @@ -431,9 +307,9 @@ _ecore_wl2_dnd_motion(Ecore_Wl2_Input *input, int x, int y, uint32_t serial) ev->x = x; ev->y = y; - ev->serial = serial; + ev->offer = input->drag; - ecore_event_add(ECORE_WL2_EVENT_DND_MOTION, ev, NULL, NULL); + ecore_event_add(ECORE_WL2_EVENT_DND_MOTION, ev, _unset_serial, input->drag); } void @@ -444,38 +320,30 @@ _ecore_wl2_dnd_drop(Ecore_Wl2_Input *input) ev = calloc(1, sizeof(Ecore_Wl2_Event_Dnd_Drop)); if (!ev) return; - if (input->drag.source) - { - if (input->focus.pointer) - ev->win = input->focus.pointer->id; - else if (input->focus.prev_pointer) - ev->win = input->focus.prev_pointer->id; - if (input->focus.keyboard) - ev->source = input->focus.keyboard->id; - - if (!ev->win) ev->win = ev->source; - } + if (input->focus.pointer) + ev->win = input->focus.pointer->id; + else if (input->focus.prev_pointer) + ev->win = input->focus.prev_pointer->id; + if (input->focus.keyboard) + ev->source = input->focus.keyboard->id; + + if (!ev->win) ev->win = ev->source; ev->x = input->pointer.sx; ev->y = input->pointer.sy; + ev->offer = input->drag; - ecore_event_add(ECORE_WL2_EVENT_DND_DROP, ev, _delay_offer_destroy, input->drag.source); + ecore_event_add(ECORE_WL2_EVENT_DND_DROP, ev, NULL, NULL); } void _ecore_wl2_dnd_selection(Ecore_Wl2_Input *input, struct wl_data_offer *offer) { - if (input->selection.source) _ecore_wl2_dnd_del(input->selection.source); - input->selection.source = NULL; + if (input->selection) _ecore_wl2_offer_unref(input->selection); + input->selection = NULL; if (offer) - { - char **t; - - input->selection.source = wl_data_offer_get_user_data(offer); - t = wl_array_add(&input->selection.source->types, sizeof(*t)); - *t = NULL; - } + input->selection = wl_data_offer_get_user_data(offer); } void @@ -571,25 +439,6 @@ ecore_wl2_dnd_drag_start(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, Ecore } } -EAPI Eina_Bool -ecore_wl2_dnd_drag_get(Ecore_Wl2_Input *input, const char *type) -{ - char **t; - - EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(input->drag.source, EINA_FALSE); - - wl_array_for_each(t, &input->drag.source->types) - if (!strcmp(type, *t)) break; - - if (!*t) return EINA_FALSE; - - input->drag.source->sel_type = ECORE_WL2_SELECTION_DND; - _selection_data_receive(input->drag.source, type); - - return EINA_TRUE; -} - EAPI void ecore_wl2_dnd_drag_end(Ecore_Wl2_Input *input) { @@ -622,12 +471,12 @@ ecore_wl2_dnd_drag_end(Ecore_Wl2_Input *input) ecore_event_add(ECORE_WL2_EVENT_DND_END, ev, NULL, NULL); } -EAPI Eina_Bool -ecore_wl2_dnd_selection_owner_has(Ecore_Wl2_Input *input) +EAPI Ecore_Wl2_Offer* +ecore_wl2_dnd_selection_get(Ecore_Wl2_Input *input) { - EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(input, NULL); - return (input->selection.source != NULL); + return input->selection; } EAPI Eina_Bool @@ -681,32 +530,303 @@ ecore_wl2_dnd_selection_set(Ecore_Wl2_Input *input, const char **types) } EAPI Eina_Bool -ecore_wl2_dnd_selection_get(Ecore_Wl2_Input *input, const char *type) +ecore_wl2_dnd_selection_clear(Ecore_Wl2_Input *input) { - char **t; - EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(input->selection.source, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(input->data.device, EINA_FALSE); - for (t = input->selection.source->types.data; *t; t++) - if (!strcmp(type, *t)) break; + wl_data_device_set_selection(input->data.device, + NULL, input->display->serial); - if (!*t) return EINA_FALSE; + return EINA_TRUE; +} - input->selection.source->sel_type = ECORE_WL2_SELECTION_CNP; - _selection_data_receive(input->selection.source, type); +static Ecore_Wl2_Drag_Action +_wl_to_action_convert(uint32_t action) +{ +#define PAIR(wl, ac) if (action == wl) return ac; + PAIR(WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY, ECORE_WL2_DRAG_ACTION_COPY) + PAIR(WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK, ECORE_WL2_DRAG_ACTION_ASK) + PAIR(WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE, ECORE_WL2_DRAG_ACTION_MOVE) + PAIR(WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE, ECORE_WL2_DRAG_ACTION_NONE) +#undef PAIR + return ECORE_WL2_DRAG_ACTION_NONE; +} - return EINA_TRUE; +static uint32_t +_action_to_wl_convert(Ecore_Wl2_Drag_Action action) +{ +#define PAIR(wl, ac) if (action == ac) return wl; + PAIR(WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY, ECORE_WL2_DRAG_ACTION_COPY) + PAIR(WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK, ECORE_WL2_DRAG_ACTION_ASK) + PAIR(WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE, ECORE_WL2_DRAG_ACTION_MOVE) + PAIR(WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE, ECORE_WL2_DRAG_ACTION_NONE) +#undef PAIR + return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; +} +static void +data_offer_offer(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, const char *type) +{ + Ecore_Wl2_Offer *offer = data; + char *str; + + if (type) + eina_array_push(offer->mimetypes, strdup(type)); /*LEEEAK */ + else + { + while((str = eina_array_pop(offer->mimetypes))) + { + free(str); + } + } +} + +static void +data_offer_source_actions(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, uint32_t source_actions) +{ + Ecore_Wl2_Offer *offer; + unsigned int i; + uint32_t types[] = {WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE, + WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY, + WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK, + WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE}; + + offer = data; + + offer->actions = 0; + + for (i = 0; i < sizeof(types); ++i) + { + if (source_actions & types[i]) + offer->actions |= _wl_to_action_convert(types[i]); + } +} + +static void +data_offer_action(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, uint32_t dnd_action) +{ + Ecore_Wl2_Offer *offer; + + offer = data; + offer->action = _wl_to_action_convert(dnd_action); +} + +static const struct wl_data_offer_listener _offer_listener = +{ + data_offer_offer, + data_offer_source_actions, + data_offer_action +}; + +void +_ecore_wl2_dnd_add(Ecore_Wl2_Input *input, struct wl_data_offer *offer) +{ + Ecore_Wl2_Offer *result; + + result = calloc(1, sizeof(Ecore_Wl2_Offer)); + result->offer = offer; + result->input = input; + result->mimetypes = eina_array_new(10); + result->ref = 1; + + wl_data_offer_add_listener(offer, &_offer_listener, result); +} + +EAPI Ecore_Wl2_Drag_Action +ecore_wl2_offer_actions_get(Ecore_Wl2_Offer *offer) +{ + return offer->actions; +} + +EAPI void +ecore_wl2_offer_actions_set(Ecore_Wl2_Offer *offer, Ecore_Wl2_Drag_Action actions, Ecore_Wl2_Drag_Action action) +{ + uint32_t val = 0; + int i = 0; + + EINA_SAFETY_ON_NULL_RETURN(offer); + + for (i = 0; i < ECORE_WL2_DRAG_ACTION_LAST; ++i) + { + if (actions & i) + val |= _action_to_wl_convert(i); + } + + offer->action = _action_to_wl_convert(action); + + wl_data_offer_set_actions(offer->offer, val, offer->action); +} + +EAPI Ecore_Wl2_Drag_Action +ecore_wl2_offer_action_get(Ecore_Wl2_Offer *offer) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(offer, ECORE_WL2_DRAG_ACTION_NONE); + return offer->action; +} + +EAPI Eina_Array* +ecore_wl2_offer_mimes_get(Ecore_Wl2_Offer *offer) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(offer, NULL); + return offer->mimetypes; +} + +static unsigned char +_emit_mime(const void *container EINA_UNUSED, void *elem, void *data) +{ + Ecore_Wl2_Offer *offer = data; + + wl_data_offer_accept(offer->offer, offer->serial, elem); + + return 1; +} + +EAPI void +ecore_wl2_offer_mimes_set(Ecore_Wl2_Offer *offer, Eina_Array *mimes) +{ + EINA_SAFETY_ON_NULL_RETURN(offer); + + wl_data_offer_accept(offer->offer, offer->serial, NULL); + if (mimes) + eina_array_foreach(mimes, _emit_mime, offer); +} + +typedef struct { + int len; + void *data; + Ecore_Wl2_Offer *offer; +} Read_Buffer; + +static void +_free_buf(void *user_data, void *event) +{ + Read_Buffer *buf = user_data; + + _ecore_wl2_offer_unref(buf->offer); + + free(buf->data); + free(user_data); + free(event); +} + +static Eina_Bool +_offer_receive_fd_cb(void *data, Ecore_Fd_Handler *fdh) +{ + Read_Buffer *buf = data; + int fd = -1; + char buffer[255]; + int len; + + fd = ecore_main_fd_handler_fd_get(fdh); + if (fd >= 0) + len = read(fd, buffer, sizeof(buffer)); + else + return ECORE_CALLBACK_RENEW; + + if (len > 0) + { + int old_len = buf->len; + + buf->len += len; + buf->data = realloc(buf->data, buf->len); + + memcpy(((char*)buf->data) + old_len, buffer, len); + return ECORE_CALLBACK_RENEW; + } + else + { + Ecore_Wl2_Event_Offer_Data_Ready *ev; + + ev = calloc(1, sizeof(Ecore_Wl2_Event_Offer_Data_Ready)); + ev->offer = buf->offer; + + ev->data = buf->data; + ev->len = buf->len; + + ecore_event_add(ECORE_WL2_EVENT_OFFER_DATA_READY, ev, _free_buf, buf); + + buf->offer->read = NULL; + return ECORE_CALLBACK_CANCEL; + } } EAPI Eina_Bool -ecore_wl2_dnd_selection_clear(Ecore_Wl2_Input *input) +ecore_wl2_offer_receive(Ecore_Wl2_Offer *offer, char *mime) { - EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE); - EINA_SAFETY_ON_NULL_RETURN_VAL(input->data.device, EINA_FALSE); + Read_Buffer *buffer; + int pipe[2]; - wl_data_device_set_selection(input->data.device, - NULL, input->display->serial); + EINA_SAFETY_ON_NULL_RETURN_VAL(offer, EINA_FALSE); + + //if a read is going on exit + if (offer->read) return EINA_FALSE; + + buffer = calloc(1, sizeof(Read_Buffer)); + buffer->offer = offer; + + // no data yet, we would have to fetch it and then tell when the data is ready + if (pipe2(pipe, O_CLOEXEC) == -1) + return EINA_FALSE; + + offer->ref ++; // we are keeping this ref until the read is done AND emitted + + wl_data_offer_receive(offer->offer, mime, pipe[1]); + close(pipe[1]); + + offer->read = + ecore_main_fd_handler_file_add(pipe[0], ECORE_FD_READ | ECORE_FD_ERROR, + _offer_receive_fd_cb, buffer, NULL, NULL); + return EINA_FALSE; +} + +EAPI void +ecore_wl2_offer_finish(Ecore_Wl2_Offer *offer) +{ + EINA_SAFETY_ON_NULL_RETURN(offer); + + wl_data_offer_finish(offer->offer); +} + +void +_ecore_wl2_offer_unref(Ecore_Wl2_Offer *offer) +{ + char *str; + + EINA_SAFETY_ON_NULL_RETURN(offer); + + offer->ref--; + + if (offer->ref > 0) return; + + wl_data_offer_destroy(offer->offer); + + if (offer->mimetypes) + { + while((str = eina_array_pop(offer->mimetypes))) + free(str); + eina_array_free(offer->mimetypes); + offer->mimetypes = NULL; + } + if (offer->input->drag == offer) offer->input->drag = NULL; + if (offer->input->selection == offer) offer->input->selection = NULL; + + free(offer); +} + +static unsigned char +_compare(const void *container EINA_UNUSED, void *elem, void *data) +{ + if (!strcmp(elem, data)) + return EINA_FALSE; return EINA_TRUE; } + +EAPI Eina_Bool +ecore_wl2_offer_supprts_mime(Ecore_Wl2_Offer *offer, const char *mime) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(offer, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(mime, EINA_FALSE); + + return !eina_array_foreach(offer->mimetypes, _compare, (void*) mime); +}
\ No newline at end of file diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c b/src/lib/ecore_wl2/ecore_wl2_input.c index 3ea2de0a64..919d424d61 100644 --- a/src/lib/ecore_wl2/ecore_wl2_input.c +++ b/src/lib/ecore_wl2/ecore_wl2_input.c @@ -1373,8 +1373,8 @@ _ecore_wl2_input_del(Ecore_Wl2_Input *input) } if (input->data.source) wl_data_source_destroy(input->data.source); - if (input->drag.source) _ecore_wl2_dnd_del(input->drag.source); - if (input->selection.source) _ecore_wl2_dnd_del(input->selection.source); + if (input->drag) _ecore_wl2_offer_unref(input->drag); + if (input->selection) _ecore_wl2_offer_unref(input->selection); if (input->data.device) wl_data_device_destroy(input->data.device); if (input->xkb.state) xkb_state_unref(input->xkb.state); diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index c15c6815da..23d1d582b1 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -413,10 +413,7 @@ struct _Ecore_Wl2_Input Eina_Bool repeating : 1; } repeat; - struct - { - Ecore_Wl2_Dnd_Source *source; - } drag, selection; + Ecore_Wl2_Offer *drag, *selection; unsigned int seat_version; }; @@ -463,6 +460,8 @@ void _ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf); void _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window); void _ecore_wl2_window_www_surface_init(Ecore_Wl2_Window *window); +void _ecore_wl2_offer_unref(Ecore_Wl2_Offer *offer); + EAPI extern int _ecore_wl2_event_window_www; EAPI extern int _ecore_wl2_event_window_www_drag; diff --git a/src/lib/elementary/elm_cnp.c b/src/lib/elementary/elm_cnp.c index be0b642efe..08b5ebb5b3 100644 --- a/src/lib/elementary/elm_cnp.c +++ b/src/lib/elementary/elm_cnp.c @@ -260,12 +260,12 @@ static Eina_Bool _wl_targets_converter(char *target, Wl_Cnp_Selection *sel, void static Eina_Bool _wl_general_converter(char *target, Wl_Cnp_Selection *sel, void *data, int size, void **data_ret, int *size_ret); static Eina_Bool _wl_text_converter(char *target, Wl_Cnp_Selection *sel, void *data, int size, void **data_ret, int *size_ret); -typedef Eina_Bool (*Wl_Data_Preparer_Cb) (Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Selection_Data_Ready *ev, Tmp_Info **tmp_info); -static Eina_Bool _wl_data_preparer_markup(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Selection_Data_Ready *ev, Tmp_Info **tmp_info); -static Eina_Bool _wl_data_preparer_uri(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Selection_Data_Ready *ev, Tmp_Info **tmp_info); -static Eina_Bool _wl_data_preparer_vcard(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Selection_Data_Ready *ev, Tmp_Info **tmp_info); -static Eina_Bool _wl_data_preparer_image(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Selection_Data_Ready *ev, Tmp_Info **tmp_info); -static Eina_Bool _wl_data_preparer_text(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Selection_Data_Ready *ev, Tmp_Info **tmp_info); +typedef Eina_Bool (*Wl_Data_Preparer_Cb) (Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Offer_Data_Ready *ev, Tmp_Info **tmp_info); +static Eina_Bool _wl_data_preparer_markup(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Offer_Data_Ready *ev, Tmp_Info **tmp_info); +static Eina_Bool _wl_data_preparer_uri(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Offer_Data_Ready *ev, Tmp_Info **tmp_info); +static Eina_Bool _wl_data_preparer_vcard(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Offer_Data_Ready *ev, Tmp_Info **tmp_info); +static Eina_Bool _wl_data_preparer_image(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Offer_Data_Ready *ev, Tmp_Info **tmp_info); +static Eina_Bool _wl_data_preparer_text(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Offer_Data_Ready *ev, Tmp_Info **tmp_info); #endif struct _Cnp_Atom @@ -2427,7 +2427,7 @@ static Eina_Bool _wl_dnd_drop(void *data EINA_UNUSED, int type EINA_UNUSED, void static Eina_Bool _wl_dnd_receive(void *data, int type EINA_UNUSED, void *event); static Eina_Bool _wl_dnd_end(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED); -static void _wl_dropable_data_handle(Wl_Cnp_Selection *sel, Ecore_Wl2_Event_Selection_Data_Ready *ev); +static void _wl_dropable_data_handle(Wl_Cnp_Selection *sel, Ecore_Wl2_Event_Offer_Data_Ready *ev); static Dropable *_wl_dropable_find(unsigned int win); static void _wl_dropable_handle(Dropable *drop, Evas_Coord x, Evas_Coord y); @@ -2691,7 +2691,7 @@ done: } static Eina_Bool -_wl_data_preparer_markup(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Selection_Data_Ready *ev, Tmp_Info **tmp_info EINA_UNUSED) +_wl_data_preparer_markup(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Offer_Data_Ready *ev, Tmp_Info **tmp_info EINA_UNUSED) { cnp_debug("In\n"); @@ -2704,7 +2704,7 @@ _wl_data_preparer_markup(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore } static Eina_Bool -_wl_data_preparer_uri(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Selection_Data_Ready *ev, Tmp_Info **tmp_info EINA_UNUSED) +_wl_data_preparer_uri(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Offer_Data_Ready *ev, Tmp_Info **tmp_info EINA_UNUSED) { char *p, *stripstr = NULL; char *data = ev->data; @@ -2787,7 +2787,7 @@ _wl_data_preparer_uri(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl } static Eina_Bool -_wl_data_preparer_vcard(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Selection_Data_Ready *ev, Tmp_Info **tmp_info EINA_UNUSED) +_wl_data_preparer_vcard(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Offer_Data_Ready *ev, Tmp_Info **tmp_info EINA_UNUSED) { cnp_debug("In\n"); @@ -2800,7 +2800,7 @@ _wl_data_preparer_vcard(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_ } static Eina_Bool -_wl_data_preparer_image(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Selection_Data_Ready *ev, Tmp_Info **tmp_info) +_wl_data_preparer_image(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Offer_Data_Ready *ev, Tmp_Info **tmp_info) { cnp_debug("In\n"); Tmp_Info *tmp; @@ -2823,7 +2823,7 @@ _wl_data_preparer_image(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_ } static Eina_Bool -_wl_data_preparer_text(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Selection_Data_Ready *ev, Tmp_Info **tmp_info EINA_UNUSED) +_wl_data_preparer_text(Wl_Cnp_Selection *sel, Elm_Selection_Data *ddata, Ecore_Wl2_Event_Offer_Data_Ready *ev, Tmp_Info **tmp_info EINA_UNUSED) { cnp_debug("In\n"); @@ -2954,38 +2954,83 @@ _wl_elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Form return EINA_FALSE; } +typedef struct { + Ecore_Wl2_Offer *offer; + Wl_Cnp_Selection sel; + Ecore_Event_Handler *handler; +} Selection_Ready; + +static Eina_Bool +_wl_selection_receive(void *data, int type EINA_UNUSED, void *event) +{ + Ecore_Wl2_Event_Offer_Data_Ready *ev = event; + Selection_Ready *ready = data; + Wl_Cnp_Selection *sel = &ready->sel; + + if (ready->offer != ev->offer) return ECORE_CALLBACK_PASS_ON; + + if (sel->requestwidget) + { + 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 + { + char *stripstr, *mkupstr; + + stripstr = malloc(ev->len + 1); + if (!stripstr) return ECORE_CALLBACK_CANCEL; + 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; + } + ecore_event_handler_del(ready->handler); + free(data); + return ECORE_CALLBACK_CANCEL; +} + static Eina_Bool _wl_elm_cnp_selection_get(const Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format, Elm_Drop_Cb datacb, void *udata) { Ecore_Wl2_Window *win; - Wl_Cnp_Selection *sel = &wl_cnp_selection; _wl_elm_cnp_init(); win = _wl_elm_widget_window_get(obj); - if (sel->requestwidget) - evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL, - _wl_sel_obj_del2, &wl_cnp_selection); - sel->requestformat = format; - sel->requestwidget = (Evas_Object *) obj; - sel->win = win; - /* sel->request(win, ECORE_X_SELECTION_TARGET_TARGETS); */ - sel->datacb = datacb; - sel->udata = udata; - - evas_object_event_callback_add(sel->requestwidget, EVAS_CALLBACK_DEL, - _wl_sel_obj_del2, &wl_cnp_selection); if ((selection == ELM_SEL_TYPE_CLIPBOARD) || (selection == ELM_SEL_TYPE_PRIMARY) || (selection == ELM_SEL_TYPE_SECONDARY)) { Ecore_Wl2_Input *input; + Ecore_Wl2_Offer *offer; const char *types[10] = {0, }; int i = -1, j; input = ecore_wl2_window_input_get(win); + offer = ecore_wl2_dnd_selection_get(input); + + if (!offer) return EINA_FALSE; if ((format & ELM_SEL_FORMAT_MARKUP) || (format & ELM_SEL_FORMAT_TEXT)) @@ -3003,9 +3048,27 @@ _wl_elm_cnp_selection_get(const Evas_Object *obj, Elm_Sel_Type selection, Elm_Se if (i < 0) return EINA_FALSE; + for (j = 0; j <= i; j++) - if (ecore_wl2_dnd_selection_get(input, types[j])) - break; + if (ecore_wl2_offer_supprts_mime(offer, types[j])) + { + Selection_Ready *ready; + + ready = calloc(1, sizeof(Selection_Ready)); + + ready->sel.requestformat = format; + ready->sel.requestwidget = (Evas_Object *) obj; + ready->sel.win = win; + ready->sel.datacb = datacb; + ready->sel.udata = udata; + ready->offer = offer; + + evas_object_event_callback_add(ready->sel.requestwidget, EVAS_CALLBACK_DEL, + _wl_sel_obj_del2, &ready->sel); + + ecore_wl2_offer_receive(offer, (char*)types[j]); + ready->handler = ecore_event_handler_add(ECORE_WL2_EVENT_OFFER_DATA_READY, _wl_selection_receive, ready); + } } return EINA_TRUE; @@ -3112,89 +3175,6 @@ _wl_selection_send(void *data, int type EINA_UNUSED, void *event) } static Eina_Bool -_wl_selection_receive(void *udata, int type EINA_UNUSED, void *event) -{ - Wl_Cnp_Selection *sel = udata; - Ecore_Wl2_Event_Selection_Data_Ready *ev = event; - - _wl_elm_cnp_init(); - - if (sel->requestwidget) - { - 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); - - 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 - { - 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: - if (sel->seltype == ELM_SEL_TYPE_XDND) - { - /* FIXME: Send Finished ?? */ - } - - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool _wl_elm_cnp_init(void) { static int _init_count = 0; @@ -3204,9 +3184,6 @@ _wl_elm_cnp_init(void) ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_SEND, _wl_selection_send, &wl_cnp_selection); - ecore_event_handler_add(ECORE_WL2_EVENT_CNP_DATA_READY, - _wl_selection_receive, &wl_cnp_selection); - return EINA_TRUE; } @@ -3221,9 +3198,6 @@ _wl_elm_dnd_init(void) text_uri = eina_stringshare_add("text/uri-list"); _wl_elm_cnp_init(); - ecore_event_handler_add(ECORE_WL2_EVENT_DND_DATA_READY, - _wl_dnd_receive, &wl_cnp_selection); - ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_END, _wl_dnd_end, &wl_cnp_selection); @@ -3468,20 +3442,23 @@ static Eina_Bool _wl_dnd_enter(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { Ecore_Wl2_Event_Dnd_Enter *ev; - int i = 0; + Eina_Array *known, *available; + unsigned int i = 0; ev = event; - if ((!ev->num_types) || (!ev->types)) return ECORE_CALLBACK_PASS_ON; + known = eina_array_new(5); + available = ecore_wl2_offer_mimes_get(ev->offer); - savedtypes.ntypes = ev->num_types; free(savedtypes.types); - savedtypes.types = malloc(sizeof(char *) * ev->num_types); + + savedtypes.ntypes = eina_array_count(available); + savedtypes.types = malloc(sizeof(char *) * savedtypes.ntypes); if (!savedtypes.types) return EINA_FALSE; - for (i = 0; i < ev->num_types; i++) + for (i = 0; i < eina_array_count(available); i++) { - savedtypes.types[i] = eina_stringshare_add(ev->types[i]); + savedtypes.types[i] = eina_stringshare_add(eina_array_data_get(available, i)); if (savedtypes.types[i] == text_uri) { savedtypes.textreq = 1; @@ -3490,17 +3467,15 @@ _wl_dnd_enter(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) } doaccept = EINA_FALSE; - for (i = 0; i < ev->num_types; i++) + for (i = 0; i < eina_array_count(available); i++) { - if (_wl_drops_accept(ev->types[i])) + if (_wl_drops_accept(eina_array_data_get(available, i))) { - doaccept = EINA_TRUE; - wl_data_offer_accept(ev->offer, ev->serial, ev->types[i]); + eina_array_push(known, strdup(eina_array_data_get(available, i))); } } - if (!doaccept) - wl_data_offer_accept(ev->offer, ev->serial, NULL); + ecore_wl2_offer_mimes_set(ev->offer, known); return ECORE_CALLBACK_PASS_ON; } @@ -3635,6 +3610,38 @@ _wl_dnd_position(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) return ECORE_CALLBACK_PASS_ON; } + +static Eina_Bool +_wl_dnd_receive(void *data, int type EINA_UNUSED, void *event) +{ + Ecore_Wl2_Event_Offer_Data_Ready *ev; + Ecore_Wl2_Offer *offer; + cnp_debug("In\n"); + + ev = event; + offer = data; + + if (offer != ev->offer) return ECORE_CALLBACK_PASS_ON; + + if (wl_cnp_selection.requestwidget) + { + Ecore_Wl2_Drag_Action action; + + action = ecore_wl2_offer_action_get(ev->offer); + + _wl_dropable_data_handle(&wl_cnp_selection, ev); + evas_object_event_callback_del_full(wl_cnp_selection.requestwidget, + EVAS_CALLBACK_DEL, + _wl_sel_obj_del2, &wl_cnp_selection); + wl_cnp_selection.requestwidget = NULL; + + } + + ecore_wl2_offer_finish(ev->offer); + + return ECORE_CALLBACK_CANCEL; +} + static Eina_Bool _wl_dnd_drop(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { @@ -3660,8 +3667,9 @@ _wl_dnd_drop(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) &wl_cnp_selection); win = _wl_elm_widget_window_get(drop->obj); - ecore_wl2_dnd_drag_get(ecore_wl2_window_input_get(win), - drop->last.type); + ecore_wl2_offer_receive(ev->offer, (char*)drop->last.type); + ecore_event_handler_add(ECORE_WL2_EVENT_OFFER_DATA_READY, _wl_dnd_receive, ev->offer); + return ECORE_CALLBACK_PASS_ON; } } @@ -3672,29 +3680,6 @@ _wl_dnd_drop(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) } static Eina_Bool -_wl_dnd_receive(void *data, int type EINA_UNUSED, void *event) -{ - Wl_Cnp_Selection *sel; - Ecore_Wl2_Event_Selection_Data_Ready *ev; - cnp_debug("In\n"); - - ev = event; - sel = data; - - if (sel->requestwidget) - { - _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; -} - -static Eina_Bool _wl_dnd_end(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { Ecore_Wl2_Event_Data_Source_End *ev; @@ -3735,7 +3720,7 @@ _wl_dnd_end(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) } static void -_wl_dropable_data_handle(Wl_Cnp_Selection *sel, Ecore_Wl2_Event_Selection_Data_Ready *ev) +_wl_dropable_data_handle(Wl_Cnp_Selection *sel, Ecore_Wl2_Event_Offer_Data_Ready *ev) { Dropable *drop; Ecore_Wl2_Window *win; @@ -5185,7 +5170,7 @@ elm_selection_selection_has_owner(Evas_Object *obj) win = _wl_elm_widget_window_get(obj); if (win) - return ecore_wl2_dnd_selection_owner_has(ecore_wl2_window_input_get(win)); + return !!ecore_wl2_dnd_selection_get(ecore_wl2_window_input_get(win)); #endif return _local_elm_selection_selection_has_owner(obj); } |