aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Hollerbach <marcel-hollerbach@t-online.de>2016-09-22 09:13:48 +0200
committerMarcel Hollerbach <marcel-hollerbach@t-online.de>2016-09-23 11:15:14 +0200
commit5884bba09694626a04c9de56229353fd76d3d945 (patch)
treed8695534031b515d56229212de09fe3348d00649
parentecore_wl2: save action of data source in seperated field (diff)
downloadefl-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.h126
-rw-r--r--src/lib/ecore_wl2/ecore_wl2.c9
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_dnd.c576
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_input.c4
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_private.h7
-rw-r--r--src/lib/elementary/elm_cnp.c295
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);
}