summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiep Ha <thiepha@gmail.com>2018-01-09 18:50:23 +0900
committerThiep Ha <thiepha@gmail.com>2018-01-11 17:56:24 +0900
commite88bbaa1e314751e5c1a04dec7f1f179188428ae (patch)
tree0964c6cd19b3888c026980d96441fea9441d176b
parent35339504b0db553083abeccd0bf5c1dcd05b4acc (diff)
downloadefl-e88bbaa1e314751e5c1a04dec7f1f179188428ae.tar.gz
cnp_dnd: make legacy APIs use new interfaces
Legacy APIs can uses efl_selection, efl_ui_dnd, efl_ui_dnd_container interfaces with helper functions.
-rw-r--r--src/Makefile_Elementary.am1
-rw-r--r--src/lib/elementary/efl_selection.c241
-rw-r--r--src/lib/elementary/efl_selection_manager.c90
-rw-r--r--src/lib/elementary/efl_ui_dnd.c678
-rw-r--r--src/lib/elementary/elm_cnp.c5851
5 files changed, 963 insertions, 5898 deletions
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index 75204582fe..d0af9ad567 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -618,7 +618,6 @@ lib_elementary_libelementary_la_SOURCES = \
lib/elementary/efl_ui_calendar.c \
lib/elementary/efl_ui_check.c \
lib/elementary/elm_clock.c \
- lib/elementary/elm_cnp.c \
lib/elementary/elm_code_line.c \
lib/elementary/elm_code_text.c \
lib/elementary/elm_code_indent.c \
diff --git a/src/lib/elementary/efl_selection.c b/src/lib/elementary/efl_selection.c
index 9f086e340e..00cfe13e1b 100644
--- a/src/lib/elementary/efl_selection.c
+++ b/src/lib/elementary/efl_selection.c
@@ -59,4 +59,245 @@ _efl_selection_has_owner(Eo *obj, void *pd EINA_UNUSED, Efl_Selection_Type type,
}
+////////// Support legacy APIs
+
+//TODO: Clear this list (when sel_man is deleted)
+Eina_List *lost_cb_list = NULL;
+
+#ifdef HAVE_ELEMENTARY_WL2
+static Ecore_Wl2_Window *
+_wl_window_get(const Evas_Object *obj)
+{
+ Evas_Object *top;
+ Ecore_Wl2_Window *win = NULL;
+
+ if (elm_widget_is(obj))
+ {
+ top = elm_widget_top_get(obj);
+ if (!top) top = elm_widget_top_get(elm_widget_parent_widget_get(obj));
+ if (top && (efl_isa(top, EFL_UI_WIN_CLASS)))
+ win = elm_win_wl_window_get(top);
+ }
+ if (!win)
+ {
+ Ecore_Evas *ee;
+ Evas *evas;
+ const char *engine_name;
+
+ if (!(evas = evas_object_evas_get(obj)))
+ return NULL;
+ if (!(ee = ecore_evas_ecore_evas_get(evas)))
+ return NULL;
+
+ engine_name = ecore_evas_engine_name_get(ee);
+ if (!strcmp(engine_name, ELM_BUFFER))
+ {
+ ee = ecore_evas_buffer_ecore_evas_parent_get(ee);
+ if (!ee) return NULL;
+ engine_name = ecore_evas_engine_name_get(ee);
+ }
+ if (!strncmp(engine_name, "wayland", sizeof("wayland") - 1))
+ {
+ /* In case the engine is not a buffer, we want to check once. */
+ win = ecore_evas_wayland2_window_get(ee);
+ if (!win) return NULL;
+ }
+ }
+
+ return win;
+}
+
+int _wl_default_seat_id_get(Evas_Object *obj)
+{
+ Ecore_Wl2_Window *win = _wl_window_get(obj);
+ Eo *seat, *parent2, *ewin;
+
+ if (obj)
+ {
+ Eo *top = elm_widget_top_get(obj);
+ if (efl_isa(top, EFL_UI_WIN_INLINED_CLASS))
+ {
+ parent2 = efl_ui_win_inlined_parent_get(top);
+ if (parent2) obj = elm_widget_top_get(parent2) ?: parent2;
+ }
+ /* fake win means canvas seat id will not match protocol seat id */
+ ewin = elm_win_get(obj);
+ if (elm_win_type_get(ewin) == ELM_WIN_FAKE) obj = NULL;
+ }
+
+ if (!obj)
+ {
+ Ecore_Wl2_Input *input;
+ Eina_Iterator *it;
+
+ it = ecore_wl2_display_inputs_get(ecore_wl2_window_display_get(win));
+ EINA_ITERATOR_FOREACH(it, input) break;
+ eina_iterator_free(it);
+ if (input)
+ ecore_wl2_input_seat_id_get(input);
+ }
+
+ seat = evas_default_device_get(evas_object_evas_get(obj), EFL_INPUT_DEVICE_TYPE_SEAT);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(seat, 1);
+ return evas_device_seat_id_get(seat);
+}
+#endif
+
+typedef struct _Cnp_Data_Cb_Wrapper Cnp_Data_Cb_Wrapper;
+struct _Cnp_Data_Cb_Wrapper
+{
+ void *udata;
+ Elm_Drop_Cb datacb;
+};
+
+static void
+_selection_data_ready_cb(void *data, Efl_Object *obj, Efl_Selection_Data *seldata)
+{
+ printf("obj: %p, data: %s, length: %zd\n", obj, (char *)seldata->data.mem, seldata->data.len);
+ Cnp_Data_Cb_Wrapper *wdata = data;
+ if (!wdata) return;
+ Elm_Selection_Data ddata;
+
+ ddata.data = calloc(1, seldata->data.len + 1);
+ if (!ddata.data) return;
+ ddata.data = memcpy(ddata.data, seldata->data.mem, seldata->data.len);
+ ddata.len = seldata->data.len;
+ ddata.x = seldata->pos.x;
+ ddata.y = seldata->pos.y;
+ ddata.format = seldata->format;
+ ddata.action = seldata->action;
+ wdata->datacb(wdata->udata, obj, &ddata);
+ free(ddata.data);
+}
+
+typedef struct _Sel_Lost_Data Sel_Lost_Data;
+struct _Sel_Lost_Data
+{
+ const Evas_Object *obj;
+ Elm_Sel_Type type;
+ void *udata;
+ Elm_Selection_Loss_Cb loss_cb;
+};
+
+static Eina_Value
+_selection_lost_cb(void *data, const Eina_Value value)
+{
+ Eina_List *l, *l2;
+ Sel_Lost_Data *ldata, *ldata2;
+
+ ldata = data;
+ EINA_LIST_FOREACH_SAFE(lost_cb_list, l, l2, ldata2)
+ {
+ if ((ldata->obj == ldata2->obj) &&
+ (ldata->type == ldata2->type))
+ {
+ ldata2->loss_cb(ldata2->udata, ldata2->type);
+ lost_cb_list = eina_list_remove(lost_cb_list, ldata2);
+ }
+ }
+ free(ldata);
+
+ return value;
+}
+
+EAPI Eina_Bool
+elm_cnp_selection_get(const Evas_Object *obj, Elm_Sel_Type type,
+ Elm_Sel_Format format, Elm_Drop_Cb datacb, void *udata)
+{
+ int seatid = 1;
+ Eo *sel_man = _selection_manager_get((Evas_Object *)obj);
+ Cnp_Data_Cb_Wrapper *wdata = calloc(1, sizeof(Cnp_Data_Cb_Wrapper));
+
+ if (!wdata) return EINA_FALSE;
+
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+ wdata->udata = udata;
+ wdata->datacb = datacb;
+ efl_selection_manager_selection_get(sel_man, (Evas_Object *)obj, type, format,
+ wdata, _selection_data_ready_cb, NULL, seatid);
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type type,
+ Elm_Sel_Format format, const void *selbuf, size_t buflen)
+{
+ int seatid = 1;
+ Eina_Future *f;
+ Sel_Lost_Data *ldata;
+ Eo *sel_man = _selection_manager_get(obj);
+ Eina_Slice data;
+
+ ldata = calloc(1, sizeof(Sel_Lost_Data));
+ if (!ldata) return EINA_FALSE;
+ data.mem = selbuf;
+ data.len = buflen;
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+ f = efl_selection_manager_selection_set(sel_man, obj, type, format, data, seatid);
+
+ ldata->obj = obj;
+ ldata->type = type;
+ eina_future_then_easy(f, _selection_lost_cb, NULL, NULL, EINA_VALUE_TYPE_UINT, ldata);
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+elm_object_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type type)
+{
+ int seatid = 1;
+ Eo *sel_man = _selection_manager_get((Evas_Object *)obj);
+
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+ efl_selection_manager_selection_clear(sel_man, obj, type, seatid);
+
+ return EINA_TRUE;
+}
+
+EAPI void
+elm_cnp_selection_loss_callback_set(Evas_Object *obj, Elm_Sel_Type type,
+ Elm_Selection_Loss_Cb func, const void *data)
+{
+ Sel_Lost_Data *ldata = calloc(1, sizeof(Sel_Lost_Data));
+ if (!ldata) return;
+ ldata->obj = obj;
+ ldata->type = type;
+ ldata->udata = (void *)data;
+ ldata->loss_cb = func;
+ lost_cb_list = eina_list_append(lost_cb_list, ldata);
+}
+
+EAPI Eina_Bool
+elm_selection_selection_has_owner(Evas_Object *obj)
+{
+ int seatid = 1;
+ Eo *sel_man = _selection_manager_get((Evas_Object *)obj);
+
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+
+ return efl_selection_manager_selection_has_owner(sel_man, obj,
+ EFL_SELECTION_TYPE_CLIPBOARD, seatid);
+}
+
+EAPI Eina_Bool
+elm_cnp_clipboard_selection_has_owner(Evas_Object *obj)
+{
+ int seatid = 1;
+ Eo *sel_man = _selection_manager_get((Evas_Object *)obj);
+
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+ return efl_selection_manager_selection_has_owner(sel_man, obj,
+ EFL_SELECTION_TYPE_CLIPBOARD, seatid);
+}
+
#include "efl_selection.eo.c"
diff --git a/src/lib/elementary/efl_selection_manager.c b/src/lib/elementary/efl_selection_manager.c
index 91cc4a6149..bcb79aa13d 100644
--- a/src/lib/elementary/efl_selection_manager.c
+++ b/src/lib/elementary/efl_selection_manager.c
@@ -19,7 +19,6 @@
# define sel_debug(x...) do { } while (0)
#endif
-static void _set_selection_list(Sel_Manager_Selection *sel_list, Sel_Manager_Seat_Selection *seat_sel);
static void _anim_data_free(Sel_Manager_Drag_Container *dc);
static void _cont_obj_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _cont_obj_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
@@ -30,13 +29,18 @@ void efl_selection_manager_selection_clear(Eo *obj, Efl_Object *owner, Efl_Selec
void efl_selection_manager_drag_start(Eo *obj, Efl_Object *drag_obj, Efl_Selection_Format format, Eina_Slice data, Efl_Selection_Action action, void *icon_func_data, Efl_Dnd_Drag_Icon_Create icon_func, Eina_Free_Cb icon_func_free_cb, unsigned int seat);
#ifdef HAVE_ELEMENTARY_X
+static void _set_selection_list(Sel_Manager_Selection *sel_list, Sel_Manager_Seat_Selection *seat_sel);
static Ecore_X_Atom _x11_dnd_action_rev_map(Efl_Selection_Action action);
static Ecore_X_Window _x11_xwin_get(const Evas_Object *obj);
#endif
#ifdef HAVE_ELEMENTARY_WL2
static Ecore_Wl2_Window *_wl_window_get(const Evas_Object *obj);
-static Ecore_Wl2_Input *_wl_seat_get(Ecore_Wl2_Window *win, const Evas_Object *obj, unsigned int seat_id);
+static Ecore_Wl2_Input *_wl_seat_get(Ecore_Wl2_Window *win, Evas_Object *obj, unsigned int seat_id);
+#endif
+
+#ifdef HAVE_ELEMENTARY_WIN32
+static void _set_selection_list(Sel_Manager_Selection *sel_list, Sel_Manager_Seat_Selection *seat_sel);
#endif
static inline void
@@ -157,6 +161,37 @@ _sel_manager_seat_selection_init(Efl_Selection_Manager_Data *pd, unsigned int se
return seat_sel;
}
+static void
+_sel_manager_promise_cancel(void *data, const Eina_Promise *dead_future EINA_UNUSED)
+{
+ Sel_Manager_Selection_Lost *sel_lost = data;
+ //FIXME: remove from sel_lost_list in seat_sel
+ free(sel_lost);
+}
+
+static inline Eina_Future *
+_update_sel_lost_list(Efl_Object *obj, Efl_Selection_Type type,
+ Sel_Manager_Seat_Selection *seat_sel)
+{
+ Eina_Promise *p;
+ Sel_Manager_Selection_Lost *sel_lost;
+
+ sel_lost = calloc(1, sizeof(Sel_Manager_Selection_Lost));
+ if (!sel_lost)
+ return NULL;
+ sel_lost->request = obj;
+ sel_lost->type = type;
+ seat_sel->sel_lost_list = eina_list_append(seat_sel->sel_lost_list, sel_lost);
+
+ p = eina_promise_new(efl_loop_future_scheduler_get(obj),
+ _sel_manager_promise_cancel, NULL);
+ eina_promise_data_set(p, sel_lost);
+ if (!p) return NULL;
+ sel_lost->promise = p;
+
+ return eina_future_new(p);
+}
+
/* TODO: this should not be an actual tempfile, but rather encode the object
* as http://dataurl.net/ if it's an image or similar. Evas should support
* decoding it as memfile. */
@@ -901,7 +936,6 @@ _x11_selection_clear(void *data, int type EINA_UNUSED, void *event)
Eina_List *l, *l_next;
Sel_Manager_Selection_Lost *sel_lost;
unsigned int i;
- ERR("In");
seat_sel = _sel_manager_seat_selection_get(pd, 1);
if (!seat_sel)
@@ -1082,37 +1116,6 @@ _x11_text_converter(char *target, void *data, int size EINA_UNUSED, void **data_
return EINA_TRUE;
}
-static void
-_sel_manager_promise_cancel(void *data, const Eina_Promise *dead_future EINA_UNUSED)
-{
- Sel_Manager_Selection_Lost *sel_lost = data;
- //FIXME: remove from sel_lost_list in seat_sel
- free(sel_lost);
-}
-
-static inline Eina_Future *
-_update_sel_lost_list(Efl_Object *obj, Efl_Selection_Type type,
- Sel_Manager_Seat_Selection *seat_sel)
-{
- Eina_Promise *p;
- Sel_Manager_Selection_Lost *sel_lost;
-
- sel_lost = calloc(1, sizeof(Sel_Manager_Selection_Lost));
- if (!sel_lost)
- return NULL;
- sel_lost->request = obj;
- sel_lost->type = type;
- seat_sel->sel_lost_list = eina_list_append(seat_sel->sel_lost_list, sel_lost);
-
- p = eina_promise_new(efl_loop_future_scheduler_get(obj),
- _sel_manager_promise_cancel, NULL);
- eina_promise_data_set(p, sel_lost);
- if (!p) return NULL;
- sel_lost->promise = p;
-
- return eina_future_new(p);
-}
-
static Eina_Future *
_x11_efl_sel_manager_selection_set(Efl_Selection_Manager_Data *pd, Efl_Object *owner,
Efl_Selection_Type type, Efl_Selection_Format format, Eina_Slice data,
@@ -1138,7 +1141,7 @@ _x11_efl_sel_manager_selection_set(Efl_Selection_Manager_Data *pd, Efl_Object *o
sel->format = format;
sel->set(xwin, &sel, sizeof(&sel));
- sel_debug("data: %p (%ld)", &sel, sizeof(&sel));
+ sel_debug("data: %p (%zu)", &sel, sizeof(&sel));
return _update_sel_lost_list(owner, type, seat_sel);
}
@@ -1964,7 +1967,6 @@ _x11_sel_manager_drop_target_add(Efl_Selection_Manager_Data *pd, Efl_Object *tar
Efl_Selection_Format format, Ecore_X_Window xwin,
unsigned int seat)
{
- ERR("In");
Sel_Manager_Dropable *dropable = NULL;
Eina_List *l;
Eina_Bool have_drop_list = EINA_FALSE;
@@ -2076,10 +2078,10 @@ _wl_drag_source_del(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *
}
static void
-_wl_efl_sel_manager_drag_start(Eo *obj, Efl_Selection_Manager_Data *pd, Efl_Object *drag_obj,
+_wl_efl_sel_manager_drag_start(Eo *obj EINA_UNUSED, Efl_Selection_Manager_Data *pd, Efl_Object *drag_obj,
Efl_Selection_Format format, Eina_Slice data,
Efl_Selection_Action action, void *icon_func_data,
- Efl_Dnd_Drag_Icon_Create icon_func, Eina_Free_Cb icon_func_free_cb,
+ Efl_Dnd_Drag_Icon_Create icon_func, Eina_Free_Cb icon_func_free_cb EINA_UNUSED,
Ecore_Wl2_Window *win, unsigned int seat)
{
Ecore_Evas *ee;
@@ -2481,11 +2483,11 @@ _wl_efl_sel_manager_selection_set(Efl_Selection_Manager_Data *pd,
return _update_sel_lost_list(owner, type, seat_sel);
}
-static void
+/*static void
_wl_selection_changed_free(void *data, void *ev EINA_UNUSED)
{
ecore_wl2_display_disconnect(data);
-}
+}*/
static Eina_Bool
_wl_selection_changed(void *data, int type EINA_UNUSED, void *event)
@@ -2622,7 +2624,7 @@ _wl_dnd_end(void *data, int type EINA_UNUSED, void *event)
}
static Ecore_Wl2_Input *
-_wl_seat_get(Ecore_Wl2_Window *win, const Evas_Object *obj, unsigned int seat_id)
+_wl_seat_get(Ecore_Wl2_Window *win, Evas_Object *obj, unsigned int seat_id)
{
Eo *seat, *parent2, *ewin;
Ecore_Wl2_Input *input = NULL;
@@ -2719,7 +2721,6 @@ _wl_selection_receive(void *data, int type EINA_UNUSED, void *event)
{
Ecore_Wl2_Event_Offer_Data_Ready *ev = event;
Sel_Manager_Selection *sel = data;
- ERR("in");
if (sel->sel_offer != ev->offer) return ECORE_CALLBACK_PASS_ON;
@@ -2783,7 +2784,7 @@ _wl_efl_sel_manager_selection_get(const Efl_Object *request, Efl_Selection_Manag
sel->data_func = data_func;
sel->data_func_free_cb = data_func_free_cb;
- input = _wl_seat_get(win, request, seat_sel->seat);
+ input = _wl_seat_get(win, (Efl_Object *)request, seat_sel->seat);
offer = ecore_wl2_dnd_selection_get(input);
//there can be no selection available
@@ -4279,7 +4280,6 @@ _drag_anim_play(void *data, double pos)
{
Sel_Manager_Drag_Container *dc = data;
- ERR("In");
if (dc->animator)
{
Eina_List *l;
@@ -4317,7 +4317,6 @@ _drag_anim_play(void *data, double pos)
static inline void
_drag_anim_start(Sel_Manager_Drag_Container *dc)
{
- ERR("In");
dc->timer = NULL;
if (dc->icon_func)
@@ -4904,7 +4903,6 @@ EOLIAN static void
_efl_selection_manager_container_drop_item_del(Eo *obj EINA_UNUSED, Efl_Selection_Manager_Data *pd,
Efl_Object *cont, unsigned int seat EINA_UNUSED)
{
- ERR("In");
_drop_item_container_del(pd, cont, EINA_TRUE);
}
diff --git a/src/lib/elementary/efl_ui_dnd.c b/src/lib/elementary/efl_ui_dnd.c
index 731229d121..ae27c53bd6 100644
--- a/src/lib/elementary/efl_ui_dnd.c
+++ b/src/lib/elementary/efl_ui_dnd.c
@@ -132,5 +132,683 @@ _efl_ui_dnd_container_drop_item_del(Eo *obj, Efl_Ui_Dnd_Container_Data *pd EINA_
efl_selection_manager_container_drop_item_del(sel_man, obj, seat);
}
+
+///////////
+typedef struct _Dnd_Icon_Create Dnd_Icon_Create;
+typedef struct _Dnd_Drag_Pos Dnd_Drag_Pos;
+typedef struct _Dnd_Drag_Accept Dnd_Drag_Accept;
+typedef struct _Dnd_Drag_Done Dnd_Drag_Done;
+typedef struct _Dnd_Drag_State Dnd_Drag_State;
+typedef struct _Dnd_Drop Dnd_Drop;
+typedef struct _Dnd_Cont_Drag_Pos Dnd_Cont_Drag_Pos;
+typedef struct _Dnd_Cont_Drop Dnd_Cont_Drop;
+typedef struct _Item_Container_Drag_Info Item_Container_Drag_Info;
+
+struct _Dnd_Icon_Create
+{
+ void *icon_data;
+ Elm_Drag_Icon_Create_Cb icon_cb;
+};
+
+struct _Dnd_Drag_Pos
+{
+ void *pos_data;
+ Elm_Drag_Pos pos_cb;
+};
+
+struct _Dnd_Drag_Accept
+{
+ void *accept_data;
+ Elm_Drag_Accept accept_cb;
+};
+
+struct _Dnd_Drag_Done
+{
+ void *done_data;
+ Elm_Drag_State done_cb;
+
+ //for deleting
+ Dnd_Drag_Pos *pos;
+ Dnd_Drag_Accept *accept;
+};
+
+struct _Dnd_Drag_State
+{
+ void *state_data;
+ Elm_Drag_State state_cb;
+};
+
+struct _Dnd_Drop
+{
+ Efl_Object *obj;
+ Elm_Sel_Format format;
+ void *drop_data;
+ Elm_Drop_Cb drop_cb;
+
+ //for deleting
+ Dnd_Drag_State *enter;
+ Dnd_Drag_State *leave;
+ Dnd_Drag_Pos *pos;
+};
+
+struct _Dnd_Cont_Drag_Pos
+{
+ void *pos_data;
+ Elm_Drag_Item_Container_Pos pos_cb;
+ Elm_Xy_Item_Get_Cb item_get_cb;
+};
+
+struct _Dnd_Cont_Drop
+{
+ Efl_Object *obj;
+ Elm_Sel_Format format;
+ void *drop_data;
+ Elm_Drop_Item_Container_Cb drop_cb;
+ Elm_Xy_Item_Get_Cb item_get_cb;
+
+ //for deleting
+ Dnd_Drag_State *enter;
+ Dnd_Drag_State *leave;
+ Dnd_Cont_Drag_Pos *pos;
+};
+
+struct _Item_Container_Drag_Info
+{
+ Elm_Drag_User_Info user_info;
+ Elm_Object_Item *it;
+ Elm_Item_Container_Data_Get_Cb data_get_cb;
+ Elm_Xy_Item_Get_Cb item_get_cb;
+};
+
+static Efl_Object *
+_dnd_icon_create_cb(void *data, Efl_Object *win, Efl_Object *drag_obj EINA_UNUSED, Eina_Position2D *pos_ret)
+{
+ Dnd_Icon_Create *ic = data;
+ Efl_Object *ret = ic->icon_cb(ic->icon_data, win, &pos_ret->x, &pos_ret->y);
+
+ free(ic);
+ return ret;
+}
+
+static void
+_dnd_drag_pos_cb(void *data, const Efl_Event *event)
+{
+ Dnd_Drag_Pos *pos = data;
+ Efl_Dnd_Drag_Pos *ddata = event->info;
+
+ if (pos->pos_cb)
+ pos->pos_cb(pos->pos_data, event->object, ddata->pos.x, ddata->pos.y,
+ ddata->action);
+}
+
+static void
+_dnd_drag_accept_cb(void *data, const Efl_Event *event)
+{
+ Dnd_Drag_Accept *accept = data;
+
+ if (accept->accept_cb)
+ accept->accept_cb(accept->accept_data, event->object, *(Eina_Bool *)event->info);
+}
+
+static void
+_dnd_drag_done_cb(void *data, const Efl_Event *event)
+{
+ Dnd_Drag_Done *done = data;
+
+ if (done->done_cb)
+ done->done_cb(done->done_data, event->object);
+
+ efl_event_callback_del(event->object, EFL_UI_DND_EVENT_DRAG_POS,
+ _dnd_drag_pos_cb, done->pos);
+ efl_event_callback_del(event->object, EFL_UI_DND_EVENT_DRAG_ACCEPT,
+ _dnd_drag_accept_cb, done->accept);
+ efl_event_callback_del(event->object, EFL_UI_DND_EVENT_DRAG_DONE,
+ _dnd_drag_done_cb, done);
+ free(done->pos);
+ free(done->accept);
+ free(done);
+}
+
+static void
+_dnd_drag_enter_leave_cb(void *data, const Efl_Event *event)
+{
+ Dnd_Drag_State *state = data;
+
+ if (state->state_cb)
+ state->state_cb(state->state_data, event->object);
+}
+
+static void
+_dnd_drop_cb(void *data, const Efl_Event *event)
+{
+ Dnd_Drop *drop = data;
+ Efl_Selection_Data *org_ddata = event->info;
+ Elm_Selection_Data ddata;
+
+ ddata.x = org_ddata->pos.x;
+ ddata.y = org_ddata->pos.y;
+ ddata.format = org_ddata->format;
+ ddata.action = org_ddata->action;
+ ddata.data = calloc(1, org_ddata->data.len);
+ if (!ddata.data) return;
+ ddata.data = memcpy(ddata.data, org_ddata->data.mem, org_ddata->data.len);
+ ddata.len = org_ddata->data.len;
+ if (drop->drop_cb)
+ drop->drop_cb(drop->drop_data, event->object, &ddata);
+ free(ddata.data);
+}
+
+EAPI Eina_Bool
+elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data,
+ Elm_Xdnd_Action action,
+ Elm_Drag_Icon_Create_Cb icon_create_cb, void *icon_create_data,
+ Elm_Drag_Pos drag_pos_cb, void *drag_pos_data,
+ Elm_Drag_Accept drag_accept_cb, void *drag_accept_data,
+ Elm_Drag_State drag_done_cb, void *drag_done_data)
+{
+ Eo *sel_man = _selection_manager_get(obj);
+ int seatid = 1;
+ Eina_Slice sl;
+ Dnd_Drag_Pos *pos = calloc(1, sizeof(Dnd_Drag_Pos));
+ Dnd_Drag_Accept *accept = calloc(1, sizeof(Dnd_Drag_Accept));
+ Dnd_Drag_Done *done = calloc(1, sizeof(Dnd_Drag_Done));
+ Dnd_Icon_Create *ic = calloc(1, sizeof(Dnd_Icon_Create));
+ if (!pos || !accept || !done || !ic) return EINA_FALSE;
+
+ pos->pos_data = drag_pos_data;
+ pos->pos_cb = drag_pos_cb;
+
+ accept->accept_data = drag_accept_data;
+ accept->accept_cb = drag_accept_cb;
+
+ done->done_data = drag_done_data;
+ done->done_cb = drag_done_cb;
+ done->pos = pos;
+ done->accept = accept;
+
+ efl_event_callback_add(obj, EFL_UI_DND_EVENT_DRAG_POS, _dnd_drag_pos_cb, pos);
+ efl_event_callback_add(obj, EFL_UI_DND_EVENT_DRAG_ACCEPT, _dnd_drag_accept_cb, accept);
+ efl_event_callback_add(obj, EFL_UI_DND_EVENT_DRAG_DONE, _dnd_drag_done_cb, done);
+ sl.mem = data;
+ sl.len = strlen(data);
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+
+ ic->icon_data = icon_create_data;
+ ic->icon_cb = icon_create_cb;
+ efl_selection_manager_drag_start(sel_man, obj, format, sl, action,
+ ic, _dnd_icon_create_cb, NULL, seatid);
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+elm_drag_action_set(Evas_Object *obj, Elm_Xdnd_Action action)
+{
+ Eo *sel_man = _selection_manager_get(obj);
+ int seatid = 1;
+
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+ efl_selection_manager_drag_action_set(sel_man, obj, action, seatid);
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+elm_drag_cancel(Evas_Object *obj)
+{
+ Eo *sel_man = _selection_manager_get(obj);
+ int seatid = 1;
+
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+
+ efl_selection_manager_drag_cancel(sel_man, obj, seatid);
+
+ return EINA_TRUE;
+}
+
+static void
+_drop_obj_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+ Eina_List *drop_list;
+ Dnd_Drop *drop;
+
+ drop_list = efl_key_data_get(obj, "__drop_list");
+ EINA_LIST_FREE(drop_list, drop)
+ {
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_ENTER,
+ _dnd_drag_enter_leave_cb, drop->enter);
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_LEAVE,
+ _dnd_drag_enter_leave_cb, drop->leave);
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_POS,
+ _dnd_drag_pos_cb, drop->pos);
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_DROP,
+ _dnd_drop_cb, drop);
+ free(drop->enter);
+ free(drop->leave);
+ free(drop->pos);
+ free(drop);
+ }
+}
+
+EAPI Eina_Bool
+elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format,
+ Elm_Drag_State enter_cb, void *enter_data,
+ Elm_Drag_State leave_cb, void *leave_data,
+ Elm_Drag_Pos pos_cb, void *pos_data,
+ Elm_Drop_Cb drop_cb, void *drop_data)
+{
+ Eo *sel_man = _selection_manager_get(obj);
+ int seatid = 1;
+ Dnd_Drag_State *enter, *leave;
+ Dnd_Drag_Pos *pos;
+ Dnd_Drop *drop;
+ Eina_List *drop_list;
+
+ enter = calloc(1, sizeof(Dnd_Drag_State));
+ leave = calloc(1, sizeof(Dnd_Drag_State));
+ pos = calloc(1, sizeof(Dnd_Drag_Pos));
+ drop = calloc(1, sizeof(Dnd_Drop));
+ if (!enter || !leave || !pos || !drop) return EINA_FALSE;
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+ enter->state_cb = enter_cb;
+ enter->state_data = enter_data;
+ leave->state_cb = leave_cb;
+ leave->state_data = leave_data;
+ pos->pos_cb = pos_cb;
+ pos->pos_data = pos_data;
+ drop->obj = obj;
+ drop->format = format;
+ drop->drop_cb = drop_cb;
+ drop->drop_data = drop_data;
+ drop->enter = enter;
+ drop->leave = leave;
+ drop->pos = pos;
+
+ drop_list = efl_key_data_get(obj, "__drop_list");
+ drop_list = eina_list_append(drop_list, drop);
+ efl_key_data_set(obj, "__drop_list", drop_list);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
+ _drop_obj_del_cb, NULL);
+ efl_event_callback_add(obj, EFL_UI_DND_EVENT_DRAG_ENTER,
+ _dnd_drag_enter_leave_cb, enter);
+ efl_event_callback_add(obj, EFL_UI_DND_EVENT_DRAG_LEAVE,
+ _dnd_drag_enter_leave_cb, leave);
+ efl_event_callback_add(obj, EFL_UI_DND_EVENT_DRAG_POS,
+ _dnd_drag_pos_cb, pos);
+ efl_event_callback_add(obj, EFL_UI_DND_EVENT_DRAG_DROP,
+ _dnd_drop_cb, drop);
+ efl_selection_manager_drop_target_add(sel_man, obj, format, seatid);
+
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+elm_drop_target_del(Evas_Object *obj, Elm_Sel_Format format,
+ Elm_Drag_State enter_cb, void *enter_data,
+ Elm_Drag_State leave_cb, void *leave_data,
+ Elm_Drag_Pos pos_cb, void *pos_data,
+ Elm_Drop_Cb drop_cb, void *drop_data)
+{
+ Eo *sel_man = _selection_manager_get(obj);
+ int seatid = 1;
+ //Eina_List *l, *l2;
+ Eina_List *drop_list;
+ Dnd_Drop *drop;
+
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+
+ drop_list = efl_key_data_get(obj, "__drop_list");
+ drop = eina_list_data_get(drop_list);
+ if (drop &&
+ (drop->format == drop->format) &&
+ (drop->enter->state_cb == enter_cb) &&
+ (drop->enter->state_data == enter_data) &&
+ (drop->leave->state_cb == leave_cb) &&
+ (drop->leave->state_data == leave_data) &&
+ (drop->pos->pos_cb == pos_cb) &&
+ (drop->pos->pos_data == pos_data) &&
+ (drop->drop_cb == drop_cb) &&
+ (drop->drop_data == drop_data))
+ {
+ drop_list = eina_list_remove(drop_list, drop);
+ efl_key_data_set(obj, "__drop_list", drop_list);
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _drop_obj_del_cb);
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_ENTER,
+ _dnd_drag_enter_leave_cb, drop->enter);
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_LEAVE,
+ _dnd_drag_enter_leave_cb, drop->leave);
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_POS,
+ _dnd_drag_pos_cb, drop->pos);
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_DROP,
+ _dnd_drop_cb, drop);
+ free(drop->enter);
+ free(drop->leave);
+ free(drop->pos);
+ free(drop);
+ }
+ efl_selection_manager_drop_target_del(sel_man, obj, format, seatid);
+
+ return EINA_TRUE;
+}
+
+static Efl_Object *
+_dnd_item_func(void *data, Efl_Canvas_Object *item, Eina_Position2D pos, Eina_Position2D *pos_ret)
+{
+ Elm_Xy_Item_Get_Cb item_get_cb = data;
+ Evas_Coord x, y;
+ Efl_Object *obj = NULL;
+
+ x = y = 0;
+ if (item_get_cb)
+ obj = item_get_cb(item, pos.x, pos.y, &x, &y);
+ if (pos_ret)
+ {
+ pos_ret->x = x;
+ pos_ret->y = y;
+ }
+
+ return obj;
+}
+
+static void
+_dnd_cont_drag_pos_cb(void *data, const Efl_Event *event)
+{
+ Dnd_Cont_Drag_Pos *pos = data;
+ Efl_Dnd_Drag_Pos *ddata = event->info;
+ Evas_Coord xret = 0, yret = 0;
+
+ if (pos->item_get_cb)
+ {
+ Evas_Coord x, y;
+ evas_object_geometry_get(event->object, &x, &y, NULL, NULL);
+ pos->item_get_cb(event->object, ddata->pos.x + x, ddata->pos.y + y,
+ &xret, &yret);
+ }
+ if (pos->pos_cb)
+ pos->pos_cb(pos->pos_data, event->object, ddata->item, ddata->pos.x, ddata->pos.y,
+ xret, yret, ddata->action);
+}
+
+static void
+_dnd_cont_drop_cb(void *data, const Efl_Event *event)
+{
+ Dnd_Cont_Drop *drop = data;
+ Efl_Selection_Data *org_ddata = event->info;
+ Elm_Selection_Data ddata;
+ Evas_Coord xret = 0, yret = 0;
+
+ ddata.x = org_ddata->pos.x;
+ ddata.y = org_ddata->pos.y;
+ ddata.format = org_ddata->format;
+ ddata.action = org_ddata->action;
+ ddata.data = calloc(1, org_ddata->data.len);
+ if (!ddata.data) return;
+ ddata.data = memcpy(ddata.data, org_ddata->data.mem, org_ddata->data.len);
+ ddata.len = org_ddata->data.len;
+
+ if (drop->item_get_cb)
+ {
+ Evas_Coord x, y;
+ evas_object_geometry_get(event->object, &x, &y, NULL, NULL);
+ drop->item_get_cb(event->object, ddata.x + x, ddata.y + y,
+ &xret, &yret);
+ }
+
+ if (drop->drop_cb)
+ drop->drop_cb(drop->drop_data, event->object, org_ddata->item,
+ &ddata, xret, yret);
+ free(ddata.data);
+}
+
+static void
+_cont_drop_free_data(Evas_Object *obj)
+{
+ Eina_List *cont_drop_list;
+ Dnd_Cont_Drop *drop;
+
+ cont_drop_list = efl_key_data_get(obj, "__cont_drop_item");
+ drop = eina_list_data_get(cont_drop_list);
+ if (drop)
+ {
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_ENTER,
+ _dnd_drag_enter_leave_cb, drop->enter);
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_LEAVE,
+ _dnd_drag_enter_leave_cb, drop->leave);
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_POS,
+ _dnd_cont_drag_pos_cb, drop->pos);
+ efl_event_callback_del(drop->obj, EFL_UI_DND_EVENT_DRAG_DROP,
+ _dnd_cont_drop_cb, drop);
+ free(drop->enter);
+ free(drop->leave);
+ free(drop->pos);
+ cont_drop_list = eina_list_remove(cont_drop_list, drop);
+ efl_key_data_set(obj, "__cont_drop_item", cont_drop_list);
+ free(drop);
+ }
+}
+
+static void
+_cont_drop_obj_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *info EINA_UNUSED)
+{
+ _cont_drop_free_data(obj);
+}
+
+EAPI Eina_Bool
+elm_drop_item_container_add(Evas_Object *obj,
+ Elm_Sel_Format format,
+ Elm_Xy_Item_Get_Cb item_get_cb,
+ Elm_Drag_State enter_cb, void *enter_data,
+ Elm_Drag_State leave_cb, void *leave_data,
+ Elm_Drag_Item_Container_Pos pos_cb, void *pos_data,
+ Elm_Drop_Item_Container_Cb drop_cb, void *drop_data)
+{
+ Eo *sel_man = _selection_manager_get(obj);
+ int seatid = 1;
+ Dnd_Drag_State *enter, *leave;
+ Dnd_Cont_Drag_Pos *pos;
+ Dnd_Cont_Drop *drop;
+ Eina_List *cont_drop_list;
+
+ enter = calloc(1, sizeof(Dnd_Drag_State));
+ leave = calloc(1, sizeof(Dnd_Drag_State));
+ pos = calloc(1, sizeof(Dnd_Cont_Drag_Pos));
+ drop = calloc(1, sizeof(Dnd_Cont_Drop));
+ if (!enter || !leave || !pos || !drop) return EINA_FALSE;
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+
+ enter->state_cb = enter_cb;
+ enter->state_data = enter_data;
+ leave->state_cb = leave_cb;
+ leave->state_data = leave_data;
+ pos->pos_cb = pos_cb;
+ pos->pos_data = pos_data;
+ pos->item_get_cb = item_get_cb;
+ drop->obj = obj;
+ drop->format = format;
+ drop->drop_cb = drop_cb;
+ drop->drop_data = drop_data;
+ drop->enter = enter;
+ drop->leave = leave;
+ drop->pos = pos;
+
+ cont_drop_list = efl_key_data_get(obj, "__cont_drop_item");
+ cont_drop_list = eina_list_append(cont_drop_list, drop);
+ efl_key_data_set(obj, "__cont_drop_item", cont_drop_list);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
+ _cont_drop_obj_del_cb, NULL);
+ efl_event_callback_add(obj, EFL_UI_DND_EVENT_DRAG_ENTER,
+ _dnd_drag_enter_leave_cb, enter);
+ efl_event_callback_add(obj, EFL_UI_DND_EVENT_DRAG_LEAVE,
+ _dnd_drag_enter_leave_cb, leave);
+ efl_event_callback_add(obj, EFL_UI_DND_EVENT_DRAG_POS,
+ _dnd_cont_drag_pos_cb, pos);
+ efl_event_callback_add(obj, EFL_UI_DND_EVENT_DRAG_DROP,
+ _dnd_cont_drop_cb, drop);
+ efl_selection_manager_container_drop_item_add(sel_man, obj, format,
+ item_get_cb, _dnd_item_func, NULL,
+ seatid);
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+elm_drop_item_container_del(Evas_Object *obj)
+{
+ Eo *sel_man = _selection_manager_get(obj);
+ int seatid = 1;
+
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+
+ _cont_drop_free_data(obj);
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _cont_drop_obj_del_cb);
+ efl_selection_manager_container_drop_item_del(sel_man, obj, seatid);
+
+ return EINA_TRUE;
+}
+
+static void
+_cont_drag_data_func(void *data, Efl_Object *obj, Efl_Selection_Format *format,
+ Eina_Rw_Slice *drag_data, Efl_Selection_Action *action)
+{
+ Item_Container_Drag_Info *di;
+
+ di = data;
+ if (!di) return;
+ di->data_get_cb(obj, di->it, &di->user_info);
+ if (format) *format = di->user_info.format;
+ if (drag_data)
+ {
+ if (di->user_info.data)
+ {
+ drag_data->mem = (void *)di->user_info.data;
+ drag_data->len = strlen(di->user_info.data);
+ }
+ }
+ if (action) *action = di->user_info.action;
+}
+
+static Eina_List *
+_cont_drag_icon_list_create(void *data, Efl_Object *obj EINA_UNUSED)
+{
+ Item_Container_Drag_Info *di;
+
+ di = data;
+ return di->user_info.icons;
+}
+
+static Efl_Object *
+_cont_drag_icon_create(void *data, Efl_Object *win, Efl_Object *drag_obj EINA_UNUSED, Eina_Position2D *pos_ret)
+{
+ Item_Container_Drag_Info *di;
+ Elm_Object_Item *it = NULL;
+
+ di = data;
+ if (!di) return NULL;
+ it = di->user_info.createicon(di->user_info.createdata, win, &pos_ret->x, &pos_ret->y);
+ di->it = it;
+ return it;
+}
+
+static Efl_Object *
+_cont_drag_item_func(void *data, Efl_Canvas_Object *item, Eina_Position2D pos, Eina_Position2D *pos_ret)
+{
+ Item_Container_Drag_Info *di = data;
+ Evas_Coord x, y;
+ Efl_Object *obj = NULL;
+
+ x = y = 0;
+ if (di->item_get_cb)
+ obj = di->item_get_cb(item, pos.x, pos.y, &x, &y);
+ if (pos_ret)
+ {
+ pos_ret->x = x;
+ pos_ret->y = y;
+ }
+ di->it = obj;
+
+ return obj;
+}
+
+static void
+_cont_drag_free_data(Evas_Object *obj)
+{
+ Eina_List *di_list;
+ Item_Container_Drag_Info *di;
+
+ di_list = efl_key_data_get(obj, "__cont_drag_item");
+ di = eina_list_data_get(di_list);
+ di_list = eina_list_remove(di_list, di);
+ efl_key_data_set(obj, "__cont_drag_item", di_list);
+ free(di);
+}
+
+static void
+_cont_drag_obj_del_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
+{
+ _cont_drag_free_data(obj);
+}
+
+EAPI Eina_Bool
+elm_drag_item_container_add(Evas_Object *obj, double anim_tm, double tm_to_drag,
+ Elm_Xy_Item_Get_Cb item_get_cb, Elm_Item_Container_Data_Get_Cb data_get_cb)
+{
+ Eo *sel_man = _selection_manager_get(obj);
+ int seatid = 1;
+ Eina_List *di_list;
+ Item_Container_Drag_Info *di;
+
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+
+ di = calloc(1, sizeof(Item_Container_Drag_Info));
+ if (!di) return EINA_FALSE;
+ di->data_get_cb = data_get_cb;
+ di->item_get_cb = item_get_cb;
+ di_list = efl_key_data_get(obj, "__cont_drag_item");
+ di_list = eina_list_append(di_list, di);
+ efl_key_data_set(obj, "__cont_drag_item", di_list);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _cont_drag_obj_del_cb, NULL);
+ efl_selection_manager_container_drag_item_add(sel_man, obj, anim_tm, tm_to_drag,
+ di, _cont_drag_data_func, NULL,
+ di, _cont_drag_item_func, NULL,
+ di, _cont_drag_icon_create, NULL,
+ di, _cont_drag_icon_list_create, NULL,
+ seatid);
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+elm_drag_item_container_del(Evas_Object *obj)
+{
+ Eo *sel_man = _selection_manager_get(obj);
+ int seatid = 1;
+
+#ifdef HAVE_ELEMENTARY_WL2
+ seatid = _wl_default_seat_id_get(obj);
+#endif
+
+ _cont_drag_free_data(obj);
+ evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL, _cont_drag_obj_del_cb);
+ efl_selection_manager_container_drag_item_del(sel_man, obj, seatid);
+
+ return EINA_TRUE;
+}
+
#include "efl_ui_dnd.eo.c"
#include "efl_ui_dnd_container.eo.c"
diff --git a/src/lib/elementary/elm_cnp.c b/src/lib/elementary/elm_cnp.c
deleted file mode 100644
index e7ac5cb625..0000000000
--- a/src/lib/elementary/elm_cnp.c
+++ /dev/null
@@ -1,5851 +0,0 @@
-#ifdef HAVE_CONFIG_H
-# include "elementary_config.h"
-#endif
-#include <Elementary.h>
-#include <Efreet.h>
-#include "elm_priv.h"
-#ifdef HAVE_MMAN_H
-# include <sys/mman.h>
-#endif
-
-//#define DEBUGON 1
-#ifdef DEBUGON
-# define cnp_debug(fmt, args...) fprintf(stderr, __FILE__":%s/%d : " fmt , __FUNCTION__, __LINE__, ##args)
-#else
-# define cnp_debug(x...) do { } while (0)
-#endif
-
-#define ARRAYINIT(foo) [foo] =
-
-EAPI int ELM_CNP_EVENT_SELECTION_CHANGED = -1;
-
-// common stuff
-enum
-{
- CNP_ATOM_TARGETS = 0,
- CNP_ATOM_ATOM,
- CNP_ATOM_LISTING_ATOMS = CNP_ATOM_ATOM,
- CNP_ATOM_text_urilist,
- CNP_ATOM_text_x_vcard,
- CNP_ATOM_image_png,
- CNP_ATOM_image_jpeg,
- CNP_ATOM_image_bmp,
- CNP_ATOM_image_gif,
- CNP_ATOM_image_tiff,
- CNP_ATOM_image_svg,
- CNP_ATOM_image_xpm,
- CNP_ATOM_image_tga,
- CNP_ATOM_image_ppm,
- CNP_ATOM_XELM,
-// CNP_ATOM_text_html_utf8,
-// CNP_ATOM_text_html,
- CNP_ATOM_UTF8STRING,
- CNP_ATOM_STRING,
- CNP_ATOM_COMPOUND_TEXT,
- CNP_ATOM_TEXT,
- CNP_ATOM_text_plain_utf8,
- CNP_ATOM_text_plain,
-
- CNP_N_ATOMS,
-};
-
-typedef struct _Tmp_Info Tmp_Info;
-typedef struct _Saved_Type Saved_Type;
-typedef struct _Cnp_Escape Cnp_Escape;
-typedef struct _Dropable Dropable;
-typedef struct _Dropable_Cbs Dropable_Cbs;
-static Eina_Bool doaccept = EINA_FALSE;
-
-struct _Tmp_Info
-{
- char *filename;
- void *map;
- int fd;
- int len;
-};
-
-struct _Saved_Type
-{
- const char **types;
- char *imgfile;
- int ntypes;
- int x, y;
- Eina_Bool textreq: 1;
-};
-
-struct _Cnp_Escape
-{
- const char *escape;
- const char *value;
-};
-
-struct _Dropable_Cbs
-{
- EINA_INLIST;
- Elm_Sel_Format types;
- Elm_Drag_State entercb;
- Elm_Drag_State leavecb;
- Elm_Drag_Pos poscb;
- Elm_Drop_Cb dropcb;
- void *enterdata;
- void *leavedata;
- void *posdata;
- void *dropdata;
-};
-
-struct _Dropable
-{
- Evas_Object *obj;
- /* FIXME: Cache window */
- Eina_Inlist *cbs_list; /* List of Dropable_Cbs * */
- struct {
- Evas_Coord x, y;
- Eina_Bool in : 1;
- const char *type;
- Elm_Sel_Format format;
- } last;
-};
-
-struct _Item_Container_Drop_Info
-{ /* Info kept for containers to support drop */
- Evas_Object *obj;
- Elm_Xy_Item_Get_Cb itemgetcb;
- Elm_Drop_Item_Container_Cb dropcb;
- Elm_Drag_Item_Container_Pos poscb;
-};
-typedef struct _Item_Container_Drop_Info Item_Container_Drop_Info;
-
-struct _Anim_Icon
-{
- int start_x;
- int start_y;
- int start_w;
- int start_h;
- Evas_Object *o;
-};
-typedef struct _Anim_Icon Anim_Icon;
-
-struct _Item_Container_Drag_Info
-{ /* Info kept for containers to support drag */
- Evas_Object *obj;
- Ecore_Timer *tm; /* When this expires, start drag */
- double anim_tm; /* Time period to set tm */
- double tm_to_drag; /* Time period to set tm */
- Elm_Xy_Item_Get_Cb itemgetcb;
- Elm_Item_Container_Data_Get_Cb data_get;
-
- Evas_Coord x_down; /* Mouse down x cord when drag starts */
- Evas_Coord y_down; /* Mouse down y cord when drag starts */
-
- /* Some extra information needed to impl default anim */
- Evas *e;
- Eina_List *icons; /* List of icons to animate (Anim_Icon) */
- int final_icon_w; /* We need the w and h of the final icon for the animation */
- int final_icon_h;
- Ecore_Animator *ea;
-
- Elm_Drag_User_Info user_info;
-};
-typedef struct _Item_Container_Drag_Info Item_Container_Drag_Info;
-
-typedef struct _Cnp_Atom Cnp_Atom;
-
-static int _elm_cnp_init_count = 0;
-/* Stringshared, so I can just compare pointers later */
-static const char *text_uri;
-
-/* Hash table type->Elm_Sel_Format */
-static Eina_Hash *_types_hash = NULL;
-
-/* Data for DND in progress */
-static Saved_Type savedtypes = { NULL, NULL, 0, 0, 0, EINA_FALSE };
-
-/* Drag & Drop functions */
-/* FIXME: Way too many globals */
-static Eina_List *drops = NULL;
-static Evas_Object *dragwin = NULL;
-static int dragwin_x_start, dragwin_y_start;
-static int dragwin_x_end, dragwin_y_end;
-static int _dragx = 0, _dragy = 0;
-static Ecore_Event_Handler *handler_pos = NULL;
-static Ecore_Event_Handler *handler_drop = NULL;
-static Ecore_Event_Handler *handler_enter = NULL;
-static Ecore_Event_Handler *handler_leave = NULL;
-#ifdef HAVE_ELEMENTARY_X
-static Ecore_Event_Handler *handler_status = NULL;
-static Ecore_Event_Handler *handler_up = NULL;
-#endif
-
-/* TODO BUG: should NEVER have these as globals! They should be per context (window). */
-static Elm_Drag_Pos dragposcb = NULL;
-static Elm_Drag_Accept dragacceptcb = NULL;
-static Elm_Drag_State dragdonecb = NULL;
-static void *dragposdata = NULL;
-static void *dragacceptdata = NULL;
-static void *dragdonedata = NULL;
-static Evas_Object *dragwidget = NULL;
-static Elm_Xdnd_Action dragaction = ELM_XDND_ACTION_UNKNOWN;
-
-static Eina_List *cont_drop_tg = NULL; /* List of Item_Container_Drop_Info */
-static Eina_List *cont_drag_tg = NULL; /* List of Item_Container_Drag_Info */
-
-static void _cont_obj_mouse_up( void *data, Evas *e, Evas_Object *obj, void *event_info);
-static void _cont_obj_mouse_move( void *data, Evas *e, Evas_Object *obj, void *event_info);
-static void _all_drop_targets_cbs_del(void *data, Evas *e, Evas_Object *obj, void *info);
-static Eina_Bool _elm_cnp_shutdown(void);
-static Eina_Bool _local_elm_drop_target_del(Evas_Object *obj, Elm_Sel_Format format,
- Elm_Drag_State entercb, void *enterdata,
- Elm_Drag_State leavecb, void *leavedata,
- Elm_Drag_Pos poscb, void *posdata,
- Elm_Drop_Cb dropcb, void *dropdata);
-
-static Tmp_Info *_tempfile_new (int size);
-static int _tmpinfo_free (Tmp_Info *tmp);
-
-static Eina_Bool _local_elm_cnp_selection_get(const Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format, Elm_Drop_Cb datacb, void *udata);
-static Eina_Bool _local_elm_object_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type selection);
-static Eina_Bool _local_elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format, const void *selbuf, size_t buflen);
-#ifdef HAVE_ELEMENTARY_X
-static Ecore_X_Window _x11_elm_widget_xwin_get(const Evas_Object *obj);
-
-typedef struct _X11_Cnp_Selection X11_Cnp_Selection;
-
-typedef Eina_Bool (*X11_Converter_Fn_Cb) (char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize);
-typedef int (*X11_Response_Handler_Cb) (X11_Cnp_Selection *sel, Ecore_X_Event_Selection_Notify *);
-typedef Eina_Bool (*X11_Data_Preparer_Cb) (Ecore_X_Event_Selection_Notify *, Elm_Selection_Data *, Tmp_Info **);
-
-static void _x11_sel_obj_del (void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED);
-static void _x11_sel_obj_del2 (void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED);
-static Eina_Bool _x11_selection_clear (void *udata EINA_UNUSED, int type, void *event);
-static Eina_Bool _x11_selection_notify (void *udata EINA_UNUSED, int type, void *event);
-static Eina_Bool _x11_targets_converter (char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize);
-static Eina_Bool _x11_text_converter (char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize);
-static Eina_Bool _x11_general_converter (char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize);
-static Eina_Bool _x11_image_converter (char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize);
-static Eina_Bool _x11_vcard_send (char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize);
-static Eina_Bool _x11_is_uri_type_data (X11_Cnp_Selection *sel EINA_UNUSED, Ecore_X_Event_Selection_Notify *notify);
-static Eina_Bool _x11_notify_handler_targets (X11_Cnp_Selection *sel, Ecore_X_Event_Selection_Notify *notify);
-static Eina_Bool _x11_data_preparer_text (Ecore_X_Event_Selection_Notify *notify, Elm_Selection_Data *ddata, Tmp_Info **tmp_info);
-static Eina_Bool _x11_data_preparer_markup (Ecore_X_Event_Selection_Notify *notify, Elm_Selection_Data *ddata, Tmp_Info **tmp_info);
-static Eina_Bool _x11_data_preparer_image (Ecore_X_Event_Selection_Notify *notify, Elm_Selection_Data *ddata, Tmp_Info **tmp_info);
-static Eina_Bool _x11_data_preparer_uri (Ecore_X_Event_Selection_Notify *notify, Elm_Selection_Data *ddata, Tmp_Info **tmp_info);
-//static int _x11_notify_handler_html (X11_Cnp_Selection *sel, Ecore_X_Event_Selection_Notify *notify);
-static Eina_Bool _x11_data_preparer_vcard (Ecore_X_Event_Selection_Notify *notify, Elm_Selection_Data *ddata, Tmp_Info **tmp_info);
-static Eina_Bool _x11_dnd_enter (void *data EINA_UNUSED, int etype EINA_UNUSED, void *ev);
-static Eina_Bool _x11_dnd_drop (void *data EINA_UNUSED, int etype EINA_UNUSED, void *ev);
-static Eina_Bool _x11_dnd_position (void *data EINA_UNUSED, int etype EINA_UNUSED, void *ev);
-static Eina_Bool _x11_dnd_status (void *data EINA_UNUSED, int etype EINA_UNUSED, void *ev);
-static Eina_Bool _x11_dnd_leave (void *data EINA_UNUSED, int etype EINA_UNUSED, void *ev);
-static Eina_Bool _x11_drag_mouse_up (void *data, int etype EINA_UNUSED, void *event);
-static void _x11_drag_move (void *data EINA_UNUSED, Ecore_X_Xdnd_Position *pos);
-
-static Eina_Bool _x11_elm_cnp_init (void);
-static Eina_Bool _x11_elm_cnp_selection_set (Ecore_X_Window xwin, Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format, const void *selbuf, size_t buflen);
-static void _x11_elm_cnp_selection_loss_callback_set(Evas_Object *obj EINA_UNUSED, Elm_Sel_Type selection, Elm_Selection_Loss_Cb func, const void *data);
-static Eina_Bool _x11_elm_object_cnp_selection_clear (Evas_Object *obj, Elm_Sel_Type selection);
-static Eina_Bool _x11_elm_cnp_selection_get (Ecore_X_Window xwin, const Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format, Elm_Drop_Cb datacb, void *udata);
-static Eina_Bool _x11_elm_drop_target_add (Evas_Object *obj, Elm_Sel_Format format,
- Elm_Drag_State entercb, void *enterdata,
- Elm_Drag_State leavecb, void *leavedata,
- Elm_Drag_Pos poscb, void *posdata,
- Elm_Drop_Cb dropcb, void *dropdata);
-static Eina_Bool _x11_elm_drop_target_del (Evas_Object *obj, Elm_Sel_Format format,
- Elm_Drag_State entercb, void *enterdata,
- Elm_Drag_State leavecb, void *leavedata,
- Elm_Drag_Pos poscb, void *posdata,
- Elm_Drop_Cb dropcb, void *dropdata);
-static Eina_Bool _x11_elm_selection_selection_has_owner (Evas_Object *obj EINA_UNUSED);
-
-#endif
-
-#ifdef HAVE_ELEMENTARY_WL2
-typedef struct _Wl_Cnp_Selection Wl_Cnp_Selection;
-
-typedef Eina_Bool (*Wl_Converter_Fn_Cb) (char *target, Wl_Cnp_Selection *sel, void *data, int size, void **data_ret, int *size_ret);
-static Eina_Bool _wl_targets_converter(char *target, Wl_Cnp_Selection *sel, void *data, int size, void **data_ret, int *size_ret);
-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_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
-{
- const char *name;
- Elm_Sel_Format formats;
-#ifdef HAVE_ELEMENTARY_X
- /* Called by ecore to do conversion */
- X11_Converter_Fn_Cb x_converter;
- X11_Data_Preparer_Cb x_data_preparer;
- /* Atom */
- Ecore_X_Atom x_atom;
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- Wl_Converter_Fn_Cb wl_converter;
- Wl_Data_Preparer_Cb wl_data_preparer;
-#endif
-
- void *_term;
-};
-
-static Eina_List *
-_dropable_list_geom_find(Evas *evas, Evas_Coord px, Evas_Coord py)
-{
- Eina_List *itr, *top_objects_list = NULL, *dropable_list = NULL;
- Evas_Object *top_obj;
- Dropable *dropable = NULL;
-
- if (!drops) return NULL;
-
- /* We retrieve the (non-smart) objects pointed by (px, py) */
- top_objects_list = evas_tree_objects_at_xy_get(evas, NULL, px, py);
- /* We walk on this list from the last because if the list contains more than one
- * element, all but the last will repeat events. The last one can repeat events
- * or not. Anyway, this last one is the first that has to be taken into account
- * for the determination of the drop target.
- */
- EINA_LIST_REVERSE_FOREACH(top_objects_list, itr, top_obj)
- {
- Evas_Object *object = top_obj;
- /* We search for the dropable data into the object. If not found, we search into its parent.
- * For example, if a button is a drop target, the first object will be an (internal) image.
- * The drop target is attached to the button, i.e to image's parent. That's why we need to
- * walk on the parents until NULL.
- * If we find this dropable data, we found our drop target.
- */
- while (object)
- {
- dropable = efl_key_data_get(object, "__elm_dropable");
- if (dropable)
- {
- Eina_Bool exist = EINA_FALSE;
- Eina_List *l;
- Dropable *d = NULL;
- EINA_LIST_FOREACH(dropable_list, l, d)
- {
- if (d == dropable)
- {
- exist = EINA_TRUE;
- break;
- }
- }
- if (!exist)
- dropable_list = eina_list_append(dropable_list, dropable);
- object = evas_object_smart_parent_get(object);
- if (dropable)
- cnp_debug("Drop target %p of type %s found\n",
- dropable->obj, efl_class_name_get(efl_class_get(dropable->obj)));
- }
- else
- object = evas_object_smart_parent_get(object);
- }
- }
- eina_list_free(top_objects_list);
- return dropable_list;
-}
-
-static void
-_dropable_coords_adjust(Dropable *dropable, Evas_Coord *x, Evas_Coord *y)
-{
- Ecore_Evas *ee;
- Evas *evas = evas_object_evas_get(dropable->obj);
- int ex = 0, ey = 0, ew = 0, eh = 0;
- Evas_Object *win;
-
- ee = ecore_evas_ecore_evas_get(evas);
- ecore_evas_geometry_get(ee, &ex, &ey, &ew, &eh);
- *x = *x - ex;
- *y = *y - ey;
-
- /* For Wayland, frame coords have to be subtracted. */
- Evas_Coord fx, fy;
- evas_output_framespace_get(evas, &fx, &fy, NULL, NULL);
- if (fx || fy) cnp_debug("evas frame fx %d fy %d\n", fx, fy);
- *x = *x - fx;
- *y = *y - fy;
-
- if (elm_widget_is(dropable->obj))
- {
- win = elm_widget_top_get(dropable->obj);
- if (win && efl_isa(win, EFL_UI_WIN_CLASS))
- {
- Evas_Coord x2, y2;
- int rot = elm_win_rotation_get(win);
- switch (rot)
- {
- case 90:
- x2 = ew - *y;
- y2 = *x;
- break;
- case 180:
- x2 = ew - *x;
- y2 = eh - *y;
- break;
- case 270:
- x2 = *y;
- y2 = eh - *x;
- break;
- default:
- x2 = *x;
- y2 = *y;
- break;
- }
- cnp_debug("rotation %d, w %d, h %d - x:%d->%d, y:%d->%d\n",
- rot, ew, eh, *x, x2, *y, y2);
- *x = x2;
- *y = y2;
- }
- }
-}
-
-static Elm_Sel_Format
-_dnd_types_to_format(const char **types, int ntypes)
-{
- Elm_Sel_Format ret_type = 0;
- int i;
- for (i = 0; i < ntypes; i++)
- {
- Cnp_Atom *atom = eina_hash_find(_types_hash, types[i]);
- if (atom) ret_type |= atom->formats;
- }
- return ret_type;
-}
-
-static Eina_Bool
-_drag_cancel_animate(void *data, double pos)
-{ /* Animation to "move back" drag-window */
- if (pos >= 0.99)
- {
-#ifdef HAVE_ELEMENTARY_X
- Ecore_X_Window xdragwin = _x11_elm_widget_xwin_get(data);
- ecore_x_window_ignore_set(xdragwin, 0);
-#endif
- evas_object_del(data);
- return ECORE_CALLBACK_CANCEL;
- }
- else
- {
- int x, y;
- x = dragwin_x_end - (pos * (dragwin_x_end - dragwin_x_start));
- y = dragwin_y_end - (pos * (dragwin_y_end - dragwin_y_start));
- evas_object_move(data, x, y);
- }
-
- return ECORE_CALLBACK_RENEW;
-}
-
-static void
-_all_drop_targets_cbs_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *info EINA_UNUSED)
-{
- Dropable *dropable = NULL;
- dropable = efl_key_data_get(obj, "__elm_dropable");
- if (dropable)
- {
- Dropable_Cbs *cbs;
- while (dropable->cbs_list)
- {
- cbs = EINA_INLIST_CONTAINER_GET(dropable->cbs_list, Dropable_Cbs);
- elm_drop_target_del(obj, cbs->types,
- cbs->entercb, cbs->enterdata, cbs->leavecb, cbs->leavedata,
- cbs->poscb, cbs->posdata, cbs->dropcb, cbs->dropdata);
- // If elm_drop_target_del() happened to delete dropabale, then
- // re-fetch it each loop to make sure it didn't
- dropable = efl_key_data_get(obj, "__elm_dropable");
- if (!dropable) break;
- }
- }
-}
-
-static Cnp_Atom _atoms[CNP_N_ATOMS] = {
- ARRAYINIT(CNP_ATOM_TARGETS) {
- .name = "TARGETS",
- .formats = ELM_SEL_FORMAT_TARGETS,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_targets_converter,
-
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_targets_converter,
-#endif
- },
- ARRAYINIT(CNP_ATOM_ATOM) {
- .name = "ATOM", // for opera browser
- .formats = ELM_SEL_FORMAT_TARGETS,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_targets_converter,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_targets_converter,
-#endif
- },
- ARRAYINIT(CNP_ATOM_XELM) {
- .name = "application/x-elementary-markup",
- .formats = ELM_SEL_FORMAT_MARKUP,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_general_converter,
- .x_data_preparer = _x11_data_preparer_markup,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_general_converter,
- .wl_data_preparer = _wl_data_preparer_markup,
-#endif
- },
- ARRAYINIT(CNP_ATOM_text_urilist) {
- .name = "text/uri-list",
- .formats = ELM_SEL_FORMAT_IMAGE,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_general_converter,
- .x_data_preparer = _x11_data_preparer_uri,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_general_converter,
- .wl_data_preparer = _wl_data_preparer_uri,
-#endif
- },
- ARRAYINIT(CNP_ATOM_text_x_vcard) {
- .name = "text/x-vcard",
- .formats = ELM_SEL_FORMAT_VCARD,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_vcard_send,
- .x_data_preparer = _x11_data_preparer_vcard,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_data_preparer = _wl_data_preparer_vcard,
-#endif
- },
- ARRAYINIT(CNP_ATOM_image_png) {
- .name = "image/png",
- .formats = ELM_SEL_FORMAT_IMAGE,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_image_converter,
- .x_data_preparer = _x11_data_preparer_image,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_data_preparer = _wl_data_preparer_image,
-#endif
- },
- ARRAYINIT(CNP_ATOM_image_jpeg) {
- .name = "image/jpeg",
- .formats = ELM_SEL_FORMAT_IMAGE,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_image_converter,
- .x_data_preparer = _x11_data_preparer_image,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_data_preparer = _wl_data_preparer_image,
-#endif
- },
- ARRAYINIT(CNP_ATOM_image_bmp) {
- .name = "image/x-ms-bmp",
- .formats = ELM_SEL_FORMAT_IMAGE,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_image_converter,
- .x_data_preparer = _x11_data_preparer_image,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_data_preparer = _wl_data_preparer_image,
-#endif
- },
- ARRAYINIT(CNP_ATOM_image_gif) {
- .name = "image/gif",
- .formats = ELM_SEL_FORMAT_IMAGE,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_image_converter,
- .x_data_preparer = _x11_data_preparer_image,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_data_preparer = _wl_data_preparer_image,
-#endif
- },
- ARRAYINIT(CNP_ATOM_image_tiff) {
- .name = "image/tiff",
- .formats = ELM_SEL_FORMAT_IMAGE,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_image_converter,
- .x_data_preparer = _x11_data_preparer_image,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_data_preparer = _wl_data_preparer_image,
-#endif
- },
- ARRAYINIT(CNP_ATOM_image_svg) {
- .name = "image/svg+xml",
- .formats = ELM_SEL_FORMAT_IMAGE,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_image_converter,
- .x_data_preparer = _x11_data_preparer_image,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_data_preparer = _wl_data_preparer_image,
-#endif
- },
- ARRAYINIT(CNP_ATOM_image_xpm) {
- .name = "image/x-xpixmap",
- .formats = ELM_SEL_FORMAT_IMAGE,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_image_converter,
- .x_data_preparer = _x11_data_preparer_image,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_data_preparer = _wl_data_preparer_image,
-#endif
- },
- ARRAYINIT(CNP_ATOM_image_tga) {
- .name = "image/x-tga",
- .formats = ELM_SEL_FORMAT_IMAGE,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_image_converter,
- .x_data_preparer = _x11_data_preparer_image,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_data_preparer = _wl_data_preparer_image,
-#endif
- },
- ARRAYINIT(CNP_ATOM_image_ppm) {
- .name = "image/x-portable-pixmap",
- .formats = ELM_SEL_FORMAT_IMAGE,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_image_converter,
- .x_data_preparer = _x11_data_preparer_image,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_data_preparer = _wl_data_preparer_image,
-#endif
- },
-/*
- ARRAYINIT(CNP_ATOM_text_html_utf8) {
- .name = "text/html;charset=utf-8",
- .formats = ELM_SEL_FORMAT_HTML,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_general_converter,
- .x_notify = _x11_notify_handler_html,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_general_converter,
- .wl_data_preparer = _wl_data_preparer_handler_html,
-#endif
-
- },
- ARRAYINIT(CNP_ATOM_text_html) {
- .name = "text/html",
- .formats = ELM_SEL_FORMAT_HTML,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_general_converter,
- .x_notify = _x11_notify_handler_html,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_general_converter,
- .wl_data_preparer = _wl_data_preparer_handler_html,
-#endif
- },
- */
- ARRAYINIT(CNP_ATOM_UTF8STRING) {
- .name = "UTF8_STRING",
- .formats = ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_text_converter,
- .x_data_preparer = _x11_data_preparer_text,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_text_converter,
- .wl_data_preparer = _wl_data_preparer_text,
-#endif
- },
- ARRAYINIT(CNP_ATOM_STRING) {
- .name = "STRING",
- .formats = ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_text_converter,
- .x_data_preparer = _x11_data_preparer_text,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_text_converter,
- .wl_data_preparer = _wl_data_preparer_text,
-#endif
- },
- ARRAYINIT(CNP_ATOM_COMPOUND_TEXT) {
- .name = "COMPOUND_TEXT",
- .formats = ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_text_converter,
- .x_data_preparer = _x11_data_preparer_text,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_text_converter,
- .wl_data_preparer = _wl_data_preparer_text,
-#endif
- },
- ARRAYINIT(CNP_ATOM_TEXT) {
- .name = "TEXT",
- .formats = ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_text_converter,
- .x_data_preparer = _x11_data_preparer_text,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_text_converter,
- .wl_data_preparer = _wl_data_preparer_text,
-#endif
- },
- ARRAYINIT(CNP_ATOM_text_plain_utf8) {
- .name = "text/plain;charset=utf-8",
- .formats = ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_text_converter,
- .x_data_preparer = _x11_data_preparer_text,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_text_converter,
- .wl_data_preparer = _wl_data_preparer_text,
-#endif
- },
- ARRAYINIT(CNP_ATOM_text_plain) {
- .name = "text/plain",
- .formats = ELM_SEL_FORMAT_TEXT | ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_HTML,
-#ifdef HAVE_ELEMENTARY_X
- .x_converter = _x11_text_converter,
- .x_data_preparer = _x11_data_preparer_text,
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- .wl_converter = _wl_text_converter,
- .wl_data_preparer = _wl_data_preparer_text,
-#endif
- },
-};
-
-// x11 specific stuff
-////////////////////////////////////////////////////////////////////////////
-#ifdef HAVE_ELEMENTARY_X
-#define ARRAYINIT(foo) [foo] =
-struct _X11_Cnp_Selection
-{
- const char *debug;
- Evas_Object *widget;
- char *selbuf;
- Evas_Object *requestwidget;
- void *udata;
- Elm_Sel_Format requestformat;
- Elm_Drop_Cb datacb;
- Eina_Bool (*set) (Ecore_X_Window, const void *data, int size);
- Eina_Bool (*clear) (void);
- void (*request) (Ecore_X_Window, const char *target);
- Elm_Selection_Loss_Cb loss_cb;
- void *loss_data;
-
- Elm_Sel_Format format;
- Ecore_X_Selection ecore_sel;
- Ecore_X_Window xwin;
- Elm_Xdnd_Action action;
-
- Eina_Bool active : 1;
-};
-
-static X11_Cnp_Selection _x11_selections[ELM_SEL_TYPE_CLIPBOARD + 1] = {
- ARRAYINIT(ELM_SEL_TYPE_PRIMARY) {
- .debug = "Primary",
- .ecore_sel = ECORE_X_SELECTION_PRIMARY,
- .set = ecore_x_selection_primary_set,
- .clear = ecore_x_selection_primary_clear,
- .request = ecore_x_selection_primary_request,
- },
- ARRAYINIT(ELM_SEL_TYPE_SECONDARY) {
- .debug = "Secondary",
- .ecore_sel = ECORE_X_SELECTION_SECONDARY,
- .set = ecore_x_selection_secondary_set,
- .clear = ecore_x_selection_secondary_clear,
- .request = ecore_x_selection_secondary_request,
- },
- ARRAYINIT(ELM_SEL_TYPE_XDND) {
- .debug = "XDnD",
- .ecore_sel = ECORE_X_SELECTION_XDND,
- .request = ecore_x_selection_xdnd_request,
- },
- ARRAYINIT(ELM_SEL_TYPE_CLIPBOARD) {
- .debug = "Clipboard",
- .ecore_sel = ECORE_X_SELECTION_CLIPBOARD,
- .set = ecore_x_selection_clipboard_set,
- .clear = ecore_x_selection_clipboard_clear,
- .request = ecore_x_selection_clipboard_request,
- },
-};
-
-static void
-_x11_sel_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
-{
- X11_Cnp_Selection *sel = data;
- if (sel->widget == obj)
- {
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
- sel->widget = NULL;
- }
- if (dragwidget == obj) dragwidget = NULL;
-}
-
-static void
-_x11_sel_obj_del2(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
-{
- X11_Cnp_Selection *sel = data;
- if (sel->requestwidget == obj) sel->requestwidget = NULL;
-}
-
-static Eina_Bool
-_x11_selection_clear(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event)
-{
- Ecore_X_Event_Selection_Clear *ev = event;
- X11_Cnp_Selection *sel;
- unsigned int i;
-
- _x11_elm_cnp_init();
- for (i = ELM_SEL_TYPE_PRIMARY; i <= ELM_SEL_TYPE_CLIPBOARD; i++)
- {
- if (_x11_selections[i].ecore_sel == ev->selection) break;
- }
- cnp_debug("selection %d clear\n", i);
- /* Not me... Don't care */
- if (i > ELM_SEL_TYPE_CLIPBOARD) return ECORE_CALLBACK_PASS_ON;
-
- sel = _x11_selections + i;
- if (sel->loss_cb) sel->loss_cb(sel->loss_data, i);
- if (sel->widget)
- evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
- _x11_sel_obj_del, sel);
- if (sel->requestwidget)
- evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
- _x11_sel_obj_del2, sel);
- sel->widget = NULL;
- sel->requestwidget = NULL;
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
-
- sel->active = EINA_FALSE;
- ELM_SAFE_FREE(sel->selbuf, free);
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_x11_fixes_selection_notify(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
-{
- Elm_Cnp_Event_Selection_Changed *e;
- Ecore_X_Event_Fixes_Selection_Notify *ev = event;
- Elm_Sel_Type type;
- X11_Cnp_Selection *sel;
-
- switch (ev->selection)
- {
- case ECORE_X_SELECTION_CLIPBOARD:
- type = ELM_SEL_TYPE_CLIPBOARD;
- break;
- case ECORE_X_SELECTION_PRIMARY:
- type = ELM_SEL_TYPE_PRIMARY;
- break;
- default: return ECORE_CALLBACK_RENEW;
- }
- sel = _x11_selections + type;
- if (sel->active && (sel->xwin != ev->owner))
- _x11_elm_object_cnp_selection_clear(sel->widget, type);
- e = calloc(1, sizeof(Elm_Cnp_Event_Selection_Changed));
- EINA_SAFETY_ON_NULL_RETURN_VAL(e, ECORE_CALLBACK_RENEW);
- e->type = type;
- e->seat_id = 1; /* under x11 this is always the default seat */
- e->exists = !!ev->owner;
- ecore_event_add(ELM_CNP_EVENT_SELECTION_CHANGED, e, NULL, NULL);
- return ECORE_CALLBACK_RENEW;
-}
-
-/*
- * Response to a selection notify:
- * - So we have asked for the selection list.
- * - If it's the targets list, parse it, and fire of what we want,
- * else it's the data we want.
- */
-static Eina_Bool
-_x11_selection_notify(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event)
-{
- Ecore_X_Event_Selection_Notify *ev = event;
- X11_Cnp_Selection *sel;
- int i;
-
- cnp_debug("selection notify callback: %d\n",ev->selection);
- switch (ev->selection)
- {
- case ECORE_X_SELECTION_PRIMARY:
- sel = _x11_selections + ELM_SEL_TYPE_PRIMARY;
- break;
- case ECORE_X_SELECTION_SECONDARY:
- sel = _x11_selections + ELM_SEL_TYPE_SECONDARY;
- break;
- case ECORE_X_SELECTION_XDND:
- sel = _x11_selections + ELM_SEL_TYPE_XDND;
- break;
- case ECORE_X_SELECTION_CLIPBOARD:
- sel = _x11_selections + ELM_SEL_TYPE_CLIPBOARD;
- break;
- default:
- return ECORE_CALLBACK_PASS_ON;
- }
- cnp_debug("Target is %s\n", ev->target);
-
- if (ev->selection != ECORE_X_SELECTION_XDND &&
- (!strcmp(ev->target, "TARGETS") || !strcmp(ev->target, "ATOMS")))
- {
- _x11_notify_handler_targets(sel, ev);
- return ECORE_CALLBACK_PASS_ON;
- }
- for (i = 0; i < CNP_N_ATOMS; i++)
- {
- if (!strcmp(ev->target, _atoms[i].name))
- {
- if (_atoms[i].x_data_preparer)
- {
- Elm_Selection_Data ddata;
- Tmp_Info *tmp_info = NULL;
- Eina_Bool success;
- ddata.data = NULL;
- cnp_debug("Found something: %s\n", _atoms[i].name);
- success = _atoms[i].x_data_preparer(ev, &ddata, &tmp_info);
- if (_atoms[i].formats == ELM_SEL_FORMAT_IMAGE && savedtypes.imgfile) break;
- if (ev->selection == ECORE_X_SELECTION_XDND)
- {
- if (success)
- {
- Dropable *dropable;
- Eina_List *l;
- cnp_debug("drag & drop\n");
- EINA_LIST_FOREACH(drops, l, dropable)
- {
- if (dropable->obj == sel->requestwidget) break;
- dropable = NULL;
- }
- if (dropable)
- {
- Dropable_Cbs *cbs;
- Eina_Inlist *itr;
- ddata.x = savedtypes.x;
- ddata.y = savedtypes.y;
- EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
- if ((cbs->types & dropable->last.format) && cbs->dropcb)
- cbs->dropcb(cbs->dropdata, dropable->obj, &ddata);
- }
- }
- /* We have to finish DnD, no matter what */
- ecore_x_dnd_send_finished();
- }
- else if (sel->datacb && success)
- {
- ddata.x = ddata.y = 0;
- sel->datacb(sel->udata, sel->requestwidget, &ddata);
- }
- free(ddata.data);
- if (tmp_info) _tmpinfo_free(tmp_info);
- }
- else cnp_debug("Ignored: No handler!\n");
- break;
- }
- }
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Elm_Sel_Format
-_get_selection_type(void *data, int size)
-{
- if (size == sizeof(Elm_Sel_Type))
- {
- unsigned int seltype = *((unsigned int *)data);
- if (seltype > ELM_SEL_TYPE_CLIPBOARD)
- return ELM_SEL_FORMAT_NONE;
- X11_Cnp_Selection *sel = _x11_selections + seltype;
- if (sel->active &&
- (sel->format >= ELM_SEL_FORMAT_TARGETS) &&
- (sel->format <= ELM_SEL_FORMAT_HTML))
- return sel->format;
- }
- return ELM_SEL_FORMAT_NONE;
-}
-
-static Eina_Bool
-_x11_targets_converter(char *target EINA_UNUSED, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize)
-{
- int i, count;
- Ecore_X_Atom *aret;
- X11_Cnp_Selection *sel;
- Elm_Sel_Format seltype;
-
- if (!data_ret) return EINA_FALSE;
- if (_get_selection_type(data, size) == ELM_SEL_FORMAT_NONE)
- {
- /* TODO : fallback into precise type */
- seltype = ELM_SEL_FORMAT_TEXT;
- }
- else
- {
- sel = _x11_selections + *((int *)data);
- seltype = sel->format;
- }
-
- for (i = CNP_ATOM_LISTING_ATOMS + 1, count = 0; i < CNP_N_ATOMS ; i++)
- {
- if (seltype & _atoms[i].formats) count++;
- }
- aret = malloc(sizeof(Ecore_X_Atom) * count);
- if (!aret) return EINA_FALSE;
- for (i = CNP_ATOM_LISTING_ATOMS + 1, count = 0; i < CNP_N_ATOMS ; i++)
- {
- if (seltype & _atoms[i].formats)
- aret[count ++] = _atoms[i].x_atom;
- }
-
- *data_ret = aret;
- if (typesize) *typesize = 32 /* urk */;
- if (ttype) *ttype = ECORE_X_ATOM_ATOM;
- if (size_ret) *size_ret = count;
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_image_converter(char *target EINA_UNUSED, void *data EINA_UNUSED, int size EINA_UNUSED, void **data_ret EINA_UNUSED, int *size_ret EINA_UNUSED, Ecore_X_Atom *ttype EINA_UNUSED, int *typesize EINA_UNUSED)
-{
- cnp_debug("Image converter called\n");
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_vcard_send(char *target EINA_UNUSED, void *data EINA_UNUSED, int size EINA_UNUSED, void **data_ret, int *size_ret, Ecore_X_Atom *ttype EINA_UNUSED, int *typesize EINA_UNUSED)
-{
- X11_Cnp_Selection *sel;
-
- cnp_debug("Vcard send called\n");
- sel = _x11_selections + *((int *)data);
- if (data_ret) *data_ret = strdup(sel->selbuf);
- if (size_ret) *size_ret = strlen(sel->selbuf);
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_is_uri_type_data(X11_Cnp_Selection *sel EINA_UNUSED, Ecore_X_Event_Selection_Notify *notify)
-{
- Ecore_X_Selection_Data *data;
- char *p;
-
- data = notify->data;
- cnp_debug("data->format is %d %p %p\n", data->format, notify, data);
- if (data->content == ECORE_X_SELECTION_CONTENT_FILES) return EINA_TRUE;
- p = (char *)data->data;
- if (!p) return EINA_TRUE;
- cnp_debug("Got %s\n", p);
- if (strncmp(p, "file:/", 6))
- {
- if (*p != '/') return EINA_FALSE;
- }
- return EINA_TRUE;
-}
-
-/*
- * Callback to handle a targets response on a selection request:
- * So pick the format we'd like; and then request it.
- */
-static Eina_Bool
-_x11_notify_handler_targets(X11_Cnp_Selection *sel, Ecore_X_Event_Selection_Notify *notify)
-{
- Ecore_X_Selection_Data_Targets *targets;
- Ecore_X_Atom *atomlist;
- int i, j;
-
- targets = notify->data;
- atomlist = (Ecore_X_Atom *)(targets->data.data);
- for (j = (CNP_ATOM_LISTING_ATOMS + 1); j < CNP_N_ATOMS; j++)
- {
- cnp_debug("\t%s %d\n", _atoms[j].name, _atoms[j].x_atom);
- if (!(_atoms[j].formats & sel->requestformat)) continue;
- for (i = 0; i < targets->data.length; i++)
- {
- if ((_atoms[j].x_atom == atomlist[i]) && (_atoms[j].x_data_preparer))
- {
- if (j == CNP_ATOM_text_urilist)
- {
- if (!_x11_is_uri_type_data(sel, notify)) continue;
- }
- cnp_debug("Atom %s matches\n", _atoms[j].name);
- goto done;
- }
- }
- }
- cnp_debug("Couldn't find anything that matches\n");
- return ECORE_CALLBACK_PASS_ON;
-done:
- cnp_debug("Sending request for %s, xwin=%#llx\n",
- _atoms[j].name, (unsigned long long)sel->xwin);
- sel->request(sel->xwin, _atoms[j].name);
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_x11_data_preparer_text(Ecore_X_Event_Selection_Notify *notify,
- Elm_Selection_Data *ddata, Tmp_Info **tmp_info EINA_UNUSED)
-{
- Ecore_X_Selection_Data *data = notify->data;
- ddata->format = ELM_SEL_FORMAT_TEXT;
- ddata->data = eina_memdup(data->data, data->length, EINA_TRUE);
- ddata->len = data->length;
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_data_preparer_markup(Ecore_X_Event_Selection_Notify *notify,
- Elm_Selection_Data *ddata, Tmp_Info **tmp_info EINA_UNUSED)
-{
- Ecore_X_Selection_Data *data = notify->data;
- ddata->format = ELM_SEL_FORMAT_MARKUP;
- ddata->data = eina_memdup(data->data, data->length, EINA_TRUE);
- ddata->len = data->length;
- return EINA_TRUE;
-}
-
-/**
- * So someone is pasting an image into my entry or widget...
- */
-static Eina_Bool
-_x11_data_preparer_uri(Ecore_X_Event_Selection_Notify *notify,
- Elm_Selection_Data *ddata, Tmp_Info **tmp_info EINA_UNUSED)
-{
- Ecore_X_Selection_Data *data;
- Ecore_X_Selection_Data_Files *files;
- char *p, *stripstr = NULL;
-
- data = notify->data;
- cnp_debug("data->format is %d %p %p\n", data->format, notify, data);
- if (data->content == ECORE_X_SELECTION_CONTENT_FILES)
- {
- Efreet_Uri *uri;
- Eina_Strbuf *strbuf;
- int i;
-
- cnp_debug("got a files list\n");
- files = notify->data;
- /*
- if (files->num_files > 1)
- {
- // Don't handle many items <- this makes mr bigglesworth sad :(
- cnp_debug("more then one file: Bailing\n");
- return EINA_FALSE;
- }
- stripstr = p = strdup(files->files[0]);
- */
-
- strbuf = eina_strbuf_new();
- if (!strbuf)
- return EINA_FALSE;
-
- for (i = 0; i < files->num_files ; i++)
- {
- uri = efreet_uri_decode(files->files[i]);
- if (uri)
- {
- eina_strbuf_append(strbuf, uri->path);
- efreet_uri_free(uri);
- }
- else
- {
- eina_strbuf_append(strbuf, files->files[i]);
- }
- if (i < (files->num_files - 1))
- eina_strbuf_append(strbuf, "\n");
- }
- stripstr = eina_strbuf_string_steal(strbuf);
- eina_strbuf_free(strbuf);
- }
- else
- {
- Efreet_Uri *uri;
-
- p = (char *)eina_memdup((unsigned char *)data->data, data->length, EINA_TRUE);
- if (!p) return EINA_FALSE;
- uri = efreet_uri_decode(p);
- if (!uri)
- {
- /* Is there any reason why we care of URI without scheme? */
- if (p[0] == '/') stripstr = p;
- else free(p);
- }
- else
- {
- free(p);
- stripstr = strdup(uri->path);
- efreet_uri_free(uri);
- }
- }
-
- if (!stripstr)
- {
- cnp_debug("Couldn't find a file\n");
- return EINA_FALSE;
- }
- free(savedtypes.imgfile);
- if (savedtypes.textreq)
- {
- savedtypes.textreq = 0;
- savedtypes.imgfile = stripstr;
- }
- else
- {
- ddata->format = ELM_SEL_FORMAT_IMAGE;
- ddata->data = stripstr;
- ddata->len = strlen(stripstr);
- savedtypes.imgfile = NULL;
- }
- return EINA_TRUE;
-}
-
-/**
- * Just received an vcard, either through cut and paste, or dnd.
- */
-static Eina_Bool
-_x11_data_preparer_vcard(Ecore_X_Event_Selection_Notify *notify,
- Elm_Selection_Data *ddata, Tmp_Info **tmp_info EINA_UNUSED)
-{
- cnp_debug("vcard receive\n");
- Ecore_X_Selection_Data *data = notify->data;
- ddata->format = ELM_SEL_FORMAT_VCARD;
- ddata->data = eina_memdup(data->data, data->length, EINA_TRUE);
- ddata->len = data->length;
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_data_preparer_image(Ecore_X_Event_Selection_Notify *notify,
- Elm_Selection_Data *ddata, Tmp_Info **tmp_info)
-{
- Ecore_X_Selection_Data *data = notify->data;
- cnp_debug("got a image file!\n");
- cnp_debug("Size if %d\n", data->length);
-
- ddata->format = ELM_SEL_FORMAT_IMAGE;
- data = notify->data;
-
- Tmp_Info *tmp = _tempfile_new(data->length);
- if (!tmp) return EINA_FALSE;
- memcpy(tmp->map, data->data, data->length);
- munmap(tmp->map, data->length);
- ddata->data = strdup(tmp->filename);
- ddata->len = strlen(tmp->filename);
- *tmp_info = tmp;
- return EINA_TRUE;
-}
-
-/**
- * Warning: Generic text/html can';t handle it sanely.
- * Firefox sends ucs2 (i think).
- * chrome sends utf8... blerg
- */
-/*
-static int
-_x11_notify_handler_html(X11_Cnp_Selection *sel, Ecore_X_Event_Selection_Notify *notify)
-{
- Ecore_X_Selection_Data *data;
-
- cnp_debug("Got some HTML: Checking encoding is useful\n");
- data = notify->data;
- char *stripstr = malloc(data->length + 1);
- if (!stripstr) return 0;
- strncpy(stripstr, (char *)data->data, data->length);
- stripstr[data->length] = '\0';
-
- if (sel->datacb)
- {
- Elm_Selection_Data ddata;
- ddata.x = ddata.y = 0;
- ddata.format = ELM_SEL_FORMAT_HTML;
- ddata.data = stripstr;
- ddata.len = data->length;
- ddata.action = ELM_XDND_ACTION_UNKNOWN;
- sel->datacb(sel->udata, sel->widget, &ddata);
- free(stripstr);
- return 0;
- }
-
- cnp_debug("String is %s (%d bytes)\n", stripstr, data->length);
- // TODO BUG: should never NEVER assume it's an elm_entry!
- _elm_entry_entry_paste(sel->requestwidget, stripstr);
- free(stripstr);
- return 0;
-}
-*/
-
-static Eina_Bool
-_x11_text_converter(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize)
-{
- X11_Cnp_Selection *sel;
-
- cnp_debug("text converter\n");
- if (_get_selection_type(data, size) == ELM_SEL_FORMAT_NONE)
- {
- if (data_ret)
- {
- *data_ret = malloc(size * sizeof(char) + 1);
- if (!*data_ret) return EINA_FALSE;
- memcpy(*data_ret, data, size);
- ((char**)(data_ret))[0][size] = 0;
- }
- if (size_ret) *size_ret = size;
- return EINA_TRUE;
- }
- sel = _x11_selections + *((int *)data);
- if (!sel->active) return EINA_TRUE;
-
- if ((sel->format & ELM_SEL_FORMAT_MARKUP) ||
- (sel->format & ELM_SEL_FORMAT_HTML))
- {
- *data_ret = _elm_util_mkup_to_text(sel->selbuf);
- if (size_ret && *data_ret) *size_ret = strlen(*data_ret);
- }
- else if (sel->format & ELM_SEL_FORMAT_TEXT)
- {
- ecore_x_selection_converter_text(target, sel->selbuf,
- strlen(sel->selbuf),
- data_ret, size_ret,
- ttype, typesize);
- }
- else if (sel->format & ELM_SEL_FORMAT_IMAGE)
- {
- cnp_debug("Image %s\n", evas_object_type_get(sel->widget));
- cnp_debug("Elm type: %s\n", elm_object_widget_type_get(sel->widget));
- evas_object_image_file_get(elm_photocam_internal_image_get(sel->widget),
- (const char **)data_ret, NULL);
- if (!*data_ret) *data_ret = strdup("No file");
- else *data_ret = strdup(*data_ret);
-
- if (!*data_ret)
- {
- ERR("Failed to allocate memory!");
- *size_ret = 0;
- return EINA_FALSE;
- }
-
- *size_ret = strlen(*data_ret);
- }
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_general_converter(char *target EINA_UNUSED, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *ttype EINA_UNUSED, int *typesize EINA_UNUSED)
-{
- if (_get_selection_type(data, size) == ELM_SEL_FORMAT_NONE)
- {
- if (data_ret)
- {
- *data_ret = malloc(size * sizeof(char) + 1);
- if (!*data_ret) return EINA_FALSE;
- memcpy(*data_ret, data, size);
- ((char**)(data_ret))[0][size] = 0;
- }
- if (size_ret) *size_ret = size;
- }
- else
- {
- X11_Cnp_Selection *sel = _x11_selections + *((int *)data);
- if (sel->selbuf)
- {
- if (data_ret) *data_ret = strdup(sel->selbuf);
- if (size_ret) *size_ret = strlen(sel->selbuf);
- }
- else
- {
- if (data_ret) *data_ret = NULL;
- if (size_ret) *size_ret = 0;
- }
- }
- return EINA_TRUE;
-}
-
-static Dropable *
-_x11_dropable_find(Ecore_X_Window win)
-{
- Eina_List *l;
- Dropable *dropable;
-
- if (!drops) return NULL;
- EINA_LIST_FOREACH(drops, l, dropable)
- {
- if (_x11_elm_widget_xwin_get(dropable->obj) == win) return dropable;
- }
- return NULL;
-}
-
-static Evas *
-_x11_evas_get_from_xwin(Ecore_X_Window win)
-{
- /* Find the Evas connected to the window */
- Dropable *dropable = _x11_dropable_find(win);
- return dropable ? evas_object_evas_get(dropable->obj) : NULL;
-}
-
-static Eina_Bool
-_x11_dnd_enter(void *data EINA_UNUSED, int etype EINA_UNUSED, void *ev)
-{
- Ecore_X_Event_Xdnd_Enter *enter = ev;
- int i;
- Dropable *dropable;
-
- if (!enter) return EINA_TRUE;
- dropable = _x11_dropable_find(enter->win);
- if (dropable)
- {
- cnp_debug("Enter %x\n", enter->win);
- }
- /* Skip it */
- cnp_debug("enter types=%p (%d)\n", enter->types, enter->num_types);
- if ((!enter->num_types) || (!enter->types)) return EINA_TRUE;
-
- cnp_debug("Types\n");
- savedtypes.ntypes = enter->num_types;
- free(savedtypes.types);
- savedtypes.types = malloc(sizeof(char *) * enter->num_types);
- if (!savedtypes.types) return EINA_FALSE;
-
- for (i = 0; i < enter->num_types; i++)
- {
- savedtypes.types[i] = eina_stringshare_add(enter->types[i]);
- cnp_debug("Type is %s %p %p\n", enter->types[i],
- savedtypes.types[i], text_uri);
- if (savedtypes.types[i] == text_uri)
- {
- /* Request it, so we know what it is */
- cnp_debug("Sending uri request\n");
- savedtypes.textreq = 1;
- ELM_SAFE_FREE(savedtypes.imgfile, free);
- ecore_x_selection_xdnd_request(enter->win, text_uri);
- }
- }
-
- /* FIXME: Find an object and make it current */
- return EINA_TRUE;
-}
-
-static void
-_x11_dnd_dropable_handle(Dropable *dropable, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action)
-{
- Dropable *d, *last_dropable = NULL;
- Eina_List *l;
- Dropable_Cbs *cbs;
- Eina_Inlist *itr;
-
- EINA_LIST_FOREACH(drops, l, d)
- {
- if (d->last.in)
- {
- last_dropable = d;
- break;
- }
- }
- if (last_dropable)
- {
- if (last_dropable == dropable) // same
- {
- Evas_Coord ox, oy;
-
- cnp_debug("same obj dropable %p\n", dropable->obj);
- evas_object_geometry_get(dropable->obj, &ox, &oy, NULL, NULL);
- EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
- if ((cbs->types & dropable->last.format) && cbs->poscb)
- cbs->poscb(cbs->posdata, dropable->obj, x - ox, y - oy, action);
- }
- else
- {
- if (dropable) // leave last obj and enter new one
- {
- cnp_debug("leave %p\n", last_dropable->obj);
- cnp_debug("enter %p\n", dropable->obj);
- last_dropable->last.in = EINA_FALSE;
- last_dropable->last.type = NULL;
- dropable->last.in = EINA_TRUE;
- EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
- if ((cbs->types & dropable->last.format) && cbs->entercb)
- cbs->entercb(cbs->enterdata, dropable->obj);
- EINA_INLIST_FOREACH_SAFE(last_dropable->cbs_list, itr, cbs)
- if ((cbs->types & last_dropable->last.format) && cbs->leavecb)
- cbs->leavecb(cbs->leavedata, last_dropable->obj);
- }
- else // leave last obj
- {
- cnp_debug("leave %p\n", last_dropable->obj);
- last_dropable->last.in = EINA_FALSE;
- last_dropable->last.type = NULL;
- EINA_INLIST_FOREACH_SAFE(last_dropable->cbs_list, itr, cbs)
- if ((cbs->types & last_dropable->last.format) && cbs->leavecb)
- cbs->leavecb(cbs->leavedata, last_dropable->obj);
- }
- }
- }
- else
- {
- if (dropable) // enter new obj
- {
- Evas_Coord ox, oy;
-
- cnp_debug("enter %p\n", dropable->obj);
- evas_object_geometry_get(dropable->obj, &ox, &oy, NULL, NULL);
- dropable->last.in = EINA_TRUE;
- EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
- {
- if (cbs->types & dropable->last.format)
- {
- if (cbs->entercb)
- cbs->entercb(cbs->enterdata, dropable->obj);
- if (cbs->poscb)
- cbs->poscb(cbs->posdata, dropable->obj,
- x - ox, y - oy, action);
- }
- }
- }
- else
- {
- cnp_debug("both dropable & last_dropable are null\n");
- }
- }
-}
-
-static Elm_Xdnd_Action
-_x11_dnd_action_map(Ecore_X_Atom action)
-{
- Elm_Xdnd_Action act = ELM_XDND_ACTION_UNKNOWN;
-
- if (action == ECORE_X_ATOM_XDND_ACTION_COPY)
- act = ELM_XDND_ACTION_COPY;
- else if (action == ECORE_X_ATOM_XDND_ACTION_MOVE)
- act = ELM_XDND_ACTION_MOVE;
- else if (action == ECORE_X_ATOM_XDND_ACTION_PRIVATE)
- act = ELM_XDND_ACTION_PRIVATE;
- else if (action == ECORE_X_ATOM_XDND_ACTION_ASK)
- act = ELM_XDND_ACTION_ASK;
- else if (action == ECORE_X_ATOM_XDND_ACTION_LIST)
- act = ELM_XDND_ACTION_LIST;
- else if (action == ECORE_X_ATOM_XDND_ACTION_LINK)
- act = ELM_XDND_ACTION_LINK;
- else if (action == ECORE_X_ATOM_XDND_ACTION_DESCRIPTION)
- act = ELM_XDND_ACTION_DESCRIPTION;
- return act;
-}
-
-static Ecore_X_Atom
-_x11_dnd_action_rev_map(Elm_Xdnd_Action action)
-{
- Ecore_X_Atom act = ECORE_X_ATOM_XDND_ACTION_MOVE;
-
- if (action == ELM_XDND_ACTION_COPY)
- act = ECORE_X_ATOM_XDND_ACTION_COPY;
- else if (action == ELM_XDND_ACTION_MOVE)
- act = ECORE_X_ATOM_XDND_ACTION_MOVE;
- else if (action == ELM_XDND_ACTION_PRIVATE)
- act = ECORE_X_ATOM_XDND_ACTION_PRIVATE;
- else if (action == ELM_XDND_ACTION_ASK)
- act = ECORE_X_ATOM_XDND_ACTION_ASK;
- else if (action == ELM_XDND_ACTION_LIST)
- act = ECORE_X_ATOM_XDND_ACTION_LIST;
- else if (action == ELM_XDND_ACTION_LINK)
- act = ECORE_X_ATOM_XDND_ACTION_LINK;
- else if (action == ELM_XDND_ACTION_DESCRIPTION)
- act = ECORE_X_ATOM_XDND_ACTION_DESCRIPTION;
- return act;
-}
-
-static Eina_Bool
-_x11_dnd_position(void *data EINA_UNUSED, int etype EINA_UNUSED, void *ev)
-{
- Ecore_X_Event_Xdnd_Position *pos = ev;
- Ecore_X_Rectangle rect = { 0, 0, 0, 0 };
- Dropable *dropable;
- Elm_Xdnd_Action act;
-
- /* Need to send a status back */
- /* FIXME: Should check I can drop here */
- /* FIXME: Should highlight widget */
- dropable = _x11_dropable_find(pos->win);
- if (dropable)
- {
- Evas_Coord x, y, ox = 0, oy = 0;
-
- act = _x11_dnd_action_map(pos->action);
- x = pos->position.x;
- y = pos->position.y;
- _dropable_coords_adjust(dropable, &x, &y);
- Evas *evas = _x11_evas_get_from_xwin(pos->win);
- Eina_List *dropable_list = evas ? _dropable_list_geom_find(evas, x, y) : NULL;
- /* check if there is dropable (obj) can accept this drop */
- if (dropable_list)
- {
- Elm_Sel_Format saved_format = _dnd_types_to_format(savedtypes.types, savedtypes.ntypes);
- Eina_List *l;
- Eina_Bool found = EINA_FALSE;
-
- EINA_LIST_FOREACH(dropable_list, l, dropable)
- {
- Dropable_Cbs *cbs;
- Eina_Inlist *itr;
- EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
- {
- Elm_Sel_Format common_fmt = saved_format & cbs->types;
- if (common_fmt)
- {
- /* We found a target that can accept this type of data */
- int i, min_index = CNP_N_ATOMS;
- /* We have to find the first atom that corresponds to one
- * of the supported data types. */
- for (i = 0; i < savedtypes.ntypes; i++)
- {
- Cnp_Atom *atom = eina_hash_find(_types_hash, savedtypes.types[i]);
- if (atom && (atom->formats & common_fmt))
- {
- int atom_idx = (atom - _atoms);
- if (min_index > atom_idx) min_index = atom_idx;
- }
- }
- if (min_index != CNP_N_ATOMS)
- {
- cnp_debug("Found atom %s\n", _atoms[min_index].name);
- found = EINA_TRUE;
- dropable->last.type = _atoms[min_index].name;
- dropable->last.format = common_fmt;
- break;
- }
- }
- }
- if (found) break;
- }
- if (found)
- {
- Dropable *d = NULL;
- Eina_Rectangle inter_rect = {0, 0, 0, 0};
- int idx = 0;
- EINA_LIST_FOREACH(dropable_list, l, d)
- {
- if (idx == 0)
- {
- evas_object_geometry_get(d->obj, &inter_rect.x, &inter_rect.y,
- &inter_rect.w, &inter_rect.h);
- }
- else
- {
- Eina_Rectangle cur_rect;
- evas_object_geometry_get(d->obj, &cur_rect.x, &cur_rect.y,
- &cur_rect.w, &cur_rect.h);
- if (!eina_rectangle_intersection(&inter_rect, &cur_rect)) continue;
- }
- idx++;
- }
- rect.x = inter_rect.x;
- rect.y = inter_rect.y;
- rect.width = inter_rect.w;
- rect.height = inter_rect.h;
- ecore_x_dnd_send_status(EINA_TRUE, EINA_FALSE, rect, pos->action);
- cnp_debug("dnd position %i %i %p\n", x - ox, y - oy, dropable);
- _x11_dnd_dropable_handle(dropable, x - ox, y - oy, act);
- // CCCCCCC: call dnd exit on last obj if obj != last
- // CCCCCCC: call drop position on obj
- }
- else
- {
- //if not: send false status
- ecore_x_dnd_send_status(EINA_FALSE, EINA_FALSE, rect, pos->action);
- cnp_debug("dnd position (%d, %d) not in obj\n", x, y);
- _x11_dnd_dropable_handle(NULL, 0, 0, act);
- // CCCCCCC: call dnd exit on last obj
- }
- eina_list_free(dropable_list);
- }
- else
- {
- ecore_x_dnd_send_status(EINA_FALSE, EINA_FALSE, rect, pos->action);
- cnp_debug("dnd position (%d, %d) has no drop\n", x, y);
- _x11_dnd_dropable_handle(NULL, 0, 0, act);
- }
- }
- else
- {
- ecore_x_dnd_send_status(EINA_FALSE, EINA_FALSE, rect, pos->action);
- }
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_dnd_leave(void *data EINA_UNUSED, int etype EINA_UNUSED, void *ev)
-{
-#ifdef DEBUGON
- cnp_debug("Leave %x\n", ((Ecore_X_Event_Xdnd_Leave *)ev)->win);
-#else
- (void)ev;
-#endif
- _x11_dnd_dropable_handle(NULL, 0, 0, ELM_XDND_ACTION_UNKNOWN);
- // CCCCCCC: call dnd exit on last obj if there was one
- // leave->win leave->source
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_dnd_drop(void *data EINA_UNUSED, int etype EINA_UNUSED, void *ev)
-{
- Ecore_X_Event_Xdnd_Drop *drop;
- Dropable *dropable = NULL;
- Elm_Selection_Data ddata;
- Evas_Coord x = 0, y = 0;
- Elm_Xdnd_Action act = ELM_XDND_ACTION_UNKNOWN;
- Eina_List *l;
- Dropable_Cbs *cbs;
- Eina_Inlist *itr;
-
- drop = ev;
-
- cnp_debug("drops %p (%d)\n", drops, eina_list_count(drops));
- if (!(dropable = _x11_dropable_find(drop->win))) return EINA_TRUE;
-
- /* Calculate real (widget relative) position */
- // - window position
- // - widget position
- savedtypes.x = drop->position.x;
- savedtypes.y = drop->position.y;
- _dropable_coords_adjust(dropable, &savedtypes.x, &savedtypes.y);
-
- cnp_debug("Drop position is %d,%d\n", savedtypes.x, savedtypes.y);
-
- EINA_LIST_FOREACH(drops, l, dropable)
- {
- if (dropable->last.in)
- {
- evas_object_geometry_get(dropable->obj, &x, &y, NULL, NULL);
- savedtypes.x -= x;
- savedtypes.y -= y;
- goto found;
- }
- }
-
- cnp_debug("Didn't find a target\n");
- return EINA_TRUE;
-
-found:
- cnp_debug("0x%x\n", drop->win);
-
- act = _x11_dnd_action_map(drop->action);
-
- dropable->last.in = EINA_FALSE;
- cnp_debug("Last type: %s - Last format: %X\n", dropable->last.type, dropable->last.format);
- if ((!strcmp(dropable->last.type, text_uri)))
- {
- cnp_debug("We found a URI... (%scached) %s\n",
- savedtypes.imgfile ? "" : "not ",
- savedtypes.imgfile);
- if (savedtypes.imgfile)
- {
- ddata.x = savedtypes.x;
- ddata.y = savedtypes.y;
- ddata.action = act;
-
- EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
- {
- /* If it's markup that also supports images */
- if (cbs->types & ELM_SEL_FORMAT_IMAGE)
- {
- cnp_debug("Doing image insert (%s)\n", savedtypes.imgfile);
- ddata.format = ELM_SEL_FORMAT_IMAGE;
- ddata.data = (char *)savedtypes.imgfile;
- ddata.len = strlen(ddata.data);
- if ((cbs->types & dropable->last.format) && cbs->dropcb)
- cbs->dropcb(cbs->dropdata, dropable->obj, &ddata);
- }
- else
- {
- cnp_debug("Item doesn't support images... passing\n");
- }
- }
- ecore_x_dnd_send_finished();
- ELM_SAFE_FREE(savedtypes.imgfile, free);
- return EINA_TRUE;
- }
- else if (savedtypes.textreq)
- {
- /* Already asked: Pretend we asked now, and paste immediately when
- * it comes in */
- savedtypes.textreq = 0;
- ecore_x_dnd_send_finished();
- return EINA_TRUE;
- }
- }
-
- cnp_debug("doing a request then: %s\n", dropable->last.type);
- _x11_selections[ELM_SEL_TYPE_XDND].xwin = drop->win;
- _x11_selections[ELM_SEL_TYPE_XDND].requestwidget = dropable->obj;
- _x11_selections[ELM_SEL_TYPE_XDND].requestformat = dropable->last.format;
- _x11_selections[ELM_SEL_TYPE_XDND].active = EINA_TRUE;
- _x11_selections[ELM_SEL_TYPE_XDND].action = act;
- ecore_x_selection_xdnd_request(drop->win, dropable->last.type);
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_dnd_status(void *data EINA_UNUSED, int etype EINA_UNUSED, void *ev)
-{
- Ecore_X_Event_Xdnd_Status *status = ev;
-
- doaccept = EINA_FALSE;
-
- /* Only thing we care about: will accept */
- if ((status) && (status->will_accept))
- {
- cnp_debug("Will accept\n");
- doaccept = EINA_TRUE;
- }
- /* Won't accept */
- else
- {
- cnp_debug("Won't accept accept\n");
- }
- if (dragacceptcb)
- dragacceptcb(dragacceptdata, _x11_selections[ELM_SEL_TYPE_XDND].widget,
- doaccept);
- return EINA_TRUE;
-}
-
-static void
-_x11_win_rotation_changed_cb(void *data, const Efl_Event *event)
-{
- Evas_Object *win = data;
- int rot = elm_win_rotation_get(event->object);
- elm_win_rotation_set(win, rot);
-}
-
-static Eina_Bool
-_x11_drag_mouse_up(void *data, int etype EINA_UNUSED, void *event)
-{
- Ecore_X_Window xwin = (Ecore_X_Window)(long)data;
- Ecore_Event_Mouse_Button *ev = event;
-
- if ((ev->buttons == 1) &&
- (ev->event_window == xwin))
- {
- Eina_Bool have_drops = EINA_FALSE;
- Eina_List *l;
- Dropable *dropable;
-
- ecore_x_pointer_ungrab();
- ELM_SAFE_FREE(handler_up, ecore_event_handler_del);
- ELM_SAFE_FREE(handler_status, ecore_event_handler_del);
- ecore_x_dnd_self_drop();
-
- cnp_debug("mouse up, xwin=%#llx\n", (unsigned long long)xwin);
-
- EINA_LIST_FOREACH(drops, l, dropable)
- {
- if (xwin == _x11_elm_widget_xwin_get(dropable->obj))
- {
- have_drops = EINA_TRUE;
- break;
- }
- }
- if (!have_drops) ecore_x_dnd_aware_set(xwin, EINA_FALSE);
- if (dragdonecb) dragdonecb(dragdonedata, dragwidget);
- if (dragwin)
- {
- if (dragwidget)
- {
- if (elm_widget_is(dragwidget))
- {
- Evas_Object *win = elm_widget_top_get(dragwidget);
- if (win && efl_isa(win, EFL_UI_WIN_CLASS))
- efl_event_callback_del(win, EFL_UI_WIN_EVENT_ROTATION_CHANGED, _x11_win_rotation_changed_cb, dragwin);
- }
- }
-
- if (!doaccept)
- { /* Commit animation when drag cancelled */
- /* Record final position of dragwin, then do animation */
- ecore_animator_timeline_add(0.3,
- _drag_cancel_animate, dragwin);
- }
- else
- { /* No animation drop was committed */
- Ecore_X_Window xdragwin = _x11_elm_widget_xwin_get(dragwin);
- ecore_x_window_ignore_set(xdragwin, 0);
- evas_object_del(dragwin);
- }
-
- dragwin = NULL; /* if not freed here, free in end of anim */
- }
-
- dragdonecb = NULL;
- dragacceptcb = NULL;
- dragposcb = NULL;
- dragwidget = NULL;
- doaccept = EINA_FALSE;
- /* moved to _drag_cancel_animate
- if (dragwin)
- {
- evas_object_del(dragwin);
- dragwin = NULL;
- }
- */
- }
- return EINA_TRUE;
-}
-
-static void
-_x11_drag_move(void *data EINA_UNUSED, Ecore_X_Xdnd_Position *pos)
-{
- evas_object_move(dragwin,
- pos->position.x - _dragx, pos->position.y - _dragy);
- dragwin_x_end = pos->position.x - _dragx;
- dragwin_y_end = pos->position.y - _dragy;
- cnp_debug("dragevas: %p -> %p\n",
- dragwidget,
- evas_object_evas_get(dragwidget));
- if (dragposcb)
- dragposcb(dragposdata, dragwidget, pos->position.x, pos->position.y,
- dragaction);
-}
-
-static Ecore_X_Window
-_x11_elm_widget_xwin_get(const Evas_Object *obj)
-{
- Evas_Object *top, *par;
- Ecore_X_Window xwin = 0;
-
- if (elm_widget_is(obj))
- {
- top = elm_widget_top_get(obj);
- if (!top)
- {
- par = elm_widget_parent_widget_get(obj);
- if (par) top = elm_widget_top_get(par);
- }
- if (top && (efl_isa(top, EFL_UI_WIN_CLASS)))
- xwin = elm_win_xwindow_get(top);
- }
- if (!xwin)
- {
- Ecore_Evas *ee;
- Evas *evas = evas_object_evas_get(obj);
- if (!evas) return 0;
- ee = ecore_evas_ecore_evas_get(evas);
- if (!ee) return 0;
-
- while(!xwin)
- {
- const char *engine_name = ecore_evas_engine_name_get(ee);
- if (!strcmp(engine_name, ELM_BUFFER))
- {
- ee = ecore_evas_buffer_ecore_evas_parent_get(ee);
- if (!ee) return 0;
- xwin = _elm_ee_xwin_get(ee);
- }
- else
- {
- /* In case the engine is not a buffer, we want to check once. */
- xwin = _elm_ee_xwin_get(ee);
- if (!xwin) return 0;
- }
- }
- }
- return xwin;
-}
-
-static Eina_Bool
-_x11_elm_cnp_init(void)
-{
- int i;
- static int _init_count = 0;
-
- if (_init_count > 0) return EINA_TRUE;
- _init_count++;
- for (i = 0; i < CNP_N_ATOMS; i++)
- {
- _atoms[i].x_atom = ecore_x_atom_get(_atoms[i].name);
- ecore_x_selection_converter_atom_add
- (_atoms[i].x_atom, _atoms[i].x_converter);
- }
- //XXX delete handlers?
- ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR, _x11_selection_clear, NULL);
- ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY, _x11_selection_notify, NULL);
- ecore_event_handler_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, _x11_fixes_selection_notify, NULL);
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_elm_cnp_selection_set(Ecore_X_Window xwin, Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format, const void *selbuf, size_t buflen)
-{
- X11_Cnp_Selection *sel;
-
- _x11_elm_cnp_init();
- if ((!selbuf) && (format != ELM_SEL_FORMAT_IMAGE))
- return elm_object_cnp_selection_clear(obj, selection);
-
- sel = _x11_selections + selection;
- if (sel->widget != obj && sel->loss_cb) sel->loss_cb(sel->loss_data, selection);
- if (sel->widget)
- evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
- _x11_sel_obj_del, sel);
- sel->active = EINA_TRUE;
- sel->widget = obj;
- sel->xwin = xwin;
- if (sel->set) sel->set(xwin, &selection, sizeof(Elm_Sel_Type));
- sel->format = format;
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
-
- evas_object_event_callback_add
- (sel->widget, EVAS_CALLBACK_DEL, _x11_sel_obj_del, sel);
-
- ELM_SAFE_FREE(sel->selbuf, free);
- if (selbuf)
- {
- if (format == ELM_SEL_FORMAT_IMAGE)
- {
- // selbuf is actual image data, not text/string
- sel->selbuf = malloc(buflen + 1);
- if (!sel->selbuf)
- {
- elm_object_cnp_selection_clear(obj, selection);
- return EINA_FALSE;
- }
- memcpy(sel->selbuf, selbuf, buflen);
- sel->selbuf[buflen] = 0;
- }
- else
- sel->selbuf = strdup((char*)selbuf);
- }
-
- return _local_elm_cnp_selection_set(obj, selection, format, selbuf, buflen);
-}
-
-static void
-_x11_elm_cnp_selection_loss_callback_set(Evas_Object *obj EINA_UNUSED, Elm_Sel_Type selection, Elm_Selection_Loss_Cb func, const void *data)
-{
- X11_Cnp_Selection *sel;
-
- _x11_elm_cnp_init();
- sel = _x11_selections + selection;
- sel->loss_cb = func;
- sel->loss_data = (void *)data;
-}
-
-static Eina_Bool
-_x11_elm_object_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type selection)
-{
- X11_Cnp_Selection *sel;
-
- _x11_elm_cnp_init();
-
- sel = _x11_selections + selection;
-
- /* No longer this selection: Consider it gone! */
- if ((!sel->active) || (sel->widget != obj)) return EINA_TRUE;
-
- if (sel->widget)
- evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
- _x11_sel_obj_del, sel);
- if (sel->requestwidget)
- evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
- _x11_sel_obj_del2, sel);
- sel->widget = NULL;
- sel->requestwidget = NULL;
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
-
- sel->active = EINA_FALSE;
- ELM_SAFE_FREE(sel->selbuf, free);
- sel->clear();
-
- return _local_elm_object_cnp_selection_clear(obj, selection);
-}
-
-static Eina_Bool
-_x11_elm_cnp_selection_get(Ecore_X_Window xwin, const Evas_Object *obj, Elm_Sel_Type selection,
- Elm_Sel_Format format, Elm_Drop_Cb datacb,
- void *udata)
-{
- X11_Cnp_Selection *sel;
-
- _x11_elm_cnp_init();
-
- sel = _x11_selections + selection;
- if (sel->active)
- return _local_elm_cnp_selection_get(obj, selection, format, datacb, udata);
-
- if (sel->requestwidget)
- evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
- _x11_sel_obj_del2, sel);
- sel->requestformat = format;
- sel->requestwidget = (Evas_Object *)obj;
- sel->xwin = xwin;
- sel->request(xwin, ECORE_X_SELECTION_TARGET_TARGETS);
- sel->datacb = datacb;
- sel->udata = udata;
-
- evas_object_event_callback_add
- (sel->requestwidget, EVAS_CALLBACK_DEL, _x11_sel_obj_del2, sel);
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format,
- Elm_Drag_State entercb, void *enterdata,
- Elm_Drag_State leavecb, void *leavedata,
- Elm_Drag_Pos poscb, void *posdata,
- Elm_Drop_Cb dropcb, void *dropdata)
-{
- Dropable *dropable = NULL;
- Dropable_Cbs *cbs = NULL;
- Ecore_X_Window xwin = _x11_elm_widget_xwin_get(obj);
- Eina_List *l;
- Eina_Bool first = !drops;
- Eina_Bool have_drops = EINA_FALSE;
-
- _x11_elm_cnp_init();
-
- /* Is this the first? */
- EINA_LIST_FOREACH(drops, l, dropable)
- {
- if (xwin == _x11_elm_widget_xwin_get(dropable->obj))
- {
- have_drops = EINA_TRUE;
- break;
- }
- }
- dropable = NULL; // In case of error, we don't want to free it
-
- cbs = calloc(1, sizeof(*cbs));
- if (!cbs) return EINA_FALSE;
-
- cbs->entercb = entercb;
- cbs->enterdata = enterdata;
- cbs->leavecb = leavecb;
- cbs->leavedata = leavedata;
- cbs->poscb = poscb;
- cbs->posdata = posdata;
- cbs->dropcb = dropcb;
- cbs->dropdata = dropdata;
- cbs->types = format;
-
- dropable = efl_key_data_get(obj, "__elm_dropable");
- if (!dropable)
- {
- /* Create new drop */
- dropable = calloc(1, sizeof(Dropable));
- if (!dropable) goto error;
- dropable->last.in = EINA_FALSE;
- drops = eina_list_append(drops, dropable);
- if (!drops) goto error;
- dropable->obj = obj;
- efl_key_data_set(obj, "__elm_dropable", dropable);
- }
- dropable->cbs_list = eina_inlist_append(dropable->cbs_list, EINA_INLIST_GET(cbs));
-
- evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
- _all_drop_targets_cbs_del, obj);
- if (!have_drops) ecore_x_dnd_aware_set(xwin, EINA_TRUE);
-
- /* TODO BUG: should handle dnd-aware per window, not just the first
- * window that requested it! */
- /* If not the first: We're done */
- if (!first) return EINA_TRUE;
-
- cnp_debug("Adding drop target calls xwin=%#llx\n", (unsigned long long)xwin);
- handler_enter = ecore_event_handler_add(ECORE_X_EVENT_XDND_ENTER,
- _x11_dnd_enter, NULL);
- handler_leave = ecore_event_handler_add(ECORE_X_EVENT_XDND_LEAVE,
- _x11_dnd_leave, NULL);
- handler_pos = ecore_event_handler_add(ECORE_X_EVENT_XDND_POSITION,
- _x11_dnd_position, NULL);
- handler_drop = ecore_event_handler_add(ECORE_X_EVENT_XDND_DROP,
- _x11_dnd_drop, NULL);
- return EINA_TRUE;
-error:
- free(cbs);
- free(dropable);
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_x11_elm_drop_target_del(Evas_Object *obj, Elm_Sel_Format format,
- Elm_Drag_State entercb, void *enterdata,
- Elm_Drag_State leavecb, void *leavedata,
- Elm_Drag_Pos poscb, void *posdata,
- Elm_Drop_Cb dropcb, void *dropdata)
-{
- Dropable *dropable = NULL;
- Eina_List *l;
- Ecore_X_Window xwin;
- Eina_Bool have_drops = EINA_FALSE;
-
- _x11_elm_cnp_init();
-
- if (!_local_elm_drop_target_del(obj, format, entercb, enterdata,
- leavecb, leavedata, poscb, posdata, dropcb, dropdata))
- {
- return EINA_FALSE;
- }
-
- /* TODO BUG: we should handle dnd-aware per window, not just the last that released it */
-
- /* If still drops there: All fine.. continue */
- if (drops) return EINA_TRUE;
-
- cnp_debug("Disabling DND\n");
- xwin = _x11_elm_widget_xwin_get(obj);
- EINA_LIST_FOREACH(drops, l, dropable)
- {
- if (xwin == _x11_elm_widget_xwin_get(dropable->obj))
- {
- have_drops = EINA_TRUE;
- break;
- }
- }
- if (!have_drops) ecore_x_dnd_aware_set(xwin, EINA_FALSE);
-
- if (!drops)
- {
- ELM_SAFE_FREE(handler_pos, ecore_event_handler_del);
- ELM_SAFE_FREE(handler_drop, ecore_event_handler_del);
- ELM_SAFE_FREE(handler_enter, ecore_event_handler_del);
- ELM_SAFE_FREE(handler_leave, ecore_event_handler_del);
- }
-
- ELM_SAFE_FREE(savedtypes.imgfile, free);
-
- return EINA_TRUE;
-}
-
-static void
-_x11_drag_target_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *info EINA_UNUSED)
-{
- X11_Cnp_Selection *sel = _x11_selections + ELM_SEL_TYPE_XDND;
-
- if (dragwidget == obj)
- {
- sel->widget = NULL;
- dragwidget = NULL;
- }
-}
-
-static Eina_Bool
-_x11_elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data,
- Elm_Xdnd_Action action,
- Elm_Drag_Icon_Create_Cb createicon, void *createdata,
- Elm_Drag_Pos dragpos, void *dragdata,
- Elm_Drag_Accept acceptcb, void *acceptdata,
- Elm_Drag_State dragdone, void *donecbdata)
-{
- Ecore_X_Window xwin = _x11_elm_widget_xwin_get(obj);
- Ecore_X_Window xdragwin;
- X11_Cnp_Selection *sel;
- Elm_Sel_Type xdnd = ELM_SEL_TYPE_XDND;
- Ecore_Evas *ee;
- int x, y, x2 = 0, y2 = 0, x3, y3;
- Evas_Object *icon = NULL;
- int w = 0, h = 0;
- int ex, ey, ew, eh;
- Ecore_X_Atom actx;
- int i;
- int xr, yr, rot;
-
- _x11_elm_cnp_init();
-
- cnp_debug("starting drag... %p\n", obj);
-
- if (dragwin)
- {
- cnp_debug("another obj is dragging...\n");
- return EINA_FALSE;
- }
-
- ecore_x_dnd_types_set(xwin, NULL, 0);
- for (i = CNP_ATOM_LISTING_ATOMS + 1; i < CNP_N_ATOMS; i++)
- {
- if (format == ELM_SEL_FORMAT_TARGETS || (_atoms[i].formats & format))
- {
- ecore_x_dnd_type_set(xwin, _atoms[i].name, EINA_TRUE);
- cnp_debug("set dnd type: %s\n", _atoms[i].name);
- }
- }
-
- sel = _x11_selections + ELM_SEL_TYPE_XDND;
- sel->active = EINA_TRUE;
- sel->widget = obj;
- sel->format = format;
- sel->selbuf = data ? strdup(data) : NULL;
- sel->action = action;
- dragwidget = obj;
- dragaction = action;
-
- evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
- _x11_drag_target_del, obj);
- /* TODO BUG: should NEVER have these as globals! They should be per context (window). */
- dragposcb = dragpos;
- dragposdata = dragdata;
- dragacceptcb = acceptcb;
- dragacceptdata = acceptdata;
- dragdonecb = dragdone;
- dragdonedata = donecbdata;
- /* TODO BUG: should increase dnd-awareness, in case it's drop target as well. See _x11_drag_mouse_up() */
- ecore_x_dnd_aware_set(xwin, EINA_TRUE);
- ecore_x_dnd_callback_pos_update_set(_x11_drag_move, NULL);
- ecore_x_dnd_self_begin(xwin, (unsigned char *)&xdnd, sizeof(Elm_Sel_Type));
- actx = _x11_dnd_action_rev_map(dragaction);
- ecore_x_dnd_source_action_set(actx);
- ecore_x_pointer_grab(xwin);
- handler_up = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
- _x11_drag_mouse_up,
- (void *)(long)xwin);
- handler_status = ecore_event_handler_add(ECORE_X_EVENT_XDND_STATUS,
- _x11_dnd_status, NULL);
- dragwin = elm_win_add(NULL, "Elm-Drag", ELM_WIN_DND);
- elm_win_alpha_set(dragwin, EINA_TRUE);
- elm_win_override_set(dragwin, EINA_TRUE);
- xdragwin = _x11_elm_widget_xwin_get(dragwin);
- ecore_x_window_ignore_set(xdragwin, 1);
-
- /* dragwin has to be rotated as the main window is */
- if (elm_widget_is(obj))
- {
- Evas_Object *win = elm_widget_top_get(obj);
- if (win && efl_isa(win, EFL_UI_WIN_CLASS))
- {
- elm_win_rotation_set(dragwin, elm_win_rotation_get(win));
- efl_event_callback_add(win, EFL_UI_WIN_EVENT_ROTATION_CHANGED, _x11_win_rotation_changed_cb, dragwin);
- }
- }
-
- if (createicon)
- {
- Evas_Coord xoff = 0, yoff = 0;
-
- icon = createicon(createdata, dragwin, &xoff, &yoff);
- if (icon)
- {
- x2 = xoff;
- y2 = yoff;
- evas_object_geometry_get(icon, NULL, NULL, &w, &h);
- }
- }
- else
- {
- icon = elm_icon_add(dragwin);
- evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- // need to resize
- }
- elm_win_resize_object_add(dragwin, icon);
-
- /* Position subwindow appropriately */
- ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
- ecore_evas_geometry_get(ee, &ex, &ey, &ew, &eh);
- evas_object_resize(dragwin, w, h);
-
- evas_object_show(icon);
- evas_object_show(dragwin);
- evas_pointer_canvas_xy_get(evas_object_evas_get(obj), &x3, &y3);
-
- rot = ecore_evas_rotation_get(ee);
- switch (rot)
- {
- case 90:
- xr = y3;
- yr = ew - x3;
- _dragx = y3 - y2;
- _dragy = x3 - x2;
- break;
- case 180:
- xr = ew - x3;
- yr = eh - y3;
- _dragx = x3 - x2;
- _dragy = y3 - y2;
- break;
- case 270:
- xr = eh - y3;
- yr = x3;
- _dragx = y3 - y2;
- _dragy = x3 - x2;
- break;
- default:
- xr = x3;
- yr = y3;
- _dragx = x3 - x2;
- _dragy = y3 - y2;
- break;
- }
- x = ex + xr - _dragx;
- y = ey + yr - _dragy;
- evas_object_move(dragwin, x, y);
- dragwin_x_start = dragwin_x_end = x;
- dragwin_y_start = dragwin_y_end = y;
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_elm_drag_action_set(Evas_Object *obj, Elm_Xdnd_Action action)
-{
- Ecore_X_Atom actx;
-
- _x11_elm_cnp_init();
- if (!dragwin) return EINA_FALSE;
-
- if (dragwidget != obj) return EINA_FALSE;
- if (dragaction == action) return EINA_TRUE;
- dragaction = action;
- actx = _x11_dnd_action_rev_map(dragaction);
- ecore_x_dnd_source_action_set(actx);
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_x11_elm_selection_selection_has_owner(Evas_Object *obj EINA_UNUSED)
-{
- _x11_elm_cnp_init();
- return !!ecore_x_selection_owner_get(ECORE_X_ATOM_SELECTION_CLIPBOARD);
-}
-
-#endif
-
-#ifdef HAVE_ELEMENTARY_WL2
-struct _Wl_Cnp_Selection
-{
- char *selbuf;
- int buflen;
-
- Evas_Object *widget;
- Evas_Object *requestwidget;
-
- void *udata;
- Elm_Sel_Type seltype;
- Elm_Sel_Format requestformat;
- Elm_Drop_Cb datacb;
-
- Elm_Selection_Loss_Cb loss_cb;
- void *loss_data;
-
- Elm_Sel_Format format;
- Ecore_Wl2_Window *win;
- Elm_Xdnd_Action action;
- uint32_t selection_serial;
- uint32_t drag_serial;
-
- Eina_Bool active : 1;
-};
-
-static Eina_Bool _wl_elm_cnp_init(void);
-
-static Wl_Cnp_Selection wl_cnp_selection =
-{
- 0, 0, NULL, NULL,
- NULL, 0, 0, NULL, NULL, NULL,
- 0, NULL, 0, EINA_FALSE
-};
-
-static void _wl_sel_obj_del2(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED);
-static Eina_Bool _wl_elm_cnp_selection_set(Evas_Object *obj EINA_UNUSED, Elm_Sel_Type selection, Elm_Sel_Format format EINA_UNUSED, const void *selbuf, size_t buflen);
-static Eina_Bool _wl_elm_cnp_selection_get(const Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format EINA_UNUSED, Elm_Drop_Cb datacb EINA_UNUSED, void *udata EINA_UNUSED);
-static Eina_Bool _wl_elm_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type selection);
-
-static Eina_Bool _wl_selection_send(void *udata, int type EINA_UNUSED, void *event);
-static Eina_Bool _wl_selection_receive(void *udata, int type EINA_UNUSED, void *event);
-
-static Eina_Bool _wl_elm_dnd_init(void);
-static Eina_Bool _wl_elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format, Elm_Drag_State entercb, void *enterdata, Elm_Drag_State leavecb, void *leavedata, Elm_Drag_Pos poscb, void *posdata, Elm_Drop_Cb dropcb, void *dropdata);
-static Eina_Bool _wl_elm_drop_target_del(Evas_Object *obj, Elm_Sel_Format format, Elm_Drag_State entercb, void *enterdata, Elm_Drag_State leavecb, void *leavedata, Elm_Drag_Pos poscb, void *posdata, Elm_Drop_Cb dropcb, void *dropdata);
-
-static Eina_Bool _wl_elm_drag_action_set(Evas_Object *obj, Elm_Xdnd_Action action);
-static Eina_Bool _wl_elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data, Elm_Xdnd_Action action, Elm_Drag_Icon_Create_Cb createicon, void *createdata, Elm_Drag_Pos dragpos, void *dragdata, Elm_Drag_Accept acceptcb, void *acceptdata, Elm_Drag_State dragdone, void *donecbdata);
-
-static void _wl_drag_source_del(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED);
-
-static Eina_Bool _wl_dnd_enter(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
-static Eina_Bool _wl_dnd_leave(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
-static Eina_Bool _wl_dnd_position(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
-static Eina_Bool _wl_dnd_drop(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
-/* static Eina_Bool _wl_dnd_offer(void *data EINA_UNUSED, int type EINA_UNUSED, void *event); */
-
-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_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);
-static void _wl_dropable_all_clean(unsigned int win);
-static Eina_Bool _wl_drops_accept(const char *type);
-static Ecore_Wl2_Window *_wl_elm_widget_window_get(const Evas_Object *obj);
-static Evas * _wl_evas_get_from_win(unsigned int win);
-
-static Eina_Bool
-_wl_is_uri_type_data(const char *data, int len)
-{
- char *p;
- if (len < 6) return EINA_FALSE;
-
- p = (char *)data;
- if (!p) return EINA_FALSE;
- if (strncmp(p, "file:/", 6))
- {
- if (*p != '/') return EINA_FALSE;
- }
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_wl_targets_converter(char *target, Wl_Cnp_Selection *sel EINA_UNUSED, void *data EINA_UNUSED, int size EINA_UNUSED, void **data_ret, int *size_ret)
-{
- cnp_debug("in\n");
- if (!data_ret) return EINA_FALSE;
-
- const char *sep = "\n";
- char *aret;
- int len = 0;
- int i = 0;
- Elm_Sel_Format formats = ELM_SEL_FORMAT_NONE;
- Eina_Bool is_uri = EINA_FALSE;
-
- if (sel->format)
- {
- formats = sel->format;
- is_uri = _wl_is_uri_type_data(sel->selbuf, sel->buflen);
- }
- else
- {
- Cnp_Atom *atom = eina_hash_find(_types_hash, target);
- if (atom)
- formats = atom->formats;
- }
- for (i = 0; i < CNP_N_ATOMS; i++)
- {
- if (formats & _atoms[i].formats)
- {
- if ((is_uri) ||
- ((!is_uri) && strcmp(_atoms[i].name, "text/uri-list")))
- len += strlen(_atoms[i].name) + strlen(sep);
- }
- }
- len++; //terminating null byte
- aret = calloc(1, len * sizeof(char));
- if (!aret) return EINA_FALSE;
- for (i = 0; i < CNP_N_ATOMS; i++)
- {
- if (formats & _atoms[i].formats)
- {
- if ((is_uri) ||
- ((!is_uri) && strcmp(_atoms[i].name, "text/uri-list")))
- {
- aret = strcat(aret, _atoms[i].name);
- aret = strcat(aret, sep);
- }
- }
- }
- *data_ret = aret;
- if (size_ret) *size_ret = len;
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_wl_general_converter(char *target, Wl_Cnp_Selection *sel EINA_UNUSED, void *data, int size, void **data_ret, int *size_ret)
-{
- Elm_Sel_Format formats = ELM_SEL_FORMAT_NONE;
- Cnp_Atom *atom = NULL;
-
- cnp_debug("in\n");
-
- atom = eina_hash_find(_types_hash, target);
- if (atom)
- formats = atom->formats;
- if (formats == ELM_SEL_FORMAT_NONE)
- {
- if (data_ret)
- {
- *data_ret = malloc(size * sizeof(char) + 1);
- if (!*data_ret) return EINA_FALSE;
- memcpy(*data_ret, data, size);
- ((char**)(data_ret))[0][size] = 0;
- }
- if (size_ret) *size_ret = size;
- }
- else
- {
- if (data)
- {
- if (data_ret) *data_ret = strdup(data);
- if (size_ret) *size_ret = strlen(data);
- }
- else
- {
- if (data_ret) *data_ret = NULL;
- if (size_ret) *size_ret = 0;
- }
- }
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_wl_text_converter(char *target, Wl_Cnp_Selection *sel, void *data, int size, void **data_ret, int *size_ret)
-{
- Elm_Sel_Format formats = ELM_SEL_FORMAT_NONE;
- Cnp_Atom *atom = NULL;
-
- cnp_debug("in\n");
-
- atom = eina_hash_find(_types_hash, target);
- if (atom)
- formats = atom->formats;
- if (formats == ELM_SEL_FORMAT_NONE)
- {
- if (data_ret)
- {
- *data_ret = malloc(size * sizeof(char) + 1);
- if (!*data_ret) return EINA_FALSE;
- memcpy(*data_ret, data, size);
- ((char**)(data_ret))[0][size] = 0;
- if (size_ret) *size_ret = size;
- return EINA_TRUE;
- }
- }
- else if ((formats & ELM_SEL_FORMAT_MARKUP) ||
- (formats & ELM_SEL_FORMAT_HTML))
- {
- *data_ret = _elm_util_mkup_to_text(data);
- if (size_ret && *data_ret) *size_ret = strlen(*data_ret);
- }
- else if (formats & ELM_SEL_FORMAT_TEXT)
- {
- *data_ret = strdup(data);
- if (size_ret && *data_ret) *size_ret = strlen(*data_ret);
- }
- else if (formats & ELM_SEL_FORMAT_IMAGE)
- {
- cnp_debug("Image %s\n", evas_object_type_get(sel->widget));
- evas_object_image_file_get(elm_photocam_internal_image_get(sel->widget),
- (const char **)data_ret, NULL);
- if (!*data_ret) *data_ret = strdup("No file");
- else *data_ret = strdup(*data_ret);
-
- if (!*data_ret)
- {
- ERR("Failed to allocate memory!");
- *size_ret = 0;
- return EINA_FALSE;
- }
-
- if (size_ret) *size_ret = strlen(*data_ret);
- }
- return EINA_TRUE;
-}
-
-static void
-_wl_selection_parser(void *_data, int size, char ***ret_data, int *ret_count)
-{
- char **files = NULL;
- int num_files = 0;
- char *data = NULL;
-
- data = malloc(size);
- if (data && (size > 0))
- {
- int i, is;
- char *tmp;
- char **t2;
-
- memcpy(data, _data, size);
- if (data[size - 1])
- {
- char *t;
-
- /* Isn't nul terminated */
- size++;
- t = realloc(data, size);
- if (!t) goto done;
- data = t;
- data[size - 1] = 0;
- }
-
- tmp = malloc(size);
- if (!tmp) goto done;
- i = 0;
- is = 0;
- while ((is < size) && (data[is]))
- {
- if ((i == 0) && (data[is] == '#'))
- for (; ((data[is]) && (data[is] != '\n')); is++) ;
- else
- {
- if ((data[is] != '\r') && (data[is] != '\n'))
- tmp[i++] = data[is++];
- else
- {
- while ((data[is] == '\r') || (data[is] == '\n'))
- is++;
- tmp[i] = 0;
- num_files++;
- t2 = realloc(files, num_files * sizeof(char *));
- if (t2)
- {
- files = t2;
- files[num_files - 1] = strdup(tmp);
- }
- else
- {
- num_files--;
- goto freetmp;
- }
- tmp[0] = 0;
- i = 0;
- }
- }
- }
- if (i > 0)
- {
- tmp[i] = 0;
- num_files++;
- t2 = realloc(files, num_files * sizeof(char *));
- if (t2)
- {
- files = t2;
- files[num_files - 1] = strdup(tmp);
- }
- else
- {
- num_files--;
- goto freetmp;
- }
- }
-freetmp:
- free(tmp);
- }
-done:
- free(data);
- if (ret_data) *ret_data = files;
- else
- {
- int i;
-
- for (i = 0; i < num_files; i++) free(files[i]);
- free(files);
- }
- if (ret_count) *ret_count = num_files;
-}
-
-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 EINA_UNUSED)
-{
- cnp_debug("In\n");
-
- ddata->format = ELM_SEL_FORMAT_MARKUP;
- ddata->data = eina_memdup((unsigned char *)ev->data, ev->len, EINA_TRUE);
- ddata->len = ev->len;
- ddata->action = sel->action;
-
- return EINA_TRUE;
-}
-
-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 EINA_UNUSED)
-{
- char *p, *stripstr = NULL;
- char *data = ev->data;
- Dropable *drop;
- const char *type = NULL;
-
- cnp_debug("In\n");
-
- drop = efl_key_data_get(sel->requestwidget, "__elm_dropable");
- if (drop) type = drop->last.type;
-
- if ((type) && (!strcmp(type, "text/uri-list")))
- {
- int num_files = 0;
- char **files = NULL;
- Efreet_Uri *uri;
- Eina_Strbuf *strbuf;
- int i;
-
- strbuf = eina_strbuf_new();
- if (!strbuf) return EINA_FALSE;
-
- _wl_selection_parser(ev->data, ev->len, &files, &num_files);
- cnp_debug("got a files list\n");
-
- for (i = 0; i < num_files; i++)
- {
- uri = efreet_uri_decode(files[i]);
- if (uri)
- {
- eina_strbuf_append(strbuf, uri->path);
- efreet_uri_free(uri);
- }
- else
- {
- eina_strbuf_append(strbuf, files[i]);
- }
- if (i < (num_files - 1))
- eina_strbuf_append(strbuf, "\n");
- free(files[i]);
- }
- free(files);
- stripstr = eina_strbuf_string_steal(strbuf);
- eina_strbuf_free(strbuf);
- }
- else
- {
- Efreet_Uri *uri;
-
- p = (char *)eina_memdup((unsigned char *)data, ev->len, EINA_TRUE);
- if (!p) return EINA_FALSE;
- uri = efreet_uri_decode(p);
- if (!uri)
- {
- /* Is there any reason why we care of URI without scheme? */
- if (p[0] == '/') stripstr = p;
- else free(p);
- }
- else
- {
- free(p);
- stripstr = strdup(uri->path);
- efreet_uri_free(uri);
- }
- }
-
- if (!stripstr)
- {
- cnp_debug("Couldn't find a file\n");
- return EINA_FALSE;
- }
- free(savedtypes.imgfile);
-
- ddata->data = stripstr;
- ddata->len = strlen(stripstr);
- ddata->action = sel->action;
- ddata->format = sel->requestformat;
-
- return EINA_TRUE;
-}
-
-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 EINA_UNUSED)
-{
- cnp_debug("In\n");
-
- ddata->format = ELM_SEL_FORMAT_VCARD;
- ddata->data = eina_memdup((unsigned char *)ev->data, ev->len, EINA_TRUE);
- ddata->len = ev->len;
- ddata->action = sel->action;
-
- return EINA_TRUE;
-}
-
-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)
-{
- cnp_debug("In\n");
- Tmp_Info *tmp;
- int len = 0;
-
- tmp = _tempfile_new(ev->len);
- if (!tmp)
- return EINA_FALSE;
- memcpy(tmp->map, ev->data, ev->len);
- munmap(tmp->map, ev->len);
-
- len = strlen(tmp->filename);
- ddata->format = ELM_SEL_FORMAT_IMAGE;
- ddata->data = eina_memdup((unsigned char*)tmp->filename, len, EINA_TRUE);
- ddata->len = len;
- ddata->action = sel->action;
- *tmp_info = tmp;
-
- return EINA_TRUE;
-}
-
-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 EINA_UNUSED)
-{
- cnp_debug("In\n");
-
- ddata->format = ELM_SEL_FORMAT_TEXT;
- ddata->data = eina_memdup((unsigned char *)ev->data, ev->len, EINA_TRUE);
- ddata->len = ev->len;
- ddata->action = sel->action;
-
- return EINA_TRUE;
-}
-
-static void
-_wl_sel_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
-{
- Wl_Cnp_Selection *sel = data;
- if (sel->widget == obj)
- {
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
- sel->widget = NULL;
- }
- if (dragwidget == obj) dragwidget = NULL;
-}
-
-static Ecore_Wl2_Input *
-_wl_default_seat_get(Ecore_Wl2_Window *win, Evas_Object *obj)
-{
- Eo *seat, *parent2, *ewin;
-
- if (obj)
- {
- // FIXME (there might be a better solution):
- // In case of inwin, we want to use the main wl2 window for cnp, but obj
- // obj belongs to the buffer canvas, so the default seat for obj does not
- // match the window win.
- Eo *top = elm_widget_top_get(obj);
- if (efl_isa(top, EFL_UI_WIN_INLINED_CLASS))
- {
- parent2 = efl_ui_win_inlined_parent_get(top);
- if (parent2) obj = elm_widget_top_get(parent2) ?: parent2;
- }
- /* fake win means canvas seat id will not match protocol seat id */
- ewin = elm_win_get(obj);
- if (elm_win_type_get(ewin) == ELM_WIN_FAKE) obj = NULL;
- }
-
- if (!obj)
- {
- Ecore_Wl2_Input *input;
- Eina_Iterator *it;
- it = ecore_wl2_display_inputs_get(ecore_wl2_window_display_get(win));
- EINA_ITERATOR_FOREACH(it, input) break;
- eina_iterator_free(it);
- return input;
- }
-
- seat = evas_default_device_get(evas_object_evas_get(obj), EFL_INPUT_DEVICE_TYPE_SEAT);
- EINA_SAFETY_ON_NULL_RETURN_VAL(seat, NULL);
- return ecore_wl2_display_input_find(ecore_wl2_window_display_get(win),
- evas_device_seat_id_get(seat));
-}
-
-static void
-_wl_sel_obj_del2(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
-{
- Wl_Cnp_Selection *sel = data;
- if (sel->requestwidget == obj) sel->requestwidget = NULL;
-}
-
-static Eina_Bool
-_wl_elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format, const void *selbuf, size_t buflen)
-{
- Ecore_Wl2_Window *win;
- Wl_Cnp_Selection *sel = &wl_cnp_selection;
-
- if ((!selbuf) && (format != ELM_SEL_FORMAT_IMAGE))
- return elm_object_cnp_selection_clear(obj, selection);
-
- if (buflen <= 0)
- return EINA_FALSE;
-
- _wl_elm_cnp_init();
-
- win = _wl_elm_widget_window_get(obj);
-
- if ((sel->widget != obj) && sel->loss_cb)
- sel->loss_cb(sel->loss_data, selection);
-
- if (sel->widget)
- evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
- _wl_sel_obj_del, &wl_cnp_selection);
- sel->active = EINA_TRUE;
- sel->seltype = selection;
- sel->widget = obj;
- sel->win = win;
- /* sel->set(win, &selection, sizeof(Elm_Sel_Type)); */
- sel->format = format;
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
-
- evas_object_event_callback_add
- (sel->widget, EVAS_CALLBACK_DEL, _wl_sel_obj_del, &wl_cnp_selection);
-
- if (selbuf)
- {
- int i = 0, count = 0;
- Eina_Bool is_uri = EINA_FALSE;
- const char **types;
-
- if (format & ELM_SEL_FORMAT_IMAGE)
- {
- /* FIXME */
- // selbuf is actual image data, not text/string
- sel->selbuf = malloc(buflen + 1);
- if (!sel->selbuf)
- {
- elm_object_cnp_selection_clear(obj, selection);
- return EINA_FALSE;
- }
- memcpy(sel->selbuf, selbuf, buflen);
- sel->selbuf[buflen] = 0;
- }
- else
- {
- free(sel->selbuf);
- sel->buflen = buflen;
- sel->selbuf = strdup((char*)selbuf);
- }
-
- is_uri = _wl_is_uri_type_data(selbuf, buflen);
- types = malloc(sizeof(char *));
- if (!types) return EINA_FALSE;
- for (i = 0, count = 1; i < CNP_N_ATOMS; i++)
- {
- if (format & _atoms[i].formats)
- {
- if ((is_uri) ||
- ((!is_uri) && strcmp(_atoms[i].name, "text/uri-list")))
- {
- const char **t = NULL;
-
- types[count - 1] = _atoms[i].name;
- count++;
- t = realloc(types, sizeof(char *) * count);
- if (!t)
- {
- free(types);
- return EINA_FALSE;
- }
- types = t;
- }
- }
- }
- types[count - 1] = 0;
-
- sel->selection_serial = ecore_wl2_dnd_selection_set(_wl_default_seat_get(win, obj), types);
-
- free(types);
- return _local_elm_cnp_selection_set(obj, selection, format, selbuf, buflen);
- }
- else
- {
- sel->selbuf = NULL;
- }
-
- return EINA_FALSE;
-}
-
-
-static Elm_Xdnd_Action
-_wl_to_elm(Ecore_Wl2_Drag_Action action)
-{
- #define CONV(wl, elm) if (action == wl) return elm;
- CONV(ECORE_WL2_DRAG_ACTION_COPY, ELM_XDND_ACTION_COPY);
- CONV(ECORE_WL2_DRAG_ACTION_MOVE, ELM_XDND_ACTION_MOVE);
- CONV(ECORE_WL2_DRAG_ACTION_ASK, ELM_XDND_ACTION_ASK);
- #undef CONV
- return ELM_XDND_ACTION_UNKNOWN;
-}
-
-typedef struct {
- Ecore_Wl2_Offer *offer;
-
- Evas_Object *requestwidget;
- Elm_Drop_Cb drop_cb;
- void *drop_cb_data;
- Elm_Sel_Format format;
-
- Ecore_Event_Handler *handler;
-} Selection_Ready;
-
-static void
-_wl_selection_receive_timeout(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
-{
- Selection_Ready *ready = data;
-
- if (ready->requestwidget != obj) return;
-
- ecore_event_handler_del(ready->handler);
- free(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;
-
- if (ready->offer != ev->offer) return ECORE_CALLBACK_PASS_ON;
-
- if (ready->drop_cb)
- {
- Elm_Selection_Data sdata;
-
- sdata.x = sdata.y = 0;
- sdata.format = ready->format;
- sdata.data = ev->data;
- sdata.len = ev->len;
- sdata.action = _wl_to_elm(ecore_wl2_offer_action_get(ready->offer));
- ready->drop_cb(ready->drop_cb_data,
- ready->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(ready->requestwidget, mkupstr);
- free(stripstr);
- free(mkupstr);
- }
-
- evas_object_event_callback_del_full(ready->requestwidget,
- EVAS_CALLBACK_DEL,
- _wl_selection_receive_timeout, ready);
-
- ecore_event_handler_del(ready->handler);
- free(data);
- return ECORE_CALLBACK_CANCEL;
-}
-
-typedef struct _Format_Translation{
- Elm_Sel_Format format;
- char **translates;
-}Format_Translation;
-
-char *markup[] = {"application/x-elementary-markup", "", NULL};
-char *text[] = {"text/plain;charset=utf-8", "text/plain", NULL};
-char *html[] = {"text/html;charset=utf-8", "text/html", NULL};
-char *vcard[] = {"text/x-vcard", NULL};
-char *image[] = {"image/", "text/uri-list", NULL};
-
-Format_Translation convertion[] = {
- {ELM_SEL_FORMAT_MARKUP, markup},
- {ELM_SEL_FORMAT_TEXT, text},
- {ELM_SEL_FORMAT_HTML, html},
- {ELM_SEL_FORMAT_VCARD, vcard},
- {ELM_SEL_FORMAT_IMAGE, image},
- {ELM_SEL_FORMAT_NONE, NULL},
-};
-
-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;
- Ecore_Wl2_Input *input;
- Ecore_Wl2_Offer *offer;
- int i = 0;
- //Wl_Cnp_Selection *sel = &wl_cnp_selection;
-
- _wl_elm_cnp_init();
-
- if (selection == ELM_SEL_TYPE_XDND) return EINA_FALSE;
-
- //if (sel->active)
- //return _local_elm_cnp_selection_get(obj, selection, format, datacb, udata);
- win = _wl_elm_widget_window_get(obj);
-
- input = _wl_default_seat_get(win, (void*)obj);
- offer = ecore_wl2_dnd_selection_get(input);
-
- //there can be no selection available
- if (!offer) return EINA_FALSE;
-
- for (i = 0; convertion[i].translates; i++)
- {
- int j = 0;
- if (!(format & convertion[i].format)) continue;
-
- for (j = 0; convertion[i].translates[j]; j++)
- {
- if (!ecore_wl2_offer_supports_mime(offer, convertion[i].translates[j])) continue;
-
- //we have found mathing mimetypes
- Selection_Ready *ready;
-
- ready = calloc(1, sizeof(Selection_Ready));
-
- ready->requestwidget = (Evas_Object *) obj;
- ready->drop_cb = datacb;
- ready->drop_cb_data = udata;
- ready->offer = offer;
- ready->format = convertion[i].format;
-
- evas_object_event_callback_add(ready->requestwidget, EVAS_CALLBACK_DEL,
- _wl_selection_receive_timeout, ready);
- ready->handler = ecore_event_handler_add(ECORE_WL2_EVENT_OFFER_DATA_READY, _wl_selection_receive, ready);
-
- ecore_wl2_offer_receive(offer, (char*)convertion[i].translates[j]);
- return EINA_TRUE;
- }
- }
-
- return EINA_FALSE;
-}
-
-static void
-_wl_elm_cnp_selection_loss_callback_set(Evas_Object *obj EINA_UNUSED, Elm_Sel_Type selection EINA_UNUSED, Elm_Selection_Loss_Cb func, const void *data)
-{
- Wl_Cnp_Selection *sel = &wl_cnp_selection;
-
- _wl_elm_cnp_init();
-
- sel->loss_cb = func;
- sel->loss_data = (void *)data;
-}
-
-static Eina_Bool
-_wl_elm_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type selection EINA_UNUSED)
-{
- Wl_Cnp_Selection *sel = &wl_cnp_selection;
-
- _wl_elm_cnp_init();
-
- if ((!sel->active) || (sel->widget != obj))
- return EINA_TRUE;
-
- if (sel->widget)
- evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
- _wl_sel_obj_del, &wl_cnp_selection);
- if (sel->requestwidget)
- evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
- _wl_sel_obj_del2, &wl_cnp_selection);
-
- sel->widget = NULL;
- sel->requestwidget = NULL;
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
-
- sel->active = EINA_FALSE;
- ELM_SAFE_FREE(sel->selbuf, free);
- sel->buflen = 0;
- /* sel->clear(); */
- sel->selection_serial = ecore_wl2_dnd_selection_clear(_wl_default_seat_get(_wl_elm_widget_window_get(obj), obj));
-
- return _local_elm_object_cnp_selection_clear(obj, selection);
-}
-
-static void
-_wl_selection_changed_free(void *data, void *ev EINA_UNUSED)
-{
- ecore_wl2_display_disconnect(data);
-}
-
-static Eina_Bool
-_wl_selection_changed(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
-{
- Elm_Cnp_Event_Selection_Changed *e;
- Ecore_Wl2_Event_Seat_Selection *ev = event;
- Ecore_Wl2_Input *seat;
-
- seat = ecore_wl2_display_input_find(ev->display, ev->seat);
- EINA_SAFETY_ON_NULL_RETURN_VAL(seat, ECORE_CALLBACK_RENEW);
- e = calloc(1, sizeof(Elm_Cnp_Event_Selection_Changed));
- EINA_SAFETY_ON_NULL_RETURN_VAL(e, ECORE_CALLBACK_RENEW);
- e->type = ELM_SEL_TYPE_CLIPBOARD;
- e->seat_id = ev->seat;
- /* connect again to add ref */
- e->display = ecore_wl2_display_connect(ecore_wl2_display_name_get(ev->display));
- e->exists = !!ecore_wl2_dnd_selection_get(seat);
- ecore_event_add(ELM_CNP_EVENT_SELECTION_CHANGED, e, _wl_selection_changed_free, ev->display);
- return ECORE_CALLBACK_RENEW;
-}
-
-static Eina_Bool
-_wl_selection_send(void *data, int type EINA_UNUSED, void *event)
-{
- char *buf;
- int ret, len_remained;
- int len_written = 0;
- Wl_Cnp_Selection *sel;
- Ecore_Wl2_Event_Data_Source_Send *ev;
- void *data_ret = NULL;
- int len_ret = 0;
- int i = 0;
-
- _wl_elm_cnp_init();
- cnp_debug("In\n");
- ev = event;
- sel = data;
- if ((ev->serial != sel->selection_serial) &&
- (ev->serial != sel->drag_serial))
- return ECORE_CALLBACK_RENEW;
-
- for (i = 0; i < CNP_N_ATOMS; i++)
- {
- if (!strcmp(_atoms[i].name, ev->type))
- {
- cnp_debug("Found a type: %s\n", _atoms[i].name);
- Dropable *drop;
- drop = efl_key_data_get(sel->requestwidget, "__elm_dropable");
- if (drop)
- drop->last.type = _atoms[i].name;
- if (_atoms[i].wl_converter)
- {
- _atoms[i].wl_converter(ev->type, sel, sel->selbuf,
- sel->buflen, &data_ret, &len_ret);
- }
- else
- {
- data_ret = strdup(sel->selbuf);
- len_ret = sel->buflen;
- }
- break;
- }
- }
-
- len_remained = len_ret;
- buf = data_ret;
- cnp_debug("write: %s", buf);
-
- while (len_written < len_ret)
- {
- ret = write(ev->fd, buf, len_remained);
- if (ret == -1) break;
- buf += ret;
- len_written += ret;
- len_remained -= ret;
- }
- free(data_ret);
-
- close(ev->fd);
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_wl_elm_cnp_init(void)
-{
- static int _init_count = 0;
-
- if (_init_count > 0) return EINA_TRUE;
- _init_count++;
-
- ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_SEND,
- _wl_selection_send, &wl_cnp_selection);
- ecore_event_handler_add(ECORE_WL2_EVENT_SEAT_SELECTION,
- _wl_selection_changed, NULL);
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_wl_elm_dnd_init(void)
-{
- static int _init_count = 0;
-
- if (_init_count > 0) return EINA_TRUE;
- _init_count++;
-
- text_uri = eina_stringshare_add("text/uri-list");
-
- _wl_elm_cnp_init();
- ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_END,
- _wl_dnd_end, &wl_cnp_selection);
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_wl_elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format, Elm_Drag_State entercb, void *enterdata, Elm_Drag_State leavecb, void *leavedata, Elm_Drag_Pos poscb, void *posdata, Elm_Drop_Cb dropcb, void *dropdata)
-{
- Dropable *dropable = NULL;
- Dropable_Cbs *cbs = NULL;
-
- Eina_Bool first = !drops;
-
- cbs = calloc(1, sizeof(*cbs));
- if (!cbs) return EINA_FALSE;
-
- cbs->entercb = entercb;
- cbs->enterdata = enterdata;
- cbs->leavecb = leavecb;
- cbs->leavedata = leavedata;
- cbs->poscb = poscb;
- cbs->posdata = posdata;
- cbs->dropcb = dropcb;
- cbs->dropdata = dropdata;
- cbs->types = format;
-
- dropable = efl_key_data_get(obj, "__elm_dropable");
- if (!dropable)
- {
- /* Create new drop */
- dropable = calloc(1, sizeof(Dropable));
- if (!dropable) goto error;
- drops = eina_list_append(drops, dropable);
- if (!drops) goto error;
- dropable->obj = obj;
- efl_key_data_set(obj, "__elm_dropable", dropable);
- }
-
- dropable->cbs_list =
- eina_inlist_append(dropable->cbs_list, EINA_INLIST_GET(cbs));
-
- evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
- _all_drop_targets_cbs_del, obj);
-
- if (first)
- {
- handler_enter =
- ecore_event_handler_add(ECORE_WL2_EVENT_DND_ENTER,
- _wl_dnd_enter, NULL);
- handler_leave =
- ecore_event_handler_add(ECORE_WL2_EVENT_DND_LEAVE,
- _wl_dnd_leave, NULL);
- handler_pos =
- ecore_event_handler_add(ECORE_WL2_EVENT_DND_MOTION,
- _wl_dnd_position, NULL);
- handler_drop =
- ecore_event_handler_add(ECORE_WL2_EVENT_DND_DROP,
- _wl_dnd_drop, NULL);
- _wl_elm_dnd_init();
- }
-
- return EINA_TRUE;
-error:
- free(cbs);
- free(dropable);
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_wl_elm_drop_target_del(Evas_Object *obj, Elm_Sel_Format format,
- Elm_Drag_State entercb, void *enterdata,
- Elm_Drag_State leavecb, void *leavedata,
- Elm_Drag_Pos poscb, void *posdata,
- Elm_Drop_Cb dropcb, void *dropdata)
-{
-
- if (!_local_elm_drop_target_del(obj, format, entercb, enterdata,
- leavecb, leavedata, poscb, posdata, dropcb, dropdata))
- {
- return EINA_FALSE;
- }
-
- if (!drops)
- {
- ELM_SAFE_FREE(handler_pos, ecore_event_handler_del);
- ELM_SAFE_FREE(handler_drop, ecore_event_handler_del);
- ELM_SAFE_FREE(handler_enter, ecore_event_handler_del);
- ELM_SAFE_FREE(handler_leave, ecore_event_handler_del);
- }
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_wl_elm_drag_action_set(Evas_Object *obj, Elm_Xdnd_Action action)
-{
- if (!dragwin) return EINA_FALSE;
- if (dragwidget != obj) return EINA_FALSE;
- if (dragaction == action) return EINA_TRUE;
- dragaction = action;
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_wl_elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data,
- Elm_Xdnd_Action action,
- Elm_Drag_Icon_Create_Cb createicon, void *createdata,
- Elm_Drag_Pos dragpos, void *dragdata,
- Elm_Drag_Accept acceptcb, void *acceptdata,
- Elm_Drag_State dragdone, void *donecbdata)
-{
- Ecore_Evas *ee;
- Evas_Object *icon = NULL;
- int x, y, x2 = 0, y2 = 0, x3, y3, w = 0, h = 0;
- const char *types[CNP_N_ATOMS + 1];
- int i, nb_types = 0;
- Ecore_Wl2_Window *parent = NULL, *win;
-
- _wl_elm_dnd_init();
-
- /* if we already have a drag, get out */
- if (dragwin) return EINA_FALSE;
-
- for (i = CNP_ATOM_LISTING_ATOMS + 1; i < CNP_N_ATOMS; i++)
- {
- if (format == ELM_SEL_FORMAT_TARGETS || (_atoms[i].formats & format))
- {
- types[nb_types++] = _atoms[i].name;
- cnp_debug("set dnd type: %s\n", _atoms[i].name);
- }
- }
- types[nb_types] = NULL;
-
- win = _wl_elm_widget_window_get(obj);
- ecore_wl2_dnd_drag_types_set(_wl_default_seat_get(win, obj), types);
-
- /* set the drag data used when a drop occurs */
- free(wl_cnp_selection.selbuf);
- wl_cnp_selection.buflen = 0;
- wl_cnp_selection.selbuf = eina_strdup(data);
-
- if (data)
- {
- wl_cnp_selection.buflen = strlen(wl_cnp_selection.selbuf);
- }
-
- /* setup callback to notify if this object gets deleted */
- evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
- _wl_drag_source_del, obj);
-
- dragwidget = obj;
- dragaction = action;
- dragposcb = dragpos;
- dragposdata = dragdata;
- dragacceptcb = acceptcb;
- dragacceptdata = acceptdata;
- dragdonecb = dragdone;
- dragdonedata = donecbdata;
-
- dragwin = elm_win_add(NULL, "Elm-Drag", ELM_WIN_DND);
- elm_win_alpha_set(dragwin, EINA_TRUE);
- elm_win_borderless_set(dragwin, EINA_TRUE);
- elm_win_override_set(dragwin, EINA_TRUE);
-
- win = elm_win_wl_window_get(dragwin);
-
- if (createicon)
- {
- Evas_Coord xoff = 0, yoff = 0;
-
- icon = createicon(createdata, dragwin, &xoff, &yoff);
- if (icon)
- {
- x2 = xoff;
- y2 = yoff;
- evas_object_geometry_get(icon, NULL, NULL, &w, &h);
- }
- }
- else
- {
- icon = elm_icon_add(dragwin);
- evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND,
- EVAS_HINT_EXPAND);
- }
-
- elm_win_resize_object_add(dragwin, icon);
- evas_object_show(icon);
-
- /* Position subwindow appropriately */
- ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
- ecore_evas_geometry_get(ee, &x, &y, NULL, NULL);
- x += x2;
- y += y2;
- dragwin_x_start = dragwin_x_end = x;
- dragwin_y_start = dragwin_y_end = y;
-
- evas_object_move(dragwin, x, y);
- evas_object_resize(dragwin, w, h);
- evas_object_show(dragwin);
-
- evas_pointer_canvas_xy_get(evas_object_evas_get(obj), &x3, &y3);
- _dragx = x3 - x2;
- _dragy = y3 - y2;
-
- if (elm_widget_is(obj))
- {
- Evas_Object *top;
-
- top = elm_widget_top_get(obj);
- if (!top) top = elm_widget_top_get(elm_widget_parent_widget_get(obj));
- if (top && (efl_isa(top, EFL_UI_WIN_CLASS)))
- parent = elm_win_wl_window_get(top);
- }
- if (!parent)
- {
- Evas *evas;
-
- if (!(evas = evas_object_evas_get(obj)))
- return EINA_FALSE;
- if (!(ee = ecore_evas_ecore_evas_get(evas)))
- return EINA_FALSE;
-
- parent = ecore_evas_wayland2_window_get(ee);
- }
-
- wl_cnp_selection.drag_serial = ecore_wl2_dnd_drag_start(_wl_default_seat_get(win, obj), parent, win);
-
- return EINA_TRUE;
-}
-
-static void
-_wl_drag_source_del(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
-{
- if (dragwidget == obj)
- dragwidget = NULL;
-}
-
-static Eina_Bool
-_wl_dnd_enter(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
-{
- Ecore_Wl2_Event_Dnd_Enter *ev;
- Eina_Array *known, *available;
- unsigned int i = 0;
-
- ev = event;
-
- available = ecore_wl2_offer_mimes_get(ev->offer);
-
- free(savedtypes.types);
-
- savedtypes.ntypes = eina_array_count(available);
- savedtypes.types = malloc(sizeof(char *) * savedtypes.ntypes);
- if (!savedtypes.types) return EINA_FALSE;
-
- known = eina_array_new(5);
-
- for (i = 0; i < eina_array_count(available); i++)
- {
- savedtypes.types[i] =
- eina_stringshare_add(eina_array_data_get(available, i));
- if (savedtypes.types[i] == text_uri)
- {
- savedtypes.textreq = 1;
- ELM_SAFE_FREE(savedtypes.imgfile, free);
- }
- }
-
- doaccept = EINA_FALSE;
- for (i = 0; i < eina_array_count(available); i++)
- {
- if (_wl_drops_accept(eina_array_data_get(available, i)))
- {
- eina_array_push(known, strdup(eina_array_data_get(available, i)));
- }
- }
-
- ecore_wl2_offer_mimes_set(ev->offer, known);
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_wl_dnd_leave(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
-{
- Ecore_Wl2_Event_Dnd_Leave *ev;
- Dropable *drop;
- cnp_debug("In\n");
-
- ev = event;
- if ((drop = _wl_dropable_find(ev->win)))
- {
- _wl_dropable_handle(NULL, 0, 0);
- _wl_dropable_all_clean(ev->win);
- }
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static Eina_Bool
-_wl_dnd_position(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
-{
- Ecore_Wl2_Event_Dnd_Motion *ev;
- Dropable *drop;
- Eina_Bool will_accept = EINA_FALSE;
-
- ev = event;
-
- cnp_debug("mouse pos %i %i\n", ev->x, ev->y);
-
- dragwin_x_end = ev->x - _dragx;
- dragwin_y_end = ev->y - _dragy;
-
- drop = _wl_dropable_find(ev->win);
-
- if (drop)
- {
- Evas_Coord x = 0, y = 0;
- Evas *evas = NULL;
- Eina_List *dropable_list = NULL;
-
- x = ev->x;
- y = ev->y;
- _dropable_coords_adjust(drop, &x, &y);
- evas = _wl_evas_get_from_win(ev->win);
- if (evas)
- dropable_list = _dropable_list_geom_find(evas, x, y);
-
- /* check if there is dropable (obj) can accept this drop */
- if (dropable_list)
- {
- Elm_Sel_Format saved_format;
- Eina_List *l;
- Eina_Bool found = EINA_FALSE;
- Dropable *dropable = NULL;
-
- saved_format =
- _dnd_types_to_format(savedtypes.types, savedtypes.ntypes);
-
- EINA_LIST_FOREACH(dropable_list, l, dropable)
- {
- Dropable_Cbs *cbs;
- Eina_Inlist *itr;
-
- EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
- {
- Elm_Sel_Format common_fmt = saved_format & cbs->types;
-
- if (common_fmt)
- {
- /* We found a target that can accept this type of data */
- int i, min_index = CNP_N_ATOMS;
-
- /* We have to find the first atom that corresponds to one
- * of the supported data types. */
- for (i = 0; i < savedtypes.ntypes; i++)
- {
- Cnp_Atom *atom;
-
- atom = eina_hash_find(_types_hash,
- savedtypes.types[i]);
- if (atom && (atom->formats & common_fmt))
- {
- int atom_idx = (atom - _atoms);
-
- if (min_index > atom_idx)
- min_index = atom_idx;
- }
- }
- if (min_index != CNP_N_ATOMS)
- {
- cnp_debug("Found atom %s\n", _atoms[min_index].name);
- found = EINA_TRUE;
- dropable->last.type = _atoms[min_index].name;
- dropable->last.format = common_fmt;
- break;
- }
- }
- }
- if (found) break;
- }
- if (found)
- {
- Evas_Coord ox = 0, oy = 0;
-
- evas_object_geometry_get(dropable->obj, &ox, &oy, NULL, NULL);
-
- cnp_debug("Candidate %p (%s)\n",
- dropable->obj, efl_class_name_get(efl_class_get(dropable->obj)));
- _wl_dropable_handle(dropable, x - ox, y - oy);
- wl_cnp_selection.requestwidget = dropable->obj;
- will_accept = EINA_TRUE;
- }
- else
- {
- //if not: send false status
- cnp_debug("dnd position (%d, %d) not in obj\n", x, y);
- _wl_dropable_handle(NULL, 0, 0);
- // CCCCCCC: call dnd exit on last obj
- }
- eina_list_free(dropable_list);
- }
- }
-
- doaccept = will_accept;
-
- if (dragacceptcb)
- dragacceptcb(dragacceptdata, wl_cnp_selection.requestwidget, will_accept);
-
- 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);
- if (action == ECORE_WL2_DRAG_ACTION_ASK)
- ecore_wl2_offer_actions_set(ev->offer, ECORE_WL2_DRAG_ACTION_COPY, ECORE_WL2_DRAG_ACTION_COPY);
- action = ecore_wl2_offer_action_get(ev->offer);
-
- wl_cnp_selection.action = _wl_to_elm(action);
-
- _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)
-{
- Ecore_Wl2_Event_Dnd_Drop *ev;
- Ecore_Wl2_Window *win;
- Dropable *drop;
- Eina_List *l;
-
- cnp_debug("In\n");
- ev = event;
- savedtypes.x = ev->x;
- savedtypes.y = ev->y;
-
- EINA_LIST_FOREACH(drops, l, drop)
- {
- if (drop->last.in)
- {
- cnp_debug("Request data of type %s\n", drop->last.type);
- wl_cnp_selection.requestwidget = drop->obj;
- wl_cnp_selection.requestformat = drop->last.format;
- evas_object_event_callback_add(wl_cnp_selection.requestwidget,
- EVAS_CALLBACK_DEL, _wl_sel_obj_del2,
- &wl_cnp_selection);
-
- win = _wl_elm_widget_window_get(drop->obj);
- 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;
- }
- }
-
- win = ecore_wl2_display_window_find(_elm_wl_display, ev->win);
- ecore_wl2_dnd_drag_end(_wl_default_seat_get(win, 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;
- Ecore_Wl2_Window *win;
-
- cnp_debug("In\n");
-
- ev = event;
- if (ev->serial != wl_cnp_selection.drag_serial)
- return ECORE_CALLBACK_RENEW;
- if (dragdonecb) dragdonecb(dragdonedata, dragwidget);
-
- if (dragwin)
- {
- if (!doaccept)
- {
- /* Commit animation when drag cancelled */
- /* Record final position of dragwin, then do animation */
- ecore_animator_timeline_add(0.3, _drag_cancel_animate, dragwin);
- }
- else
- {
- /* No animation drop was committed */
- evas_object_del(dragwin);
- }
- dragwin = NULL; /* if not freed here, free in end of anim */
- }
-
- dragdonecb = NULL;
- dragacceptcb = NULL;
- dragposcb = NULL;
- dragwidget = NULL;
- doaccept = EINA_FALSE;
-
- win = ecore_wl2_display_window_find(_elm_wl_display, ev->win);
- ecore_wl2_input_ungrab(_wl_default_seat_get(win, NULL));
-
- return ECORE_CALLBACK_PASS_ON;
-}
-
-static void
-_wl_dropable_data_handle(Wl_Cnp_Selection *sel, Ecore_Wl2_Event_Offer_Data_Ready *ev)
-{
- Dropable *drop;
- Ecore_Wl2_Window *win;
-
- cnp_debug("In\n");
- drop = efl_key_data_get(sel->requestwidget, "__elm_dropable");
- if (drop)
- {
- Cnp_Atom *atom = NULL;
-
- atom = eina_hash_find(_types_hash, drop->last.type);
- if (atom && atom->wl_data_preparer)
- {
- Elm_Selection_Data ddata;
- Tmp_Info *tmp_info = NULL;
- Eina_Bool success;
- ddata.data = NULL;
-
- cnp_debug("Call notify for: %s\n", atom->name);
- success = atom->wl_data_preparer(sel, &ddata, ev, &tmp_info);
- if (success)
- {
- Dropable *dropable;
- Eina_List *l;
-
- EINA_LIST_FOREACH(drops, l, dropable)
- {
- if (dropable->obj == sel->requestwidget) break;
- dropable = NULL;
- }
- if (dropable)
- {
- cnp_debug("call dropcb\n");
- Dropable_Cbs *cbs;
- Eina_Inlist *itr;
- ddata.x = savedtypes.x;
- ddata.y = savedtypes.y;
- EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
- if ((cbs->types & dropable->last.format) &&
- cbs->dropcb)
- cbs->dropcb(cbs->dropdata, dropable->obj, &ddata);
- }
- }
- win = _wl_elm_widget_window_get(sel->requestwidget);
- ecore_wl2_dnd_drag_end(_wl_default_seat_get(win, NULL));
- if (tmp_info) _tmpinfo_free(tmp_info);
- free(ddata.data);
- return;
- }
- }
-
- win = _wl_elm_widget_window_get(sel->requestwidget);
- ecore_wl2_dnd_drag_end(_wl_default_seat_get(win, NULL));
- savedtypes.textreq = 0;
-}
-
-static Dropable *
-_wl_dropable_find(unsigned int win)
-{
- Eina_List *l;
- Dropable *dropable;
- Ecore_Wl2_Window *window;
-
- if (!drops) return NULL;
-
- window = ecore_wl2_display_window_find(_elm_wl_display, win);
- if (!window) return NULL;
-
- EINA_LIST_FOREACH(drops, l, dropable)
- if (_wl_elm_widget_window_get(dropable->obj) == window)
- return dropable;
-
- return NULL;
-}
-
-static Evas *
-_wl_evas_get_from_win(unsigned int win)
-{
- Dropable *dropable = _wl_dropable_find(win);
- return dropable ? evas_object_evas_get(dropable->obj) : NULL;
-}
-
-static void
-_wl_dropable_handle(Dropable *drop, Evas_Coord x, Evas_Coord y)
-{
- Dropable *d, *last_dropable = NULL;
- Dropable_Cbs *cbs;
- Eina_Inlist *itr;
- Eina_List *l;
-
- EINA_LIST_FOREACH(drops, l, d)
- {
- if (d->last.in)
- {
- last_dropable = d;
- break;
- }
- }
-
- /* If we are on the same object, just update the position */
- if ((drop) && (last_dropable == drop))
- {
- EINA_INLIST_FOREACH_SAFE(drop->cbs_list, itr, cbs)
- if (cbs->poscb)
- cbs->poscb(cbs->posdata, drop->obj, x, y, dragaction);
- return;
- }
- /* We leave the last dropable */
- if (last_dropable)
- {
- EINA_INLIST_FOREACH_SAFE(last_dropable->cbs_list, itr, cbs)
- if (cbs->leavecb)
- cbs->leavecb(cbs->leavedata, last_dropable->obj);
- last_dropable->last.in = EINA_FALSE;
- }
- /* We enter the new dropable */
- if (drop)
- {
- EINA_INLIST_FOREACH_SAFE(drop->cbs_list, itr, cbs)
- if (cbs->entercb)
- cbs->entercb(cbs->enterdata, drop->obj);
- EINA_INLIST_FOREACH_SAFE(drop->cbs_list, itr, cbs)
- if (cbs->poscb)
- cbs->poscb(cbs->posdata, drop->obj, x, y, dragaction);
- drop->last.in = EINA_TRUE;
- }
-}
-
-static void
-_wl_dropable_all_clean(unsigned int win)
-{
- Eina_List *l;
- Dropable *dropable;
- Ecore_Wl2_Window *window;
-
- window = ecore_wl2_display_window_find(_elm_wl_display, win);
- if (!window) return;
-
- EINA_LIST_FOREACH(drops, l, dropable)
- {
- if (_wl_elm_widget_window_get(dropable->obj) == window)
- {
- dropable->last.x = 0;
- dropable->last.y = 0;
- dropable->last.in = EINA_FALSE;
- }
- }
-}
-
-static Eina_Bool
-_wl_drops_accept(const char *type)
-{
- Eina_List *l;
- Dropable *drop;
- Eina_Bool will_accept = EINA_FALSE;
-
- if (!type) return EINA_FALSE;
-
- EINA_LIST_FOREACH(drops, l, drop)
- {
- Dropable_Cbs *cbs;
- EINA_INLIST_FOREACH(drop->cbs_list, cbs)
- {
- for (int i = 0; convertion[i].translates ; ++i)
- {
- if (!(convertion[i].format & cbs->types)) continue;
-
- for (int j = 0; convertion[i].translates[j]; ++j)
- {
- if (!strncmp(type, convertion[i].translates[j], strlen(convertion[i].translates[j])))
- {
- wl_cnp_selection.requestwidget = drop->obj;
- return EINA_TRUE;
- }
- }
- }
- }
- }
-
- return will_accept;
-}
-
-static Ecore_Wl2_Window *
-_wl_elm_widget_window_get(const Evas_Object *obj)
-{
- Evas_Object *top;
- Ecore_Wl2_Window *win = NULL;
-
- if (elm_widget_is(obj))
- {
- top = elm_widget_top_get(obj);
- if (!top) top = elm_widget_top_get(elm_widget_parent_widget_get(obj));
- if (top && (efl_isa(top, EFL_UI_WIN_CLASS)))
- win = elm_win_wl_window_get(top);
- }
- if (!win)
- {
- Ecore_Evas *ee;
- Evas *evas;
- const char *engine_name;
-
- if (!(evas = evas_object_evas_get(obj)))
- return NULL;
- if (!(ee = ecore_evas_ecore_evas_get(evas)))
- return NULL;
-
- engine_name = ecore_evas_engine_name_get(ee);
- if (!strcmp(engine_name, ELM_BUFFER))
- {
- ee = ecore_evas_buffer_ecore_evas_parent_get(ee);
- if (!ee) return NULL;
- engine_name = ecore_evas_engine_name_get(ee);
- }
- if (!strncmp(engine_name, "wayland", sizeof("wayland") - 1))
- {
- /* In case the engine is not a buffer, we want to check once. */
- win = ecore_evas_wayland2_window_get(ee);
- if (!win) return NULL;
- }
- }
-
- return win;
-}
-
-#endif
-
-#ifdef HAVE_ELEMENTARY_COCOA
-
-typedef struct _Cocoa_Cnp_Selection Cocoa_Cnp_Selection;
-
-struct _Cocoa_Cnp_Selection
-{
- Ecore_Cocoa_Window *win;
- Evas_Object *widget;
- char *selbuf;
- int buflen;
- Evas_Object *requestwidget;
- void *udata;
- Elm_Sel_Format requestformat;
- Elm_Drop_Cb datacb;
-
- Elm_Selection_Loss_Cb loss_cb;
- void *loss_data;
- int pb_count;
-
- Elm_Sel_Format format;
-
- Eina_Bool active : 1;
-};
-
-static Cocoa_Cnp_Selection _cocoa_cnp_sel;
-
-static Ecore_Cocoa_Window *
-_cocoa_elm_widget_cocoa_window_get(const Evas_Object *obj)
-{
- Evas_Object *top, *par;
- Ecore_Cocoa_Window *win = NULL;
-
- if (elm_widget_is(obj))
- {
- top = elm_widget_top_get(obj);
- if (!top)
- {
- par = elm_widget_parent_widget_get(obj);
- if (par) top = elm_widget_top_get(par);
- }
- if ((top) && (efl_isa(top, EFL_UI_WIN_CLASS)))
- win = elm_win_cocoa_window_get(top);
- }
- if (!win)
- {
- // FIXME
- CRI("WIN has not been retrieved!!!");
- }
-
- return win;
-}
-
-static Ecore_Cocoa_Cnp_Type
-_elm_sel_format_to_ecore_cocoa_cnp_type(Elm_Sel_Format fmt)
-{
- Ecore_Cocoa_Cnp_Type type = 0;
-
- if ((fmt & ELM_SEL_FORMAT_TEXT) ||
- (fmt & ELM_SEL_FORMAT_VCARD))
- type |= ECORE_COCOA_CNP_TYPE_STRING;
- if (fmt & ELM_SEL_FORMAT_MARKUP)
- type |= ECORE_COCOA_CNP_TYPE_MARKUP;
- if (fmt & ELM_SEL_FORMAT_HTML)
- type |= ECORE_COCOA_CNP_TYPE_HTML;
- if (fmt & ELM_SEL_FORMAT_IMAGE)
- type |= ECORE_COCOA_CNP_TYPE_IMAGE;
-
- return type;
-}
-
-static void
-_cocoa_sel_obj_del_req_cb(void *data,
- Evas *e EINA_UNUSED,
- Evas_Object *obj,
- void *ev_info EINA_UNUSED)
-{
- Cocoa_Cnp_Selection *sel = data;
- if (sel->requestwidget == obj) sel->requestwidget = NULL;
-}
-
-static void
-_cocoa_sel_obj_del_cb(void *data,
- Evas *e EINA_UNUSED,
- Evas_Object *obj,
- void *ev_info EINA_UNUSED)
-{
- Cocoa_Cnp_Selection *sel = data;
- if (sel->widget == obj)
- {
- sel->widget = NULL;
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
- }
- if (dragwidget == obj) dragwidget = NULL;
-}
-
-static void
-_job_pb_cb(void *data)
-{
- Cocoa_Cnp_Selection *sel = data;
- Elm_Selection_Data ddata;
- Ecore_Cocoa_Cnp_Type type, get_type;
- void *pbdata;
- int pbdata_len;
-
- if (sel->datacb)
- {
- ddata.x = 0;
- ddata.y = 0;
-
- /* Pass to cocoa clipboard */
- type = _elm_sel_format_to_ecore_cocoa_cnp_type(sel->requestformat);
- pbdata = ecore_cocoa_clipboard_get(&pbdata_len, type, &get_type);
-
- ddata.format = ELM_SEL_FORMAT_NONE;
- if (get_type & ECORE_COCOA_CNP_TYPE_STRING)
- ddata.format |= ELM_SEL_FORMAT_TEXT;
- if (get_type & ECORE_COCOA_CNP_TYPE_MARKUP)
- ddata.format |= ELM_SEL_FORMAT_MARKUP;
- if (get_type & ECORE_COCOA_CNP_TYPE_IMAGE)
- ddata.format |= ELM_SEL_FORMAT_IMAGE;
- if (get_type & ECORE_COCOA_CNP_TYPE_HTML)
- ddata.format |= ELM_SEL_FORMAT_HTML;
-
- ddata.data = pbdata;
- ddata.len = pbdata_len;
- ddata.action = ELM_XDND_ACTION_UNKNOWN;
- sel->datacb(sel->udata, sel->requestwidget, &ddata);
- free(pbdata);
- }
-}
-
-static Eina_Bool
-_cocoa_elm_cnp_selection_set(Ecore_Cocoa_Window *win,
- Evas_Object *obj,
- Elm_Sel_Type selection,
- Elm_Sel_Format format,
- const void *selbuf,
- size_t buflen)
-{
- Cocoa_Cnp_Selection *sel = &_cocoa_cnp_sel;
- Ecore_Cocoa_Cnp_Type type;
- Eina_Bool ok = EINA_TRUE;
-
- if ((!selbuf) && (format != ELM_SEL_FORMAT_IMAGE))
- return elm_object_cnp_selection_clear(obj, selection);
- if (buflen <= 0) return EINA_FALSE;
-
- if (sel->loss_cb) sel->loss_cb(sel->loss_data, selection);
- if (sel->widget)
- evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
- _cocoa_sel_obj_del_cb, sel);
-
- sel->widget = obj;
- sel->win = win;
- sel->format = format;
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
-
- evas_object_event_callback_add(sel->widget, EVAS_CALLBACK_DEL,
- _cocoa_sel_obj_del_cb, sel);
- ELM_SAFE_FREE(sel->selbuf, free);
- sel->buflen = 0;
- if (selbuf)
- {
- sel->selbuf = malloc(buflen + 1);
- if (EINA_UNLIKELY(!sel->selbuf))
- {
- CRI("Failed to allocate memory!");
- elm_object_cnp_selection_clear(obj, selection);
- return EINA_FALSE;
- }
- memcpy(sel->selbuf, selbuf, buflen);
- sel->selbuf[buflen] = 0;
- sel->buflen = buflen;
- type = _elm_sel_format_to_ecore_cocoa_cnp_type(format);
- ecore_cocoa_clipboard_set(selbuf, buflen, type);
- }
-
- return ok;
-}
-
-static void
-_cocoa_elm_cnp_selection_loss_callback_set(Evas_Object *obj EINA_UNUSED,
- Elm_Sel_Type selection EINA_UNUSED,
- Elm_Selection_Loss_Cb func EINA_UNUSED,
- const void *data EINA_UNUSED)
-{
- // Currently, we have no way to track changes in Cocoa pasteboard.
- // Therefore, don't track this...
- //sel->loss_cb = func;
- //sel->loss_data = (void *)data;
-}
-
-static Eina_Bool
-_cocoa_elm_cnp_selection_clear(Evas_Object *obj EINA_UNUSED,
- Elm_Sel_Type selection EINA_UNUSED)
-{
- Cocoa_Cnp_Selection *sel = &_cocoa_cnp_sel;
-
- if (sel->widget)
- evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
- _cocoa_sel_obj_del_cb, sel);
- if (sel->requestwidget)
- evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
- _cocoa_sel_obj_del_req_cb, sel);
-
- sel->widget = NULL;
- sel->requestwidget = NULL;
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
- ELM_SAFE_FREE(sel->selbuf, free);
- sel->buflen = 0;
- ecore_cocoa_clipboard_clear();
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_cocoa_elm_cnp_selection_get(const Evas_Object *obj,
- Ecore_Cocoa_Window *win,
- Elm_Sel_Type selection EINA_UNUSED,
- Elm_Sel_Format format,
- Elm_Drop_Cb datacb,
- void *udata)
-{
- Cocoa_Cnp_Selection *sel = &_cocoa_cnp_sel;
-
- if (sel->requestwidget)
- evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
- _cocoa_sel_obj_del_req_cb, sel);
-
- sel->requestformat = format;
- sel->requestwidget = (Evas_Object *)obj;
- sel->win = win;
- sel->datacb = datacb;
- sel->udata = udata;
-
- ecore_job_add(_job_pb_cb, sel);
-
- evas_object_event_callback_add(sel->requestwidget, EVAS_CALLBACK_DEL,
- _cocoa_sel_obj_del_req_cb, sel);
-
- return EINA_TRUE;
-}
-
-
-#endif
-
-////////////////////////////////////////////////////////////////////////////
-// for local (Within 1 app/process) cnp (used by fb as fallback
-////////////////////////////////////////////////////////////////////////////
-#if 1
-typedef struct _Local_Selinfo Local_Selinfo;
-
-struct _Local_Selinfo
-{
- Elm_Sel_Format format;
- struct {
- char *buf;
- size_t size;
- } sel;
- struct {
- Evas_Object *obj;
- Elm_Drop_Cb func;
- void *data;
- Ecore_Job *job;
- } get;
-};
-
-// for ELM_SEL_TYPE_PRIMARY, ELM_SEL_TYPE_SECONDARY, ELM_SEL_TYPE_XDND,
-// ELM_SEL_TYPE_CLIPBOARD
-static Local_Selinfo _local_selinfo[4];
-
-static void _local_get_job(void *data);
-
-static Eina_Bool _local_elm_cnp_init(void);
-static Eina_Bool _local_elm_cnp_selection_set(Evas_Object *obj EINA_UNUSED, Elm_Sel_Type selection, Elm_Sel_Format format, const void *selbuf, size_t buflen);
-static void _local_elm_cnp_selection_loss_callback_set(Evas_Object *obj EINA_UNUSED, Elm_Sel_Type selection EINA_UNUSED, Elm_Selection_Loss_Cb func EINA_UNUSED, const void *data EINA_UNUSED);
-static Eina_Bool _local_elm_object_cnp_selection_clear(Evas_Object *obj EINA_UNUSED, Elm_Sel_Type selection);
-static Eina_Bool _local_elm_cnp_selection_get(const Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format EINA_UNUSED, Elm_Drop_Cb datacb, void *udata);
-static Eina_Bool _local_elm_drop_target_add(Evas_Object *obj EINA_UNUSED, Elm_Sel_Format format EINA_UNUSED,
- Elm_Drag_State entercb EINA_UNUSED, void *enterdata EINA_UNUSED,
- Elm_Drag_State leavecb EINA_UNUSED, void *leavedata EINA_UNUSED,
- Elm_Drag_Pos poscb EINA_UNUSED, void *posdata EINA_UNUSED,
- Elm_Drop_Cb dropcb EINA_UNUSED, void *dropdata EINA_UNUSED);
-static Eina_Bool _local_elm_drag_start(Evas_Object *obj EINA_UNUSED,
- Elm_Sel_Format format EINA_UNUSED,
- const char *data EINA_UNUSED,
- Elm_Xdnd_Action action EINA_UNUSED,
- Elm_Drag_Icon_Create_Cb createicon EINA_UNUSED,
- void *createdata EINA_UNUSED,
- Elm_Drag_Pos dragpos EINA_UNUSED,
- void *dragdata EINA_UNUSED,
- Elm_Drag_Accept acceptcb EINA_UNUSED,
- void *acceptdata EINA_UNUSED,
- Elm_Drag_State dragdone EINA_UNUSED,
- void *donecbdata EINA_UNUSED);
-static Eina_Bool _local_elm_selection_selection_has_owner(Evas_Object *obj EINA_UNUSED);
-
-static void
-_local_get_job(void *data)
-{
- Local_Selinfo *info = data;
- Elm_Selection_Data ev;
-
- info->get.job = NULL;
- ev.x = 0;
- ev.y = 0;
- ev.format = info->format;
- ev.data = info->sel.buf;
- ev.len = info->sel.size;
- ev.action = ELM_XDND_ACTION_UNKNOWN;
- if (info->get.func)
- info->get.func(info->get.data, info->get.obj, &ev);
-}
-
-static Eina_Bool
-_local_elm_cnp_init(void)
-{
- static int _init_count = 0;
-
- if (_init_count > 0) return EINA_TRUE;
- _init_count++;
- memset(&(_local_selinfo), 0, sizeof(_local_selinfo));
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_local_elm_cnp_selection_set(Evas_Object *obj EINA_UNUSED,
- Elm_Sel_Type selection, Elm_Sel_Format format,
- const void *selbuf, size_t buflen)
-{
- _local_elm_cnp_init();
- free(_local_selinfo[selection].sel.buf);
- _local_selinfo[selection].format = format;
- _local_selinfo[selection].sel.buf = malloc(buflen + 1);
- if ((_local_selinfo[selection].sel.buf) && (selbuf))
- {
- memcpy(_local_selinfo[selection].sel.buf, selbuf, buflen);
- _local_selinfo[selection].sel.buf[buflen] = 0;
- _local_selinfo[selection].sel.size = buflen;
- }
- else
- _local_selinfo[selection].sel.size = 0;
- return EINA_TRUE;
-}
-
-static void
-_local_elm_cnp_selection_loss_callback_set(Evas_Object *obj EINA_UNUSED,
- Elm_Sel_Type selection EINA_UNUSED,
- Elm_Selection_Loss_Cb func EINA_UNUSED,
- const void *data EINA_UNUSED)
-{
- _local_elm_cnp_init();
- // this doesn't need to do anything as we never lose selection to anyone
- // as thisis local
-}
-
-static Eina_Bool
-_local_elm_object_cnp_selection_clear(Evas_Object *obj EINA_UNUSED,
- Elm_Sel_Type selection)
-{
- _local_elm_cnp_init();
- ELM_SAFE_FREE(_local_selinfo[selection].sel.buf, free);
- _local_selinfo[selection].sel.size = 0;
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_local_elm_cnp_selection_get(const Evas_Object *obj,
- Elm_Sel_Type selection,
- Elm_Sel_Format format EINA_UNUSED,
- Elm_Drop_Cb datacb, void *udata)
-{
- _local_elm_cnp_init();
- if (_local_selinfo[selection].get.job)
- ecore_job_del(_local_selinfo[selection].get.job);
- _local_selinfo[selection].get.obj = (Evas_Object *)obj;
- _local_selinfo[selection].get.func = datacb;
- _local_selinfo[selection].get.data = udata;
- _local_selinfo[selection].get.job =
- ecore_job_add(_local_get_job, &(_local_selinfo[selection]));
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_local_elm_drop_target_add(Evas_Object *obj EINA_UNUSED,
- Elm_Sel_Format format EINA_UNUSED,
- Elm_Drag_State entercb EINA_UNUSED,
- void *enterdata EINA_UNUSED,
- Elm_Drag_State leavecb EINA_UNUSED,
- void *leavedata EINA_UNUSED,
- Elm_Drag_Pos poscb EINA_UNUSED,
- void *posdata EINA_UNUSED,
- Elm_Drop_Cb dropcb EINA_UNUSED,
- void *dropdata EINA_UNUSED)
-{
- // XXX: implement me
- _local_elm_cnp_init();
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_local_elm_drop_target_del(Evas_Object *obj, Elm_Sel_Format format,
- Elm_Drag_State entercb, void *enterdata,
- Elm_Drag_State leavecb, void *leavedata,
- Elm_Drag_Pos poscb, void *posdata,
- Elm_Drop_Cb dropcb, void *dropdata)
-{
- Dropable *dropable = NULL;
-
- _local_elm_cnp_init();
-
- dropable = efl_key_data_get(obj, "__elm_dropable");
- if (dropable)
- {
- Eina_Inlist *itr;
- Dropable_Cbs *cbs_info;
- /* Look for the callback in the list */
- EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs_info)
- if (cbs_info->entercb == entercb && cbs_info->enterdata == enterdata &&
- cbs_info->leavecb == leavecb && cbs_info->leavedata == leavedata &&
- cbs_info->poscb == poscb && cbs_info->posdata == posdata &&
- cbs_info->dropcb == dropcb && cbs_info->dropdata == dropdata &&
- cbs_info->types == format)
- {
- dropable->cbs_list = eina_inlist_remove(dropable->cbs_list,
- EINA_INLIST_GET(cbs_info));
- free(cbs_info);
- }
- /* In case no more callbacks are listed for the object */
- if (!dropable->cbs_list)
- {
- drops = eina_list_remove(drops, dropable);
- efl_key_data_set(obj, "__elm_dropable", NULL);
- free(dropable);
- dropable = NULL;
- evas_object_event_callback_del(obj, EVAS_CALLBACK_DEL,
- _all_drop_targets_cbs_del);
- }
- if (!drops)
- {
- _elm_cnp_shutdown();
- }
- return EINA_TRUE;
- }
-
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_local_elm_drag_start(Evas_Object *obj EINA_UNUSED,
- Elm_Sel_Format format EINA_UNUSED,
- const char *data EINA_UNUSED,
- Elm_Xdnd_Action action EINA_UNUSED,
- Elm_Drag_Icon_Create_Cb createicon EINA_UNUSED,
- void *createdata EINA_UNUSED,
- Elm_Drag_Pos dragpos EINA_UNUSED,
- void *dragdata EINA_UNUSED,
- Elm_Drag_Accept acceptcb EINA_UNUSED,
- void *acceptdata EINA_UNUSED,
- Elm_Drag_State dragdone EINA_UNUSED,
- void *donecbdata EINA_UNUSED)
-{
- // XXX: implement me
- _local_elm_cnp_init();
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_local_elm_drag_action_set(Evas_Object *obj EINA_UNUSED,
- Elm_Xdnd_Action action EINA_UNUSED)
-{
- // XXX: implement me
- _local_elm_cnp_init();
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_local_elm_selection_selection_has_owner(Evas_Object *obj EINA_UNUSED)
-{
- _local_elm_cnp_init();
- if (_local_selinfo[ELM_SEL_TYPE_CLIPBOARD].sel.buf) return EINA_TRUE;
- return EINA_FALSE;
-}
-#endif
-
-// win32 specific stuff
-////////////////////////////////////////////////////////////////////////////
-#ifdef HAVE_ELEMENTARY_WIN32
-
-typedef struct _Win32_Cnp_Selection Win32_Cnp_Selection;
-
-struct _Win32_Cnp_Selection
-{
- const char *debug;
- Evas_Object *widget;
- char *selbuf;
- Evas_Object *requestwidget;
- void *udata;
- Elm_Sel_Format requestformat;
- Elm_Drop_Cb datacb;
- Eina_Bool (*set)(const Ecore_Win32_Window *window, const void *data, int size);
- Eina_Bool (*clear)(const Ecore_Win32_Window *window);
- Eina_Bool (*get)(const Ecore_Win32_Window *window , void **data, int *size);
- Elm_Selection_Loss_Cb loss_cb;
- void *loss_data;
-
- Elm_Sel_Format format;
- Ecore_Win32_Selection ecore_sel;
- Ecore_Win32_Window *win;
- Elm_Xdnd_Action action;
-
- Eina_Bool active : 1;
-};
-
-#define ARRAYINIT(foo) [foo] =
-
-static Win32_Cnp_Selection _win32_selections[ELM_SEL_TYPE_CLIPBOARD + 1] =
-{
- ARRAYINIT(ELM_SEL_TYPE_PRIMARY)
- {
- .debug = "Primary",
- .ecore_sel = ECORE_WIN32_SELECTION_PRIMARY,
- .set = ecore_win32_clipboard_set,
- .clear = ecore_win32_clipboard_clear,
- .get = ecore_win32_clipboard_get,
- },
- ARRAYINIT(ELM_SEL_TYPE_SECONDARY)
- {
- .debug = "Secondary",
- .ecore_sel = ECORE_WIN32_SELECTION_OTHER,
- },
- ARRAYINIT(ELM_SEL_TYPE_XDND)
- {
- .debug = "XDnD",
- .ecore_sel = ECORE_WIN32_SELECTION_OTHER,
- },
- ARRAYINIT(ELM_SEL_TYPE_CLIPBOARD)
- {
- .debug = "Clipboard",
- .ecore_sel = ECORE_WIN32_SELECTION_CLIPBOARD,
- .set = ecore_win32_clipboard_set,
- .clear = ecore_win32_clipboard_clear,
- .get = ecore_win32_clipboard_get,
- }
-};
-
-static char *
-_win32_text_n_to_rn(char *intext)
-{
- size_t size = 0, newlines = 0;
- char *outtext = NULL, *p, *o;
-
- if (!intext) return NULL;
- for (p = intext; *p; p++)
- {
- if (*p == '\n') newlines++;
- size++;
- }
- outtext = malloc(size + newlines + 1);
- if (!outtext) return intext;
- for (p = intext, o = outtext; *p; p++, o++)
- {
- if (*p == '\n')
- {
- o++;
- *p = '\r';
- }
- *o = *p;
- }
- *o = '\0';
- free(intext);
- return outtext;
-}
-
-static char *
-_win32_text_rn_to_n(char *intext)
-{
- char *outtext = NULL, *p, *o;
-
- if (!intext) return NULL;
- outtext = malloc(strlen(intext) + 1);
- if (!outtext) return intext;
- for (p = intext, o = outtext; *p; p++, o++)
- {
- if ((*p == '\r') && (p[1] == '\n'))
- {
- p++;
- *p = '\n';
- }
- else *o = *p;
- }
- *o = '\0';
- free(intext);
- return outtext;
-}
-
-static void
-_win32_sel_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
-{
- Win32_Cnp_Selection *sel = data;
- if (sel->widget == obj) sel->widget = NULL;
- if (dragwidget == obj) dragwidget = NULL;
-}
-
-static void
-_win32_sel_obj_del2(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
-{
- Win32_Cnp_Selection *sel = data;
- if (sel->requestwidget == obj) sel->requestwidget = NULL;
-}
-
-static Eina_Bool
-_win32_elm_cnp_init(void)
-{
- static int _init_count = 0;
-
- if (_init_count > 0) return EINA_TRUE;
- _init_count++;
- return EINA_TRUE;
-}
-
-static Ecore_Win32_Window *
-_win32_elm_widget_window_get(const Evas_Object *obj)
-{
- Evas_Object *top;
- Ecore_Win32_Window *win = NULL;
-
- if (elm_widget_is(obj))
- {
- top = elm_widget_top_get(obj);
- if (!top)
- {
- Evas_Object *par;
- par = elm_widget_parent_widget_get(obj);
- if (par) top = elm_widget_top_get(par);
- }
- if (top && (efl_isa(top, EFL_UI_WIN_CLASS)))
- win = elm_win_win32_window_get(top);
- }
-
- if (!win)
- {
- Ecore_Evas *ee;
- Evas *evas;
- const char *engine_name;
-
- evas = evas_object_evas_get(obj);
- if (!evas) return NULL;
-
- ee = ecore_evas_ecore_evas_get(evas);
- if (!ee) return NULL;
-
- engine_name = ecore_evas_engine_name_get(ee);
- if (!strcmp(engine_name, ELM_BUFFER))
- {
- ee = ecore_evas_buffer_ecore_evas_parent_get(ee);
- if (!ee) return NULL;
- win = ecore_evas_win32_window_get(ee);
- }
- else
- {
- if ((strcmp(engine_name, ELM_SOFTWARE_WIN32) == 0) ||
- (strcmp(engine_name, ELM_SOFTWARE_DDRAW) == 0))
- return ecore_evas_win32_window_get(ee);
- }
- }
-
- return win;
-}
-
-static Eina_Bool
-_win32_elm_cnp_selection_set(Ecore_Win32_Window *win, Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format, const void *selbuf, size_t buflen)
-{
- Win32_Cnp_Selection *sel;
-
- if (selection != ELM_SEL_TYPE_CLIPBOARD)
- return EINA_FALSE;
-
- _win32_elm_cnp_init();
- if ((!selbuf) && (format != ELM_SEL_FORMAT_IMAGE))
- return elm_object_cnp_selection_clear(obj, selection);
-
- sel = _win32_selections + selection;
- if (sel->widget != obj && sel->loss_cb) sel->loss_cb(sel->loss_data, selection);
- if (sel->widget)
- evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
- _win32_sel_obj_del, sel);
- sel->active = EINA_TRUE;
- sel->widget = obj;
- sel->win = win;
- if (sel->set) sel->set(win, selbuf, buflen);
- sel->format = format;
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
-
- evas_object_event_callback_add
- (sel->widget, EVAS_CALLBACK_DEL, _win32_sel_obj_del, sel);
-
- ELM_SAFE_FREE(sel->selbuf, free);
- if (selbuf)
- {
- if (format == ELM_SEL_FORMAT_IMAGE)
- {
- // selbuf is actual image data, not text/string
- sel->selbuf = malloc(buflen + 1);
- if (!sel->selbuf)
- {
- elm_object_cnp_selection_clear(obj, selection);
- return EINA_FALSE;
- }
- memcpy(sel->selbuf, selbuf, buflen);
- sel->selbuf[buflen] = 0;
- }
- else
- sel->selbuf = strdup((char*)selbuf);
- }
-
- return EINA_TRUE;
-}
-
-static void
-_win32_elm_cnp_selection_loss_callback_set(Evas_Object *obj EINA_UNUSED, Elm_Sel_Type selection, Elm_Selection_Loss_Cb func, const void *data)
-{
- Win32_Cnp_Selection *sel;
-
- if (selection != ELM_SEL_TYPE_CLIPBOARD)
- return;
-
- _win32_elm_cnp_init();
- sel = _win32_selections + selection;
- sel->loss_cb = func;
- sel->loss_data = (void *)data;
-}
-
-static Eina_Bool
-_win32_elm_object_cnp_selection_clear(Ecore_Win32_Window *win, Evas_Object *obj, Elm_Sel_Type selection)
-{
- Win32_Cnp_Selection *sel;
-
- if (selection != ELM_SEL_TYPE_CLIPBOARD)
- return EINA_FALSE;
-
- _win32_elm_cnp_init();
-
- sel = _win32_selections + selection;
-
- /* No longer this selection: Consider it gone! */
- if ((!sel->active) || (sel->widget != obj))
- return EINA_TRUE;
-
- if (sel->widget)
- evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
- _win32_sel_obj_del, sel);
- if (sel->requestwidget)
- evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
- _win32_sel_obj_del2, sel);
- sel->widget = NULL;
- sel->requestwidget = NULL;
- sel->loss_cb = NULL;
- sel->loss_data = NULL;
-
- sel->active = EINA_FALSE;
- ELM_SAFE_FREE(sel->selbuf, free);
- /* sel->clear(win); */
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_win32_elm_cnp_selection_get(Ecore_Win32_Window *win,
- const Evas_Object *obj,
- Elm_Sel_Type selection,
- Elm_Sel_Format format,
- Elm_Drop_Cb datacb,
- void *udata)
-{
- Win32_Cnp_Selection *sel;
- void *data;
- int size;
-
- if (selection != ELM_SEL_TYPE_CLIPBOARD)
- return EINA_FALSE;
-
- _win32_elm_cnp_init();
-
- sel = _win32_selections + selection;
-
- if (sel->requestwidget)
- evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
- _win32_sel_obj_del2, sel);
- sel->requestformat = format;
- sel->requestwidget = (Evas_Object *)obj;
- sel->win = win;
- sel->get(win, &data, &size);
- sel->datacb = datacb;
- sel->udata = udata;
-
- if (!data || (size <= 0))
- goto cb_add;
-
- if ((sel->format & ELM_SEL_FORMAT_MARKUP) ||
- (sel->format & ELM_SEL_FORMAT_HTML))
- {
- char *str;
-
- str = (char *)malloc(size + 1);
- if (str)
- {
- memcpy(str, data, size);
- str[size] = '\0';
- data = _win32_text_n_to_rn(_elm_util_mkup_to_text(str));
- free(str);
- if (data)
- size = strlen(data);
- else
- size = 0;
- }
- else
- {
- free(data);
- data = NULL;
- }
- }
-
- if (sel->datacb && data && (size > 0))
- {
- Elm_Selection_Data sdata;
-
- sdata.x = sdata.y = 0;
- sdata.format = ELM_SEL_FORMAT_TEXT;
- sdata.data = data;
- sdata.len = size;
- sdata.action = sel->action;
- sel->datacb(sel->udata, sel->requestwidget, &sdata);
- }
-
- if (data)
- free(data);
-
- cb_add:
- evas_object_event_callback_add
- (sel->requestwidget, EVAS_CALLBACK_DEL, _win32_sel_obj_del2, sel);
-
- return EINA_TRUE;
-}
-
-#endif /* HAVE_ELEMENTARY_WIN32 */
-
-// common internal funcs
-////////////////////////////////////////////////////////////////////////////
-static Eina_Bool
-_elm_cnp_init(void)
-{
- int i;
- if (_elm_cnp_init_count > 0) return EINA_TRUE;
- _elm_cnp_init_count++;
- ELM_CNP_EVENT_SELECTION_CHANGED = ecore_event_type_new();
- text_uri = eina_stringshare_add("text/uri-list");
- _types_hash = eina_hash_string_small_new(NULL);
- for (i = 0; i < CNP_N_ATOMS; i++)
- {
- eina_hash_add(_types_hash, _atoms[i].name, &_atoms[i]);
- }
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_elm_cnp_shutdown(void)
-{
- if (!_elm_cnp_init_count) return EINA_TRUE;
- if (--_elm_cnp_init_count > 0) return EINA_TRUE;
- ELM_CNP_EVENT_SELECTION_CHANGED = -1;
- eina_stringshare_del(text_uri);
- text_uri = NULL;
- ELM_SAFE_FREE(_types_hash, eina_hash_free);
- return EINA_TRUE;
-}
-
-/* TODO: this should not be an actual tempfile, but rather encode the object
- * as http://dataurl.net/ if it's an image or similar. Evas should support
- * decoding it as memfile. */
-static Tmp_Info *
-_tempfile_new(int size)
-{
-#ifdef HAVE_MMAN_H
- Tmp_Info *info;
- const char *tmppath = NULL;
- mode_t cur_umask;
- int len;
-
- info = calloc(1, sizeof(Tmp_Info));
- if (!info) return NULL;
-#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
- if (getuid() == geteuid())
-#endif
- tmppath = getenv("TMP");
- if (!tmppath) tmppath = P_tmpdir;
- len = snprintf(NULL, 0, "%s/%sXXXXXX", tmppath, "elmcnpitem-");
- if (len < 0) goto on_error;
- len++;
- info->filename = malloc(len);
- if (!info->filename) goto on_error;
- snprintf(info->filename,len,"%s/%sXXXXXX", tmppath, "elmcnpitem-");
- cur_umask = umask(S_IRWXO | S_IRWXG);
- info->fd = mkstemp(info->filename);
- umask(cur_umask);
- if (info->fd < 0) goto on_error;
-# ifdef __linux__
- {
- char *tmp;
- /* And before someone says anything see POSIX 1003.1-2008 page 400 */
- long pid;
-
- pid = (long)getpid();
- /* Use pid instead of /proc/self: That way if can be passed around */
- len = snprintf(NULL,0,"/proc/%li/fd/%i", pid, info->fd);
- len++;
- tmp = malloc(len);
- if (tmp)
- {
- snprintf(tmp,len, "/proc/%li/fd/%i", pid, info->fd);
- unlink(info->filename);
- free(info->filename);
- info->filename = tmp;
- }
- }
-# endif
- cnp_debug("filename is %s\n", info->filename);
- if (size < 1) goto on_error;
- /* Map it in */
- if (ftruncate(info->fd, size))
- {
- perror("ftruncate");
- goto on_error;
- }
- eina_mmap_safety_enabled_set(EINA_TRUE);
- info->map = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, info->fd, 0);
- if (info->map == MAP_FAILED)
- {
- perror("mmap");
- goto on_error;
- }
- return info;
-
- on_error:
- if (info->fd >= 0) close(info->fd);
- info->fd = -1;
- /* Set map to NULL and return */
- info->map = NULL;
- info->len = 0;
- free(info->filename);
- free(info);
- return NULL;
-#else
- (void) size;
- return NULL;
-#endif
-}
-
-static int
-_tmpinfo_free(Tmp_Info *info)
-{
- if (!info) return 0;
- free(info->filename);
- free(info);
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////
-// common exposed funcs
-////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////
-EAPI Eina_Bool
-elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type selection,
- Elm_Sel_Format format, const void *selbuf, size_t buflen)
-{
- if (selection > ELM_SEL_TYPE_CLIPBOARD) return EINA_FALSE;
- if (!_elm_cnp_init_count) _elm_cnp_init();
-#ifdef HAVE_ELEMENTARY_X
- Ecore_X_Window xwin = _x11_elm_widget_xwin_get(obj);
- if (xwin)
- return _x11_elm_cnp_selection_set(xwin, obj, selection, format, selbuf, buflen);
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- if (_wl_elm_widget_window_get(obj))
- return _wl_elm_cnp_selection_set(obj, selection, format, selbuf, buflen);
-#endif
-#ifdef HAVE_ELEMENTARY_COCOA
- Ecore_Cocoa_Window *win = _cocoa_elm_widget_cocoa_window_get(obj);
- if (win)
- return _cocoa_elm_cnp_selection_set(win, obj, selection, format, selbuf, buflen);
-#endif
-#ifdef HAVE_ELEMENTARY_WIN32
- Ecore_Win32_Window *win;
-
- win = _win32_elm_widget_window_get(obj);
- if (win)
- return _win32_elm_cnp_selection_set(win, obj, selection, format, selbuf, buflen);
-#endif
- return _local_elm_cnp_selection_set(obj, selection, format, selbuf, buflen);
-}
-
-EAPI void
-elm_cnp_selection_loss_callback_set(Evas_Object *obj, Elm_Sel_Type selection,
- Elm_Selection_Loss_Cb func,
- const void *data)
-{
- if (selection > ELM_SEL_TYPE_CLIPBOARD) return;
- if (!_elm_cnp_init_count) _elm_cnp_init();
-#ifdef HAVE_ELEMENTARY_X
- if (_x11_elm_widget_xwin_get(obj))
- _x11_elm_cnp_selection_loss_callback_set(obj, selection, func, data);
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- if (_wl_elm_widget_window_get(obj))
- _wl_elm_cnp_selection_loss_callback_set(obj, selection, func, data);
-#endif
-#ifdef HAVE_ELEMENTARY_COCOA
- if (_cocoa_elm_widget_cocoa_window_get(obj))
- _cocoa_elm_cnp_selection_loss_callback_set(obj, selection, func, data);
-#endif
-#ifdef HAVE_ELEMENTARY_WIN32
- if (_win32_elm_widget_window_get(obj))
- _win32_elm_cnp_selection_loss_callback_set(obj, selection, func, data);
-#endif
- _local_elm_cnp_selection_loss_callback_set(obj, selection, func, data);
-}
-
-EAPI Eina_Bool
-elm_object_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type selection)
-{
- if (selection > ELM_SEL_TYPE_CLIPBOARD) return EINA_FALSE;
- if (!_elm_cnp_init_count) _elm_cnp_init();
-#ifdef HAVE_ELEMENTARY_X
- if (_x11_elm_widget_xwin_get(obj))
- return _x11_elm_object_cnp_selection_clear(obj, selection);
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- if (_wl_elm_widget_window_get(obj))
- return _wl_elm_cnp_selection_clear(obj, selection);
-#endif
-#ifdef HAVE_ELEMENTARY_COCOA
- if (_cocoa_elm_widget_cocoa_window_get(obj))
- return _cocoa_elm_cnp_selection_clear(obj, selection);
-#endif
-#ifdef HAVE_ELEMENTARY_WIN32
- Ecore_Win32_Window *win;
-
- win = _win32_elm_widget_window_get(obj);
- if (win)
- return _win32_elm_object_cnp_selection_clear(win, obj, selection);
-#endif
- return _local_elm_object_cnp_selection_clear(obj, selection);
-}
-
-EAPI Eina_Bool
-elm_cnp_selection_get(const Evas_Object *obj, Elm_Sel_Type selection,
- Elm_Sel_Format format, Elm_Drop_Cb datacb, void *udata)
-{
- if (selection > ELM_SEL_TYPE_CLIPBOARD) return EINA_FALSE;
- if (!_elm_cnp_init_count) _elm_cnp_init();
-#ifdef HAVE_ELEMENTARY_X
- Ecore_X_Window xwin = _x11_elm_widget_xwin_get(obj);
- if (xwin)
- return _x11_elm_cnp_selection_get(xwin, obj, selection, format, datacb, udata);
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- if (_wl_elm_widget_window_get(obj))
- return _wl_elm_cnp_selection_get(obj, selection, format, datacb, udata);
-#endif
-#ifdef HAVE_ELEMENTARY_COCOA
- Ecore_Cocoa_Window *win = _cocoa_elm_widget_cocoa_window_get(obj);
- if (win)
- return _cocoa_elm_cnp_selection_get(obj, win, selection, format, datacb, udata);
-#endif
-#ifdef HAVE_ELEMENTARY_WIN32
- Ecore_Win32_Window *win;
-
- win = _win32_elm_widget_window_get(obj);
- if (win)
- return _win32_elm_cnp_selection_get(win, obj, selection, format, datacb, udata);
-#endif
- return _local_elm_cnp_selection_get(obj, selection, format, datacb, udata);
-}
-
-////////////////////////////////////////////////////////////////////////////
-
-/**
- * Add a widget as drop target.
- */
-EAPI Eina_Bool
-elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format,
- Elm_Drag_State entercb, void *enterdata,
- Elm_Drag_State leavecb, void *leavedata,
- Elm_Drag_Pos poscb, void *posdata,
- Elm_Drop_Cb dropcb, void *dropdata)
-{
- if (!_elm_cnp_init_count) _elm_cnp_init();
-#ifdef HAVE_ELEMENTARY_X
- if (_x11_elm_widget_xwin_get(obj))
- return _x11_elm_drop_target_add(obj, format, entercb, enterdata,
- leavecb, leavedata, poscb, posdata,
- dropcb, dropdata);
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- if (_wl_elm_widget_window_get(obj))
- return _wl_elm_drop_target_add(obj, format, entercb, enterdata,
- leavecb, leavedata, poscb, posdata,
- dropcb, dropdata);
-#endif
- return _local_elm_drop_target_add(obj, format, entercb, enterdata,
- leavecb, leavedata, poscb, posdata,
- dropcb, dropdata);
-}
-
-EAPI Eina_Bool
-elm_drop_target_del(Evas_Object *obj, Elm_Sel_Format format,
- Elm_Drag_State entercb, void *enterdata,
- Elm_Drag_State leavecb, void *leavedata,
- Elm_Drag_Pos poscb, void *posdata,
- Elm_Drop_Cb dropcb, void *dropdata)
-{
- if (!_elm_cnp_init_count) _elm_cnp_init();
-#ifdef HAVE_ELEMENTARY_X
- if (_x11_elm_widget_xwin_get(obj))
- return _x11_elm_drop_target_del(obj, format, entercb, enterdata,
- leavecb, leavedata, poscb, posdata, dropcb, dropdata);
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- if (_wl_elm_widget_window_get(obj))
- return _wl_elm_drop_target_del(obj, format, entercb, enterdata,
- leavecb, leavedata, poscb, posdata, dropcb, dropdata);
-#endif
- /* FIXME: Not the best place for an error message, but meh.
- * This code path is actually valid if running in framebuffer, but it still shouldn't
- * be getting here because the drop target shouldn't be added. This is an error
- * and it's because of some stupid handling in both the X11 and the wayland backends
- * as seen in the commit that introduced this comment.
- * Window check is probably not the best idea, you should be doing engine check instead. */
- ERR("Please contact developers, you should probably not get here.");
- return _local_elm_drop_target_del(obj, format, entercb, enterdata,
- leavecb, leavedata, poscb, posdata, dropcb, dropdata);
-}
-
-EAPI Eina_Bool
-elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data,
- Elm_Xdnd_Action action,
- Elm_Drag_Icon_Create_Cb createicon, void *createdata,
- Elm_Drag_Pos dragpos, void *dragdata,
- Elm_Drag_Accept acceptcb, void *acceptdata,
- Elm_Drag_State dragdone, void *donecbdata)
-{
- if (!_elm_cnp_init_count) _elm_cnp_init();
-#ifdef HAVE_ELEMENTARY_X
- if (_x11_elm_widget_xwin_get(obj))
- return _x11_elm_drag_start(obj, format, data, action,
- createicon, createdata,
- dragpos, dragdata,
- acceptcb, acceptdata,
- dragdone, donecbdata);
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- if (_wl_elm_widget_window_get(obj))
- return _wl_elm_drag_start(obj, format, data, action,
- createicon, createdata,
- dragpos, dragdata,
- acceptcb, acceptdata,
- dragdone, donecbdata);
-#endif
- return _local_elm_drag_start(obj, format, data, action,
- createicon, createdata,
- dragpos, dragdata,
- acceptcb, acceptdata,
- dragdone, donecbdata);
-}
-
-EAPI Eina_Bool
-elm_drag_action_set(Evas_Object *obj, Elm_Xdnd_Action action)
-{
- if (!_elm_cnp_init_count) _elm_cnp_init();
-#ifdef HAVE_ELEMENTARY_X
- if (_x11_elm_widget_xwin_get(obj))
- return _x11_elm_drag_action_set(obj, action);
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- if (_wl_elm_widget_window_get(obj))
- return _wl_elm_drag_action_set(obj, action);
-#endif
- return _local_elm_drag_action_set(obj, action);
-}
-
-EAPI Eina_Bool
-elm_selection_selection_has_owner(Evas_Object *obj)
-{
- if (!_elm_cnp_init_count) _elm_cnp_init();
-#ifdef HAVE_ELEMENTARY_X
- if (_x11_elm_widget_xwin_get(obj))
- return _x11_elm_selection_selection_has_owner(obj);
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- Ecore_Wl2_Window *win;
-
- win = _wl_elm_widget_window_get(obj);
- if (win)
- return !!ecore_wl2_dnd_selection_get(_wl_default_seat_get(win, obj));
-#endif
- return _local_elm_selection_selection_has_owner(obj);
-}
-
-EAPI Eina_Bool
-elm_cnp_clipboard_selection_has_owner(Evas_Object *win)
-{
- EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
- return elm_selection_selection_has_owner(win);
-}
-
-/* START - Support elm containers for Drag and Drop */
-/* START - Support elm containers for Drop */
-static int
-_drop_item_container_cmp(const void *d1,
- const void *d2)
-{
- const Item_Container_Drop_Info *st = d1;
- return (((uintptr_t) (st->obj)) - ((uintptr_t) d2));
-}
-
-static void
-_elm_item_container_pos_cb(void *data, Evas_Object *obj, Evas_Coord x, Evas_Coord y, Elm_Xdnd_Action action)
-{ /* obj is the container pointer */
- Elm_Object_Item *it = NULL;
- int xposret = 0;
- int yposret = 0;
-
- Item_Container_Drop_Info *st =
- eina_list_search_unsorted(cont_drop_tg, _drop_item_container_cmp, obj);
-
- if (st && st->poscb)
- { /* Call container drop func with specific item pointer */
- int xo = 0;
- int yo = 0;
-
- evas_object_geometry_get(obj, &xo, &yo, NULL, NULL);
- if (st->itemgetcb)
- it = st->itemgetcb(obj, x+xo, y+yo, &xposret, &yposret);
-
- st->poscb(data, obj, it, x, y, xposret, yposret, action);
- }
-}
-
-static Eina_Bool
-_elm_item_container_drop_cb(void *data, Evas_Object *obj , Elm_Selection_Data *ev)
-{ /* obj is the container pointer */
- Elm_Object_Item *it = NULL;
- int xposret = 0;
- int yposret = 0;
-
- Item_Container_Drop_Info *st =
- eina_list_search_unsorted(cont_drop_tg, _drop_item_container_cmp, obj);
-
- if (st && st->dropcb)
- { /* Call container drop func with specific item pointer */
- int xo = 0;
- int yo = 0;
-
- evas_object_geometry_get(obj, &xo, &yo, NULL, NULL);
- if (st->itemgetcb)
- it = st->itemgetcb(obj, ev->x+xo, ev->y+yo, &xposret, &yposret);
-
- return st->dropcb(data, obj, it, ev, xposret, yposret);
- }
-
- return EINA_FALSE;
-}
-
-static Eina_Bool
-elm_drop_item_container_del_internal(Evas_Object *obj, Eina_Bool full)
-{
- Item_Container_Drop_Info *st =
- eina_list_search_unsorted(cont_drop_tg, _drop_item_container_cmp, obj);
-
- if (st)
- {
- // temp until st is stored inside data of obj.
- _all_drop_targets_cbs_del(NULL, NULL, obj, NULL);
- st->itemgetcb= NULL;
- st->poscb = NULL;
- st->dropcb = NULL;
-
- if (full)
- {
- cont_drop_tg = eina_list_remove(cont_drop_tg, st);
- free(st);
- }
-
- return EINA_TRUE;
- }
-
- return EINA_FALSE;
-}
-
-EAPI Eina_Bool
-elm_drop_item_container_del(Evas_Object *obj)
-{
- return elm_drop_item_container_del_internal(obj, EINA_TRUE);
-}
-
-EAPI Eina_Bool
-elm_drop_item_container_add(Evas_Object *obj,
- Elm_Sel_Format format,
- Elm_Xy_Item_Get_Cb itemgetcb,
- Elm_Drag_State entercb, void *enterdata,
- Elm_Drag_State leavecb, void *leavedata,
- Elm_Drag_Item_Container_Pos poscb, void *posdata,
- Elm_Drop_Item_Container_Cb dropcb, void *dropdata)
-{
- Item_Container_Drop_Info *st;
-
- if (elm_drop_item_container_del_internal(obj, EINA_FALSE))
- { /* Updating info of existing obj */
- st = eina_list_search_unsorted(cont_drop_tg, _drop_item_container_cmp, obj);
- if (!st) return EINA_FALSE;
- }
- else
- {
- st = calloc(1, sizeof(*st));
- if (!st) return EINA_FALSE;
-
- st->obj = obj;
- cont_drop_tg = eina_list_append(cont_drop_tg, st);
- }
-
- st->itemgetcb = itemgetcb;
- st->poscb = poscb;
- st->dropcb = dropcb;
- elm_drop_target_add(obj, format,
- entercb, enterdata,
- leavecb, leavedata,
- _elm_item_container_pos_cb, posdata,
- _elm_item_container_drop_cb, dropdata);
-
- return EINA_TRUE;
-}
-/* END - Support elm containers for Drop */
-
-/* START - Support elm containers for Drag */
-static int
-_drag_item_container_cmp(const void *d1,
- const void *d2)
-{
- const Item_Container_Drag_Info *st = d1;
- return (((uintptr_t) (st->obj)) - ((uintptr_t) d2));
-}
-
-static void
-_cont_drag_done_cb(void *data, Evas_Object *obj EINA_UNUSED)
-{
- Item_Container_Drag_Info *st = data;
- elm_widget_scroll_freeze_pop(st->obj);
- if (st->user_info.dragdone)
- st->user_info.dragdone(st->user_info.donecbdata, dragwidget, doaccept);
-}
-
-static Eina_Bool
-_cont_obj_drag_start(void *data)
-{ /* Start a drag-action when timer expires */
- cnp_debug("In\n");
- Item_Container_Drag_Info *st = data;
- st->tm = NULL;
- Elm_Drag_User_Info *info = &st->user_info;
- if (info->dragstart) info->dragstart(info->startcbdata, st->obj);
- elm_widget_scroll_freeze_push(st->obj);
- evas_object_event_callback_del_full
- (st->obj, EVAS_CALLBACK_MOUSE_MOVE, _cont_obj_mouse_move, st);
- elm_drag_start( /* Commit the start only if data_get successful */
- st->obj, info->format,
- info->data, info->action,
- info->createicon, info->createdata,
- info->dragpos, info->dragdata,
- info->acceptcb, info->acceptdata,
- _cont_drag_done_cb, st);
- ELM_SAFE_FREE(info->data, free);
-
- return ECORE_CALLBACK_CANCEL;
-}
-
-static void
-_anim_st_free(Item_Container_Drag_Info *st)
-{ /* Stops and free mem of ongoing animation */
- if (st)
- {
- ELM_SAFE_FREE(st->ea, ecore_animator_del);
- Anim_Icon *sti;
- Eo *icon;
-
- EINA_LIST_FREE(st->icons, sti)
- {
- evas_object_del(sti->o);
- free(sti);
- }
- st->icons = NULL;
-
- EINA_LIST_FREE(st->user_info.icons, icon)
- {
- evas_object_del(icon);
- }
- st->user_info.icons = NULL;
- }
-}
-
-static inline Eina_List *
-_anim_icons_make(Item_Container_Drag_Info *st)
-{ /* Transfer user icons to animation icons list */
- Eina_List *list = NULL;
- Evas_Object *o;
-
- EINA_LIST_FREE(st->user_info.icons, o)
- { /* Now add icons to animation window */
- Anim_Icon *ast = calloc(1, sizeof(*ast));
-
- if (!ast)
- {
- ERR("Failed to allocate memory for icon!");
- continue;
- }
-
- evas_object_geometry_get(o, &ast->start_x, &ast->start_y, &ast->start_w, &ast->start_h);
- evas_object_show(o);
- ast->o = o;
- list = eina_list_append(list, ast);
- }
-
- return list;
-}
-
-static Eina_Bool
-_drag_anim_play(void *data, double pos)
-{ /* Impl of the animation of icons, called on frame time */
- cnp_debug("In\n");
- Item_Container_Drag_Info *st = data;
- Eina_List *l;
- Anim_Icon *sti;
-
- if (st->ea)
- {
- if (pos > 0.99)
- {
- st->ea = NULL; /* Avoid deleting on mouse up */
- EINA_LIST_FOREACH(st->icons, l, sti)
- evas_object_hide(sti->o);
-
- _cont_obj_drag_start(st); /* Start dragging */
- return ECORE_CALLBACK_CANCEL;
- }
-
- Evas_Coord xm, ym;
- evas_pointer_canvas_xy_get(st->e, &xm, &ym);
- EINA_LIST_FOREACH(st->icons, l, sti)
- {
- int x, y, h, w;
- w = sti->start_w + ((st->final_icon_w - sti->start_w) * pos);
- h = sti->start_h + ((st->final_icon_h - sti->start_h) * pos);
- x = sti->start_x - (pos * ((sti->start_x + (w/2) - xm)));
- y = sti->start_y - (pos * ((sti->start_y + (h/2) - ym)));
- evas_object_move(sti->o, x, y);
- evas_object_resize(sti->o, w, h);
- }
-
- return ECORE_CALLBACK_RENEW;
- }
-
- return ECORE_CALLBACK_CANCEL;
-}
-
-static inline Eina_Bool
-_drag_anim_start(void *data)
-{ /* Start default animation */
- cnp_debug("In\n");
- Item_Container_Drag_Info *st = data;
-
- st->tm = NULL;
- /* Now we need to build an (Anim_Icon *) list */
- st->icons = _anim_icons_make(st);
- if (st->user_info.createicon)
- {
- Evas_Object *temp_win = elm_win_add(NULL, "Temp", ELM_WIN_DND);
- Evas_Object *final_icon = st->user_info.createicon(st->user_info.createdata, temp_win, NULL, NULL);
- evas_object_geometry_get(final_icon, NULL, NULL, &st->final_icon_w, &st->final_icon_h);
- evas_object_del(final_icon);
- evas_object_del(temp_win);
- }
- st->ea = ecore_animator_timeline_add(st->anim_tm, _drag_anim_play, st);
-
- return EINA_FALSE;
-}
-
-static Eina_Bool
-_cont_obj_anim_start(void *data)
-{ /* Start a drag-action when timer expires */
- cnp_debug("In\n");
- Item_Container_Drag_Info *st = data;
- int xposret, yposret; /* Unused */
- Elm_Object_Item *it = (st->itemgetcb) ?
- (st->itemgetcb(st->obj, st->x_down, st->y_down, &xposret, &yposret))
- : NULL;
-
- st->tm = NULL;
- st->user_info.format = ELM_SEL_FORMAT_TARGETS; /* Default */
- st->icons = NULL;
- st->user_info.data = NULL;
- st->user_info.action = ELM_XDND_ACTION_COPY; /* Default */
-
- if (!it) /* Failed to get mouse-down item, abort drag */
- return ECORE_CALLBACK_CANCEL;
-
- if (st->data_get)
- { /* collect info then start animation or start dragging */
- if (st->data_get( /* Collect drag info */
- st->obj, /* The container object */
- it, /* Drag started on this item */
- &st->user_info))
- {
- if (EINA_DBL_EQ(st->anim_tm, 0.0))
- _cont_obj_drag_start(st); /* Start dragging, no anim */
- else
- {
- if (st->user_info.icons)
- {
- _drag_anim_start(st);
- }
- else
- {
- // even if we don't manage the icons animation, we have
- // to wait until it is finished before beginning drag.
- st->tm = ecore_timer_add(st->anim_tm, _cont_obj_drag_start, st);
- }
- }
- }
- }
-
- return ECORE_CALLBACK_CANCEL;
-}
-
-static void
-_cont_obj_mouse_down(void *data, Evas *e, Evas_Object *obj EINA_UNUSED, void *event_info)
-{ /* Launch a timer to start dragging */
- Evas_Event_Mouse_Down *ev = event_info;
- cnp_debug("In - event %X\n", ev->event_flags);
- if (ev->button != 1)
- return; /* We only process left-click at the moment */
-
- Item_Container_Drag_Info *st = data;
- st->e = e;
- st->x_down = ev->canvas.x;
- st->y_down = ev->canvas.y;
-
- evas_object_event_callback_add(st->obj, EVAS_CALLBACK_MOUSE_UP,
- _cont_obj_mouse_up, st);
-
- ecore_timer_del(st->tm);
-
- if (st->tm_to_drag)
- {
- st->tm = ecore_timer_add(st->tm_to_drag, _cont_obj_anim_start, st);
- evas_object_event_callback_add(st->obj, EVAS_CALLBACK_MOUSE_MOVE,
- _cont_obj_mouse_move, st);
- }
- else
- _cont_obj_anim_start(st);
-}
-
-static Eina_Bool elm_drag_item_container_del_internal(Evas_Object *obj, Eina_Bool full);
-
-static void
-_abort_drag(Evas_Object *obj, Item_Container_Drag_Info *st)
-{
- evas_object_event_callback_del_full
- (st->obj, EVAS_CALLBACK_MOUSE_MOVE, _cont_obj_mouse_move, st);
- evas_object_event_callback_del_full
- (st->obj, EVAS_CALLBACK_MOUSE_UP, _cont_obj_mouse_up, st);
- elm_drag_item_container_del_internal(obj, EINA_FALSE);
-
- ELM_SAFE_FREE(st->tm, ecore_timer_del);
-
- _anim_st_free(st);
-}
-
-static void
-_cont_obj_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
-{ /* Cancel any drag waiting to start on timeout */
- cnp_debug("In\n");
- Item_Container_Drag_Info *st = data;
- Evas_Event_Mouse_Move *ev = event_info;
-
- if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
- {
- cnp_debug("event on hold - have to cancel DnD\n");
-
- _abort_drag(obj, st);
- st = NULL;
- }
-
- if (st && evas_device_class_get(ev->dev) == EVAS_DEVICE_CLASS_TOUCH)
- {
- int dx = ev->cur.canvas.x - st->x_down, dy = ev->cur.canvas.y - st->y_down;
- int finger_size = elm_config_finger_size_get();
- if ((dx * dx + dy * dy > finger_size * finger_size))
- {
- cnp_debug("mouse moved too much - have to cancel DnD\n");
-
- _abort_drag(obj, st);
- st = NULL;
- }
- }
- cnp_debug("Out\n");
-}
-
-static void
-_cont_obj_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
-{ /* Cancel any drag waiting to start on timeout */
- Item_Container_Drag_Info *st = data;
-
- cnp_debug("In\n");
- if (((Evas_Event_Mouse_Up *)event_info)->button != 1)
- return; /* We only process left-click at the moment */
-
- evas_object_event_callback_del_full
- (st->obj, EVAS_CALLBACK_MOUSE_MOVE, _cont_obj_mouse_move, st);
- evas_object_event_callback_del_full
- (st->obj, EVAS_CALLBACK_MOUSE_UP, _cont_obj_mouse_up, st);
-
- ELM_SAFE_FREE(st->tm, ecore_timer_del);
-
- _anim_st_free(st);
-}
-
-static Eina_Bool
-elm_drag_item_container_del_internal(Evas_Object *obj, Eina_Bool full)
-{
- Item_Container_Drag_Info *st =
- eina_list_search_unsorted(cont_drag_tg, _drag_item_container_cmp, obj);
-
- if (st)
- {
- ELM_SAFE_FREE(st->tm, ecore_timer_del); /* Cancel drag-start timer */
-
- if (st->ea) /* Cancel ongoing default animation */
- _anim_st_free(st);
-
- if (full)
- {
- st->itemgetcb = NULL;
- st->data_get = NULL;
- evas_object_event_callback_del_full
- (obj, EVAS_CALLBACK_MOUSE_DOWN, _cont_obj_mouse_down, st);
-
- cont_drag_tg = eina_list_remove(cont_drag_tg, st);
- ELM_SAFE_FREE(st->user_info.data, free);
- free(st);
- }
-
- return EINA_TRUE;
- }
- return EINA_FALSE;
-}
-
-EAPI Eina_Bool
-elm_drag_item_container_del(Evas_Object *obj)
-{
- return elm_drag_item_container_del_internal(obj, EINA_TRUE);
-}
-
-EAPI Eina_Bool
-elm_drag_item_container_add(Evas_Object *obj, double anim_tm, double tm_to_drag, Elm_Xy_Item_Get_Cb itemgetcb, Elm_Item_Container_Data_Get_Cb data_get)
-{
- Item_Container_Drag_Info *st;
-
- if (elm_drag_item_container_del_internal(obj, EINA_FALSE))
- { /* Updating info of existing obj */
- st = eina_list_search_unsorted(cont_drag_tg, _drag_item_container_cmp, obj);
- if (!st) return EINA_FALSE;
- }
- else
- {
- st = calloc(1, sizeof(*st));
- if (!st) return EINA_FALSE;
-
- st->obj = obj;
- cont_drag_tg = eina_list_append(cont_drag_tg, st);
-
- /* Register for mouse callback for container to start/abort drag */
- evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
- _cont_obj_mouse_down, st);
- }
-
- st->tm = NULL;
- st->anim_tm = anim_tm;
- st->tm_to_drag = tm_to_drag;
- st->itemgetcb = itemgetcb;
- st->data_get = data_get;
-
- return EINA_TRUE;
-}
-/* END - Support elm containers for Drag */
-/* END - Support elm containers for Drag and Drop */
-
-EAPI Eina_Bool
-elm_drag_cancel(Evas_Object *obj)
-{
-#ifdef HAVE_ELEMENTARY_X
- Ecore_X_Window xwin = _x11_elm_widget_xwin_get(obj);
- if (xwin)
- {
- ecore_x_pointer_ungrab();
- ELM_SAFE_FREE(handler_up, ecore_event_handler_del);
- ELM_SAFE_FREE(handler_status, ecore_event_handler_del);
- ecore_x_dnd_abort(xwin);
- if (dragwidget)
- {
- if (elm_widget_is(dragwidget))
- {
- Evas_Object *win = elm_widget_top_get(dragwidget);
- if (win && efl_isa(win, EFL_UI_WIN_CLASS))
- efl_event_callback_del(win, EFL_UI_WIN_EVENT_ROTATION_CHANGED, _x11_win_rotation_changed_cb, dragwin);
- }
- }
- goto end;
- }
-#endif
-#ifdef HAVE_ELEMENTARY_WL2
- Ecore_Wl2_Window *win;
-
- win = _wl_elm_widget_window_get(obj);
- if (win)
- ecore_wl2_dnd_drag_end(_wl_default_seat_get(win, obj));
-#endif
-
-end:
- ELM_SAFE_FREE(dragwin, evas_object_del);
- dragdonecb = NULL;
- dragacceptcb = NULL;
- dragposcb = NULL;
- dragwidget = NULL;
- doaccept = EINA_FALSE;
- return EINA_TRUE;
-}
-