From dd2d0c46baa8ad1c1221dc7fd4a9f60767c85207 Mon Sep 17 00:00:00 2001 From: Thiep Ha Date: Tue, 3 May 2016 09:07:48 +0000 Subject: [PATCH] elm dnd/wl: add type converters we support different types for DnD, but there is no converters. This patch adds converters for types, so that we can send different data for different types. Change-Id: I1150a3189091dc506d7164efc78f58b5a2fc4ea4 --- src/lib/elm_cnp.c | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 212 insertions(+), 4 deletions(-) diff --git a/src/lib/elm_cnp.c b/src/lib/elm_cnp.c index 8ef65ad..13198db 100644 --- a/src/lib/elm_cnp.c +++ b/src/lib/elm_cnp.c @@ -8,7 +8,7 @@ # include #endif -//#define DEBUGON 1 +#define DEBUGON 1 #ifdef DEBUGON # define cnp_debug(fmt, args...) fprintf(stderr, __FILE__":%s/%d : " fmt , __FUNCTION__, __LINE__, ##args) #else @@ -252,6 +252,15 @@ static Eina_Bool _x11_elm_selection_selection_has_owner (Evas_Object *obj EINA_ #endif +#ifdef HAVE_ELEMENTARY_WAYLAND +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); +#endif + struct _Cnp_Atom { const char *name; @@ -263,6 +272,10 @@ struct _Cnp_Atom /* Atom */ Ecore_X_Atom x_atom; #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + Wl_Converter_Fn_Cb wl_converter; +#endif + void *_term; }; @@ -440,6 +453,10 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { .formats = ELM_SEL_FORMAT_TARGETS, #ifdef HAVE_ELEMENTARY_X .x_converter = _x11_targets_converter, + +#endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_targets_converter, #endif }, ARRAYINIT(CNP_ATOM_ATOM) { @@ -448,6 +465,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { #ifdef HAVE_ELEMENTARY_X .x_converter = _x11_targets_converter, #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_targets_converter, +#endif }, ARRAYINIT(CNP_ATOM_XELM) { .name = "application/x-elementary-markup", @@ -456,6 +476,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { .x_converter = _x11_general_converter, .x_data_preparer = _x11_data_preparer_markup, #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_general_converter, +#endif }, ARRAYINIT(CNP_ATOM_text_urilist) { .name = "text/uri-list", @@ -464,6 +487,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { .x_converter = _x11_general_converter, .x_data_preparer = _x11_data_preparer_uri, #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_general_converter, +#endif }, ARRAYINIT(CNP_ATOM_text_x_vcard) { .name = "text/x-vcard", @@ -553,6 +579,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { .x_converter = _x11_general_converter, .x_notify = _x11_notify_handler_html, #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_general_converter, +#endif }, ARRAYINIT(CNP_ATOM_text_html) { .name = "text/html", @@ -561,6 +590,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { .x_converter = _x11_general_converter, .x_notify = _x11_notify_handler_html, #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_general_converter, +#endif }, */ ARRAYINIT(CNP_ATOM_UTF8STRING) { @@ -570,6 +602,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { .x_converter = _x11_text_converter, .x_data_preparer = _x11_data_preparer_text, #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_text_converter, +#endif }, ARRAYINIT(CNP_ATOM_STRING) { .name = "STRING", @@ -578,6 +613,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { .x_converter = _x11_text_converter, .x_data_preparer = _x11_data_preparer_text, #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_text_converter, +#endif }, ARRAYINIT(CNP_ATOM_COMPOUND_TEXT) { .name = "COMPOUND_TEXT", @@ -586,6 +624,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { .x_converter = _x11_text_converter, .x_data_preparer = _x11_data_preparer_text, #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_text_converter, +#endif }, ARRAYINIT(CNP_ATOM_TEXT) { .name = "TEXT", @@ -594,6 +635,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { .x_converter = _x11_text_converter, .x_data_preparer = _x11_data_preparer_text, #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_text_converter, +#endif }, ARRAYINIT(CNP_ATOM_text_plain_utf8) { .name = "text/plain;charset=utf-8", @@ -602,6 +646,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { .x_converter = _x11_text_converter, .x_data_preparer = _x11_data_preparer_text, #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_text_converter, +#endif }, ARRAYINIT(CNP_ATOM_text_plain) { .name = "text/plain", @@ -610,6 +657,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { .x_converter = _x11_text_converter, .x_data_preparer = _x11_data_preparer_text, #endif +#ifdef HAVE_ELEMENTARY_WAYLAND + .wl_converter = _wl_text_converter, +#endif }, }; @@ -2399,6 +2449,136 @@ static Eina_Bool _wl_drops_accept(const char *type); static unsigned int _wl_elm_widget_window_get(const Evas_Object *obj); static Evas * _wl_evas_get_from_win(unsigned int win); +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; + Cnp_Atom *atom = NULL; + + 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) + { + len += strlen(_atoms[i].name) + strlen(sep); + } + } + aret = calloc(1, len * sizeof(char)); + if (!aret) return EINA_FALSE; + for (i = 0; i < CNP_N_ATOMS; i++) + { + if (formats & _atoms[i].formats) + { + 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) +{ + cnp_debug("in\n"); + Elm_Sel_Format formats = ELM_SEL_FORMAT_NONE; + Cnp_Atom *atom = NULL; + + 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) +{ + cnp_debug("in\n"); + Elm_Sel_Format formats = ELM_SEL_FORMAT_NONE; + Cnp_Atom *atom = NULL; + + 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_sel_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) { @@ -3338,6 +3518,9 @@ _wl_dnd_send(void *data, int type EINA_UNUSED, void *event) int len_written = 0; Wl_Cnp_Selection *sel; Ecore_Wl_Event_Data_Source_Send *ev; + void *data_ret = NULL; + int len_ret = 0; + int i = 0; cnp_debug("In\n"); ev = event; @@ -3369,10 +3552,34 @@ _wl_dnd_send(void *data, int type EINA_UNUSED, void *event) //sel = data; // - len_remained = sel->buflen; - buf = sel->selbuf; + 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; + eo_do(sel->requestwidget, drop = eo_key_data_get("__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; + } + } - while (len_written < sel->buflen) + len_remained = len_ret; + buf = data_ret; + cnp_debug("write: %s\n", buf); + + while (len_written < len_ret) { ret = write(ev->fd, buf, len_remained); if (ret == -1) break; @@ -3380,6 +3587,7 @@ _wl_dnd_send(void *data, int type EINA_UNUSED, void *event) len_written += ret; len_remained -= ret; } + free(data_ret); close(ev->fd); return ECORE_CALLBACK_PASS_ON; -- 2.7.4