forked from enlightenment/efl
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:
parent
7d6fd10523
commit
5884bba096
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue