forked from enlightenment/efl
Elementary: Copy-Paste support for Wayland Engines.
NB: Based on patch from Alex <zhiwen.wu@intel.com>, but cleaned up for compiler warnings. SVN revision: 75810
This commit is contained in:
parent
fb46a1ad76
commit
6ea2e696ff
|
@ -98,19 +98,6 @@ static Tmp_Info *_tempfile_new (int size);
|
||||||
static int _tmpinfo_free (Tmp_Info *tmp);
|
static int _tmpinfo_free (Tmp_Info *tmp);
|
||||||
static Eina_Bool _pasteimage_append (char *file, Evas_Object *entry);
|
static Eina_Bool _pasteimage_append (char *file, Evas_Object *entry);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// x11 specific stuff
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
#ifdef HAVE_ELEMENTARY_X
|
|
||||||
#define ARRAYINIT(foo) [foo] =
|
|
||||||
//#define DEBUGON 1
|
//#define DEBUGON 1
|
||||||
#ifdef DEBUGON
|
#ifdef DEBUGON
|
||||||
# define cnp_debug(x...) fprintf(stderr, __FILE__": " x)
|
# define cnp_debug(x...) fprintf(stderr, __FILE__": " x)
|
||||||
|
@ -118,6 +105,11 @@ static Eina_Bool _pasteimage_append (char *file, Evas_Object *entry);
|
||||||
# define cnp_debug(x...) do { } while (0)
|
# define cnp_debug(x...) do { } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// x11 specific stuff
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifdef HAVE_ELEMENTARY_X
|
||||||
|
#define ARRAYINIT(foo) [foo] =
|
||||||
|
|
||||||
typedef struct _X11_Cnp_Selection X11_Cnp_Selection;
|
typedef struct _X11_Cnp_Selection X11_Cnp_Selection;
|
||||||
typedef struct _X11_Cnp_Atom X11_Cnp_Atom;
|
typedef struct _X11_Cnp_Atom X11_Cnp_Atom;
|
||||||
|
|
||||||
|
@ -1534,6 +1526,124 @@ _x11_elm_selection_selection_has_owner(Evas_Object *obj __UNUSED__)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ELEMENTARY_WAYLAND
|
||||||
|
typedef struct _Wl_Cnp_Selection Wl_Cnp_Selection;
|
||||||
|
|
||||||
|
struct _Wl_Cnp_Selection
|
||||||
|
{
|
||||||
|
char *selbuf;
|
||||||
|
int buflen;
|
||||||
|
|
||||||
|
Evas_Object *widget;
|
||||||
|
Evas_Object *requestwidget;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Wl_Cnp_Selection wl_cnp_selection = {0, 0, NULL, NULL};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_wl_sel_obj_del2(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
||||||
|
{
|
||||||
|
Wl_Cnp_Selection *sel = data;
|
||||||
|
if (sel->requestwidget == obj) sel->requestwidget = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_wl_elm_cnp_selection_set(Evas_Object *obj __UNUSED__, Elm_Sel_Type selection, Elm_Sel_Format format __UNUSED__, const void *selbuf, size_t buflen)
|
||||||
|
{
|
||||||
|
const char *types[10] = {0, };
|
||||||
|
|
||||||
|
/* TODO: other EML_SEL_TYPE and ELM_SEL_FORMAT */
|
||||||
|
if (ELM_SEL_TYPE_CLIPBOARD == selection)
|
||||||
|
{
|
||||||
|
types[0] = "text/plain;charset=utf-8";
|
||||||
|
ecore_wl_dnd_set_selection(ecore_wl_dnd_get(), types);
|
||||||
|
|
||||||
|
if (wl_cnp_selection.selbuf) free(wl_cnp_selection.selbuf);
|
||||||
|
wl_cnp_selection.selbuf = strdup((char*)selbuf);
|
||||||
|
wl_cnp_selection.buflen = buflen;
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_wl_elm_cnp_selection_get(Evas_Object *obj, Elm_Sel_Type selection, Elm_Sel_Format format __UNUSED__, Elm_Drop_Cb datacb __UNUSED__, void *udata __UNUSED__)
|
||||||
|
{
|
||||||
|
/* For now, just avoid overlapped request */
|
||||||
|
if (wl_cnp_selection.requestwidget) return EINA_FALSE;
|
||||||
|
|
||||||
|
/* TODO: other EML_SEL_TYPE and ELM_SEL_FORMAT */
|
||||||
|
if (ELM_SEL_TYPE_CLIPBOARD == selection)
|
||||||
|
{
|
||||||
|
wl_cnp_selection.requestwidget = obj;
|
||||||
|
evas_object_event_callback_add(wl_cnp_selection.requestwidget, EVAS_CALLBACK_DEL,
|
||||||
|
_wl_sel_obj_del2, &wl_cnp_selection);
|
||||||
|
ecore_wl_dnd_get_selection(ecore_wl_dnd_get(), "text/plain;charset=utf-8");
|
||||||
|
}
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_wl_selection_send(void *udata, int type __UNUSED__, void *event)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
int ret, len_remained;
|
||||||
|
int len_written = 0;
|
||||||
|
Wl_Cnp_Selection *sel = udata;
|
||||||
|
Ecore_Wl_Event_Data_Source_Send *ev = event;
|
||||||
|
|
||||||
|
len_remained = sel->buflen;
|
||||||
|
buf = sel->selbuf;
|
||||||
|
|
||||||
|
while (len_written < sel->buflen)
|
||||||
|
{
|
||||||
|
ret = write(ev->fd, buf, len_remained);
|
||||||
|
if (ret == -1) break;
|
||||||
|
buf += ret;
|
||||||
|
len_written += ret;
|
||||||
|
len_remained -= ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(ev->fd);
|
||||||
|
return ECORE_CALLBACK_PASS_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_wl_selection_receive(void *udata, int type __UNUSED__, void *event)
|
||||||
|
{
|
||||||
|
Wl_Cnp_Selection *sel = udata;
|
||||||
|
Ecore_Wl_Event_Selection_Data_Ready *ev = event;
|
||||||
|
|
||||||
|
if (sel->requestwidget)
|
||||||
|
{
|
||||||
|
if (!ev->done)
|
||||||
|
{
|
||||||
|
/* TODO BUG: should never NEVER assume it's an elm_entry! */
|
||||||
|
_elm_entry_entry_paste(sel->requestwidget, ev->data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
|
||||||
|
_wl_sel_obj_del2, sel);
|
||||||
|
sel->requestwidget = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ECORE_CALLBACK_PASS_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool _wl_elm_cnp_init(void)
|
||||||
|
{
|
||||||
|
ecore_event_handler_add(ECORE_WL_EVENT_DATA_SOURCE_SEND,
|
||||||
|
_wl_selection_send, &wl_cnp_selection);
|
||||||
|
ecore_event_handler_add(ECORE_WL_EVENT_SELECTION_DATA_READY,
|
||||||
|
_wl_selection_receive, &wl_cnp_selection);
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1711,10 +1821,17 @@ _local_elm_selection_selection_has_owner(Evas_Object *obj __UNUSED__)
|
||||||
// common internal funcs
|
// common internal funcs
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_elm_cnp_init(void)
|
_elm_cnp_init(Evas_Object *obj)
|
||||||
{
|
{
|
||||||
if (_elm_cnp_init_count > 0) return EINA_TRUE;
|
if (_elm_cnp_init_count > 0) return EINA_TRUE;
|
||||||
_elm_cnp_init_count++;
|
_elm_cnp_init_count++;
|
||||||
|
#ifdef HAVE_ELEMENTARY_X
|
||||||
|
if (_x11_elm_widget_xwin_get(obj)) _x11_elm_cnp_init();
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ELEMENTARY_WAYLAND
|
||||||
|
if (elm_win_wl_window_get(obj)) _wl_elm_cnp_init();
|
||||||
|
#endif
|
||||||
|
_local_elm_cnp_init();
|
||||||
text_uri = eina_stringshare_add("text/uri-list");
|
text_uri = eina_stringshare_add("text/uri-list");
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1838,10 +1955,14 @@ elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type selection,
|
||||||
Elm_Sel_Format format, const void *selbuf, size_t buflen)
|
Elm_Sel_Format format, const void *selbuf, size_t buflen)
|
||||||
{
|
{
|
||||||
if (selection > ELM_SEL_TYPE_CLIPBOARD) return EINA_FALSE;
|
if (selection > ELM_SEL_TYPE_CLIPBOARD) return EINA_FALSE;
|
||||||
if (!_elm_cnp_init_count) _elm_cnp_init();
|
if (!_elm_cnp_init_count) _elm_cnp_init(obj);
|
||||||
#ifdef HAVE_ELEMENTARY_X
|
#ifdef HAVE_ELEMENTARY_X
|
||||||
if (_x11_elm_widget_xwin_get(obj))
|
if (_x11_elm_widget_xwin_get(obj))
|
||||||
return _x11_elm_cnp_selection_set(obj, selection, format, selbuf, buflen);
|
return _x11_elm_cnp_selection_set(obj, selection, format, selbuf, buflen);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ELEMENTARY_WAYLAND
|
||||||
|
if (elm_win_wl_window_get(obj))
|
||||||
|
return _wl_elm_cnp_selection_set(obj, selection, format, selbuf, buflen);
|
||||||
#endif
|
#endif
|
||||||
return _local_elm_cnp_selection_set(obj, selection, format, selbuf, buflen);
|
return _local_elm_cnp_selection_set(obj, selection, format, selbuf, buflen);
|
||||||
}
|
}
|
||||||
|
@ -1852,7 +1973,7 @@ elm_cnp_selection_loss_callback_set(Evas_Object *obj, Elm_Sel_Type selection,
|
||||||
const void *data)
|
const void *data)
|
||||||
{
|
{
|
||||||
if (selection > ELM_SEL_TYPE_CLIPBOARD) return;
|
if (selection > ELM_SEL_TYPE_CLIPBOARD) return;
|
||||||
if (!_elm_cnp_init_count) _elm_cnp_init();
|
if (!_elm_cnp_init_count) _elm_cnp_init(obj);
|
||||||
#ifdef HAVE_ELEMENTARY_X
|
#ifdef HAVE_ELEMENTARY_X
|
||||||
if (_x11_elm_widget_xwin_get(obj))
|
if (_x11_elm_widget_xwin_get(obj))
|
||||||
_x11_elm_cnp_selection_loss_callback_set(obj, selection, func, data);
|
_x11_elm_cnp_selection_loss_callback_set(obj, selection, func, data);
|
||||||
|
@ -1864,7 +1985,7 @@ EAPI Eina_Bool
|
||||||
elm_object_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type selection)
|
elm_object_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type selection)
|
||||||
{
|
{
|
||||||
if (selection > ELM_SEL_TYPE_CLIPBOARD) return EINA_FALSE;
|
if (selection > ELM_SEL_TYPE_CLIPBOARD) return EINA_FALSE;
|
||||||
if (!_elm_cnp_init_count) _elm_cnp_init();
|
if (!_elm_cnp_init_count) _elm_cnp_init(obj);
|
||||||
#ifdef HAVE_ELEMENTARY_X
|
#ifdef HAVE_ELEMENTARY_X
|
||||||
if (_x11_elm_widget_xwin_get(obj))
|
if (_x11_elm_widget_xwin_get(obj))
|
||||||
return _x11_elm_object_cnp_selection_clear(obj, selection);
|
return _x11_elm_object_cnp_selection_clear(obj, selection);
|
||||||
|
@ -1877,10 +1998,14 @@ elm_cnp_selection_get(Evas_Object *obj, Elm_Sel_Type selection,
|
||||||
Elm_Sel_Format format, Elm_Drop_Cb datacb, void *udata)
|
Elm_Sel_Format format, Elm_Drop_Cb datacb, void *udata)
|
||||||
{
|
{
|
||||||
if (selection > ELM_SEL_TYPE_CLIPBOARD) return EINA_FALSE;
|
if (selection > ELM_SEL_TYPE_CLIPBOARD) return EINA_FALSE;
|
||||||
if (!_elm_cnp_init_count) _elm_cnp_init();
|
if (!_elm_cnp_init_count) _elm_cnp_init(obj);
|
||||||
#ifdef HAVE_ELEMENTARY_X
|
#ifdef HAVE_ELEMENTARY_X
|
||||||
if (_x11_elm_widget_xwin_get(obj))
|
if (_x11_elm_widget_xwin_get(obj))
|
||||||
return _x11_elm_cnp_selection_get(obj, selection, format, datacb, udata);
|
return _x11_elm_cnp_selection_get(obj, selection, format, datacb, udata);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ELEMENTARY_WAYLAND
|
||||||
|
if (elm_win_wl_window_get(obj))
|
||||||
|
return _wl_elm_cnp_selection_get(obj, selection, format, datacb, udata);
|
||||||
#endif
|
#endif
|
||||||
return _local_elm_cnp_selection_get(obj, selection, format, datacb, udata);
|
return _local_elm_cnp_selection_get(obj, selection, format, datacb, udata);
|
||||||
}
|
}
|
||||||
|
@ -1894,7 +2019,7 @@ EAPI Eina_Bool
|
||||||
elm_drop_target_add(Evas_Object *obj, Elm_Sel_Type format,
|
elm_drop_target_add(Evas_Object *obj, Elm_Sel_Type format,
|
||||||
Elm_Drop_Cb dropcb, void *cbdata)
|
Elm_Drop_Cb dropcb, void *cbdata)
|
||||||
{
|
{
|
||||||
if (!_elm_cnp_init_count) _elm_cnp_init();
|
if (!_elm_cnp_init_count) _elm_cnp_init(obj);
|
||||||
#ifdef HAVE_ELEMENTARY_X
|
#ifdef HAVE_ELEMENTARY_X
|
||||||
if (_x11_elm_widget_xwin_get(obj))
|
if (_x11_elm_widget_xwin_get(obj))
|
||||||
return _x11_elm_drop_target_add(obj, format, dropcb, cbdata);
|
return _x11_elm_drop_target_add(obj, format, dropcb, cbdata);
|
||||||
|
@ -1905,7 +2030,7 @@ elm_drop_target_add(Evas_Object *obj, Elm_Sel_Type format,
|
||||||
EAPI Eina_Bool
|
EAPI Eina_Bool
|
||||||
elm_drop_target_del(Evas_Object *obj)
|
elm_drop_target_del(Evas_Object *obj)
|
||||||
{
|
{
|
||||||
if (!_elm_cnp_init_count) _elm_cnp_init();
|
if (!_elm_cnp_init_count) _elm_cnp_init(obj);
|
||||||
#ifdef HAVE_ELEMENTARY_X
|
#ifdef HAVE_ELEMENTARY_X
|
||||||
if (_x11_elm_widget_xwin_get(obj))
|
if (_x11_elm_widget_xwin_get(obj))
|
||||||
return _x11_elm_drop_target_del(obj);
|
return _x11_elm_drop_target_del(obj);
|
||||||
|
@ -1917,7 +2042,7 @@ EAPI Eina_Bool
|
||||||
elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data,
|
elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data,
|
||||||
void (*dragdone) (void *data, Evas_Object *), void *donecbdata)
|
void (*dragdone) (void *data, Evas_Object *), void *donecbdata)
|
||||||
{
|
{
|
||||||
if (!_elm_cnp_init_count) _elm_cnp_init();
|
if (!_elm_cnp_init_count) _elm_cnp_init(obj);
|
||||||
#ifdef HAVE_ELEMENTARY_X
|
#ifdef HAVE_ELEMENTARY_X
|
||||||
if (_x11_elm_widget_xwin_get(obj))
|
if (_x11_elm_widget_xwin_get(obj))
|
||||||
return _x11_elm_drag_start(obj, format, data, dragdone, donecbdata);
|
return _x11_elm_drag_start(obj, format, data, dragdone, donecbdata);
|
||||||
|
@ -1928,10 +2053,13 @@ elm_drag_start(Evas_Object *obj, Elm_Sel_Format format, const char *data,
|
||||||
EAPI Eina_Bool
|
EAPI Eina_Bool
|
||||||
elm_selection_selection_has_owner(Evas_Object *obj)
|
elm_selection_selection_has_owner(Evas_Object *obj)
|
||||||
{
|
{
|
||||||
if (!_elm_cnp_init_count) _elm_cnp_init();
|
if (!_elm_cnp_init_count) _elm_cnp_init(obj);
|
||||||
#ifdef HAVE_ELEMENTARY_X
|
#ifdef HAVE_ELEMENTARY_X
|
||||||
if (_x11_elm_widget_xwin_get(obj))
|
if (_x11_elm_widget_xwin_get(obj))
|
||||||
return _x11_elm_selection_selection_has_owner(obj);
|
return _x11_elm_selection_selection_has_owner(obj);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ELEMENTARY_WAYLAND
|
||||||
|
return ecore_wl_dnd_selection_has_owner(ecore_wl_dnd_get());
|
||||||
#endif
|
#endif
|
||||||
return _local_elm_selection_selection_has_owner(obj);
|
return _local_elm_selection_selection_has_owner(obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1272,6 +1272,18 @@ _paste(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
|
||||||
else if (wd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
|
else if (wd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
|
||||||
formats |= ELM_SEL_FORMAT_IMAGE;
|
formats |= ELM_SEL_FORMAT_IMAGE;
|
||||||
elm_cnp_selection_get(data, ELM_SEL_TYPE_CLIPBOARD, formats, NULL, NULL);
|
elm_cnp_selection_get(data, ELM_SEL_TYPE_CLIPBOARD, formats, NULL, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef HAVE_ELEMENTARY_WAYLAND
|
||||||
|
Elm_Sel_Format formats = ELM_SEL_FORMAT_MARKUP;
|
||||||
|
wd->selection_asked = EINA_TRUE;
|
||||||
|
if (wd->cnp_mode == ELM_CNP_MODE_PLAINTEXT)
|
||||||
|
formats = ELM_SEL_FORMAT_TEXT;
|
||||||
|
else if (wd->cnp_mode != ELM_CNP_MODE_NO_IMAGE)
|
||||||
|
formats |= ELM_SEL_FORMAT_IMAGE;
|
||||||
|
elm_cnp_selection_get(data, ELM_SEL_TYPE_CLIPBOARD, formats, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue