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.
This commit is contained in:
Thiep Ha 2016-05-03 09:07:48 +00:00
parent b917eb4c25
commit 1bc9483a82
1 changed files with 212 additions and 6 deletions

View File

@ -8,7 +8,7 @@
# include <sys/mman.h>
#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;