From: Thiep Ha Date: Tue, 3 May 2016 09:07:48 +0000 (+0000) Subject: elm dnd/wl: add type converters X-Git-Tag: accepted/tizen/common/20160826.142851~36 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dd2d0c46baa8ad1c1221dc7fd4a9f60767c85207;p=platform%2Fupstream%2Felementary.git 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 --- 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;