diff --git a/src/lib/elementary/elm_cnp.c b/src/lib/elementary/elm_cnp.c index 848febe714..8288b5e7bf 100644 --- a/src/lib/elementary/elm_cnp.c +++ b/src/lib/elementary/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 @@ -250,6 +250,15 @@ static Eina_Bool _x11_elm_selection_selection_has_owner (Evas_Object *obj EINA_ #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); +#endif + struct _Cnp_Atom { const char *name; @@ -261,6 +270,10 @@ struct _Cnp_Atom /* Atom */ Ecore_X_Atom x_atom; #endif +#ifdef HAVE_ELEMENTARY_WL2 + Wl_Converter_Fn_Cb wl_converter; +#endif + void *_term; }; @@ -438,6 +451,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_WL2 + .wl_converter = _wl_targets_converter, #endif }, ARRAYINIT(CNP_ATOM_ATOM) { @@ -445,6 +462,9 @@ 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_WL2 + .wl_converter = _wl_targets_converter, #endif }, ARRAYINIT(CNP_ATOM_XELM) { @@ -453,6 +473,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { #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, #endif }, ARRAYINIT(CNP_ATOM_text_urilist) { @@ -461,6 +484,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { #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, #endif }, ARRAYINIT(CNP_ATOM_text_x_vcard) { @@ -550,6 +576,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { #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, #endif }, ARRAYINIT(CNP_ATOM_text_html) { @@ -558,6 +587,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { #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, #endif }, */ @@ -567,6 +599,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { #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, #endif }, ARRAYINIT(CNP_ATOM_STRING) { @@ -575,6 +610,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { #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, #endif }, ARRAYINIT(CNP_ATOM_COMPOUND_TEXT) { @@ -583,6 +621,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { #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, #endif }, ARRAYINIT(CNP_ATOM_TEXT) { @@ -591,6 +632,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { #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, #endif }, ARRAYINIT(CNP_ATOM_text_plain_utf8) { @@ -599,6 +643,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { #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, #endif }, ARRAYINIT(CNP_ATOM_text_plain) { @@ -607,6 +654,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = { #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, #endif }, }; @@ -2304,8 +2354,6 @@ _x11_elm_selection_selection_has_owner(Evas_Object *obj EINA_UNUSED) #endif #ifdef HAVE_ELEMENTARY_WL2 -typedef struct _Wl_Cnp_Selection Wl_Cnp_Selection; - struct _Wl_Cnp_Selection { char *selbuf; @@ -2373,6 +2421,136 @@ 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_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) { @@ -3154,15 +3332,42 @@ _wl_dnd_send(void *data, int type EINA_UNUSED, void *event) 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; cnp_debug("In\n"); ev = 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; + drop = eo_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; + } + } - 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; @@ -3170,6 +3375,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;