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
This commit is contained in:
Marcel Hollerbach 2016-09-22 09:13:48 +02:00
parent 7d6fd10523
commit 5884bba096
6 changed files with 600 additions and 423 deletions

View File

@ -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
@ -867,26 +867,18 @@ EAPI void ecore_wl2_dnd_drag_types_set(Ecore_Wl2_Input *input, const char **type
/** @since 1.17 */
EAPI void ecore_wl2_dnd_drag_start(Ecore_Wl2_Input *input, Ecore_Wl2_Window *window, Ecore_Wl2_Window *drag_window);
/* 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 */
EAPI Eina_Bool ecore_wl2_dnd_selection_set(Ecore_Wl2_Input *input, const char **types);
/* 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

View File

@ -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();

View File

@ -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)
_unset_serial(void *user_data, void *event)
{
Ecore_Wl2_Event_Selection_Data_Ready *ev;
Ecore_Wl2_Offer *offer = user_data;
ev = event;
if (!ev) return;
if (offer)
offer->serial = 0;
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)
{
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);
}
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;
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 (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 (!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
@ -680,25 +529,6 @@ ecore_wl2_dnd_selection_set(Ecore_Wl2_Input *input, const char **types)
return EINA_TRUE;
}
EAPI Eina_Bool
ecore_wl2_dnd_selection_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->selection.source, EINA_FALSE);
for (t = input->selection.source->types.data; *t; t++)
if (!strcmp(type, *t)) break;
if (!*t) return EINA_FALSE;
input->selection.source->sel_type = ECORE_WL2_SELECTION_CNP;
_selection_data_receive(input->selection.source, type);
return EINA_TRUE;
}
EAPI Eina_Bool
ecore_wl2_dnd_selection_clear(Ecore_Wl2_Input *input)
{
@ -710,3 +540,293 @@ ecore_wl2_dnd_selection_clear(Ecore_Wl2_Input *input)
return EINA_TRUE;
}
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;
}
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_offer_receive(Ecore_Wl2_Offer *offer, char *mime)
{
Read_Buffer *buffer;
int pipe[2];
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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
@ -3111,89 +3174,6 @@ _wl_selection_send(void *data, int type EINA_UNUSED, void *event)
return ECORE_CALLBACK_PASS_ON;
}
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)
{
@ -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;
}
}
@ -3671,29 +3679,6 @@ _wl_dnd_drop(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)
{
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)
{
@ -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);
}