From fbd09e2562e60186c8327717c04b0a191e6906ab Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 29 May 2013 12:46:51 +0100 Subject: [PATCH] add support for text/x-moz-url DND operations --- ChangeLog | 1 + NEWS | 1 + src/lib/ecore_x/Ecore_X.h | 10 ++++ src/lib/ecore_x/Ecore_X_Atoms.h | 1 + src/lib/ecore_x/ecore_x_atoms_decl.h | 2 + src/lib/ecore_x/xcb/ecore_xcb_selection.c | 70 +++++++++++++++++++++++ src/lib/ecore_x/xlib/ecore_x_selection.c | 69 ++++++++++++++++++++++ 7 files changed, 154 insertions(+) diff --git a/ChangeLog b/ChangeLog index 43896da428..ff35f3f5d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2013-05-29 Mike Blumenkrantz * Added eina_str_convert_len() to work around broken eina_str_convert() + * Add ecore-x(cb) support for text/x-moz-url DND operations 2013-05-28 ChunEon Park (Hermet) diff --git a/NEWS b/NEWS index 1e75370f40..3fcda0b5dc 100644 --- a/NEWS +++ b/NEWS @@ -46,6 +46,7 @@ Additions: ecore_x_randr_crtc_info_free() ecore_x_dnd_self_begin() ecore_x_dnd_self_drop() + support for text/x-moz-url DND operations * ecore_wayland: - Store global wayland interfaces in a globals list so wayland programs can bind to other non-standard wayland protocol extensions. diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h index 876770474f..fa10024a27 100644 --- a/src/lib/ecore_x/Ecore_X.h +++ b/src/lib/ecore_x/Ecore_X.h @@ -259,6 +259,7 @@ typedef enum _Ecore_X_Randr_Edid_Aspect_Ratio #define ECORE_X_SELECTION_TARGET_STRING "STRING" #define ECORE_X_SELECTION_TARGET_UTF8_STRING "UTF8_STRING" #define ECORE_X_SELECTION_TARGET_FILENAME "FILENAME" +#define ECORE_X_SELECTION_TARGET_X_MOZ_URL "X_MOZ_URL" #define ECORE_X_DND_VERSION 5 @@ -427,6 +428,7 @@ typedef struct _Ecore_X_Event_Fixes_Selection_Notify Ecore_X_Event_Fixes_S typedef struct _Ecore_X_Selection_Data Ecore_X_Selection_Data; typedef struct _Ecore_X_Selection_Data_Files Ecore_X_Selection_Data_Files; typedef struct _Ecore_X_Selection_Data_Text Ecore_X_Selection_Data_Text; +typedef struct _Ecore_X_Selection_Data_X_Moz_Url Ecore_X_Selection_Data_X_Moz_Url; typedef struct _Ecore_X_Selection_Data_Targets Ecore_X_Selection_Data_Targets; typedef struct _Ecore_X_Event_Xdnd_Enter Ecore_X_Event_Xdnd_Enter; typedef struct _Ecore_X_Event_Xdnd_Position Ecore_X_Event_Xdnd_Position; @@ -714,6 +716,7 @@ struct _Ecore_X_Selection_Data ECORE_X_SELECTION_CONTENT_NONE, ECORE_X_SELECTION_CONTENT_TEXT, ECORE_X_SELECTION_CONTENT_FILES, + ECORE_X_SELECTION_CONTENT_X_MOZ_URL, ECORE_X_SELECTION_CONTENT_TARGETS, ECORE_X_SELECTION_CONTENT_CUSTOM } content; @@ -736,6 +739,13 @@ struct _Ecore_X_Selection_Data_Text char *text; }; +struct _Ecore_X_Selection_Data_X_Moz_Url +{ + Ecore_X_Selection_Data data; + Eina_Inarray *links; + Eina_Inarray *link_names; +}; + struct _Ecore_X_Selection_Data_Targets { Ecore_X_Selection_Data data; diff --git a/src/lib/ecore_x/Ecore_X_Atoms.h b/src/lib/ecore_x/Ecore_X_Atoms.h index 2048c7488e..48e01b6985 100644 --- a/src/lib/ecore_x/Ecore_X_Atoms.h +++ b/src/lib/ecore_x/Ecore_X_Atoms.h @@ -14,6 +14,7 @@ EAPI extern Ecore_X_Atom ECORE_X_ATOM_FILE_NAME; EAPI extern Ecore_X_Atom ECORE_X_ATOM_STRING; EAPI extern Ecore_X_Atom ECORE_X_ATOM_TEXT; EAPI extern Ecore_X_Atom ECORE_X_ATOM_UTF8_STRING; +EAPI extern Ecore_X_Atom ECORE_X_ATOM_X_MOZ_URL; EAPI extern Ecore_X_Atom ECORE_X_ATOM_WINDOW; EAPI extern Ecore_X_Atom ECORE_X_ATOM_PIXMAP; EAPI extern Ecore_X_Atom ECORE_X_ATOM_VISUALID; diff --git a/src/lib/ecore_x/ecore_x_atoms_decl.h b/src/lib/ecore_x/ecore_x_atoms_decl.h index e30bc359e8..dc40510061 100644 --- a/src/lib/ecore_x/ecore_x_atoms_decl.h +++ b/src/lib/ecore_x/ecore_x_atoms_decl.h @@ -5,6 +5,7 @@ EAPI Ecore_X_Atom ECORE_X_ATOM_COMPOUND_TEXT = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_FILE_NAME = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_STRING = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_TEXT = 0; +EAPI Ecore_X_Atom ECORE_X_ATOM_X_MOZ_URL = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_UTF8_STRING = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_WINDOW = 0; EAPI Ecore_X_Atom ECORE_X_ATOM_PIXMAP = 0; @@ -353,6 +354,7 @@ const Atom_Item atom_items[] = { "FILE_NAME", &ECORE_X_ATOM_FILE_NAME }, { "STRING", &ECORE_X_ATOM_STRING }, { "TEXT", &ECORE_X_ATOM_TEXT }, + { "X_MOZ_URL", &ECORE_X_ATOM_X_MOZ_URL }, { "UTF8_STRING", &ECORE_X_ATOM_UTF8_STRING }, { "WINDOW", &ECORE_X_ATOM_WINDOW }, { "PIXMAP", &ECORE_X_ATOM_PIXMAP }, diff --git a/src/lib/ecore_x/xcb/ecore_xcb_selection.c b/src/lib/ecore_x/xcb/ecore_xcb_selection.c index c75878320c..338e8450de 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_selection.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_selection.c @@ -8,6 +8,10 @@ static void *_ecore_xcb_selection_parser_text(const char *target EINA_UNUSED, void *data, int size, int format EINA_UNUSED); +static void *_ecore_xcb_selection_parser_xmozurl(const char *target EINA_UNUSED, + void *data, + int size, + int format EINA_UNUSED); static void *_ecore_xcb_selection_parser_files(const char *target, void *data, int size, @@ -61,6 +65,8 @@ _ecore_xcb_selection_init(void) _ecore_xcb_selection_parser_text); ecore_x_selection_parser_add("text/uri-list", _ecore_xcb_selection_parser_files); + ecore_x_selection_parser_add("text/x-moz-url", + _ecore_x_selection_parser_xmozurl); ecore_x_selection_parser_add("_NETSCAPE_URL", _ecore_xcb_selection_parser_files); ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS, @@ -769,6 +775,66 @@ _ecore_xcb_selection_parser_text(const char *target EINA_UNUSED, return sel; } +static int +_ecore_xcb_selection_data_xmozurl_free(void *data) +{ + Ecore_X_Selection_Data_X_Moz_Url *sel = data; + char **buf; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (!sel) return 0; + + buf = eina_inarray_nth(sel->links, 0); + free(*buf); + eina_inarray_free(sel->links); + eina_inarray_free(sel->link_names); + free(sel); + return 1; +} + +static void * +_ecore_xcb_selection_parser_xmozurl(const char *target EINA_UNUSED, + void *_data, + int size, + int format EINA_UNUSED) +{ + Ecore_X_Selection_Data_X_Moz_Url *sel; + char *prev, *n, *buf, *data = _data; + size_t sz; + int num = 0; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + buf = eina_str_convert_len("UTF-16LE", "UTF-8", data, size, &sz); + if (!buf) return NULL; + sel = calloc(1, sizeof(Ecore_X_Selection_Data_X_Moz_Url)); + if (!sel) + { + free(buf); + return NULL; + } + sel->links = eina_inarray_new(sizeof(char*), 0); + sel->link_names = eina_inarray_new(sizeof(char*), 0); + prev = buf; + for (n = memchr(buf, '\n', sz); n; n = memchr(prev, '\n', sz - (prev - buf))) + { + n[0] = 0; + if (num % 2 == 0) + eina_inarray_push(sel->links, &prev); + else + eina_inarray_push(sel->link_names, &prev); + num++; + prev = n + 1; + } + eina_inarray_push(sel->link_names, &prev[0]); + + ECORE_XCB_SELECTION_DATA(sel)->length = size; + ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_X_MOZ_URL; + ECORE_XCB_SELECTION_DATA(sel)->data = (void*)data; + ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_xmozurl_free; + return sel; +} + static void * _ecore_xcb_selection_parser_files(const char *target, void *data, @@ -1004,6 +1070,8 @@ _ecore_xcb_selection_target_atom_get(const char *target) x_target = ECORE_X_ATOM_UTF8_STRING; else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME)) x_target = ECORE_X_ATOM_FILE_NAME; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_X_MOZ_URL)) + x_target = ECORE_X_ATOM_X_MOZ_URL; else x_target = ecore_x_atom_get(target); @@ -1021,6 +1089,8 @@ _ecore_xcb_selection_target_get(Ecore_X_Atom target) return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING); else if (target == ECORE_X_ATOM_TEXT) return strdup(ECORE_X_SELECTION_TARGET_TEXT); + else if (target == ECORE_X_ATOM_X_MOZ_URL) + return strdup(ECORE_X_SELECTION_TARGET_X_MOZ_URL); else return ecore_x_atom_name_get(target); } diff --git a/src/lib/ecore_x/xlib/ecore_x_selection.c b/src/lib/ecore_x/xlib/ecore_x_selection.c index ae2d41c5af..8e2efa411b 100644 --- a/src/lib/ecore_x/xlib/ecore_x_selection.c +++ b/src/lib/ecore_x/xlib/ecore_x_selection.c @@ -34,6 +34,10 @@ static void *_ecore_x_selection_parser_text(const char *target, void *data, int size, int format); +static void *_ecore_x_selection_parser_xmozurl(const char *target, + void *data, + int size, + int format); static int _ecore_x_selection_data_text_free(void *data); static void *_ecore_x_selection_parser_targets(const char *target, void *data, @@ -68,6 +72,8 @@ _ecore_x_selection_data_init(void) _ecore_x_selection_parser_text); ecore_x_selection_parser_add("text/uri-list", _ecore_x_selection_parser_files); + ecore_x_selection_parser_add("text/x-moz-url", + _ecore_x_selection_parser_xmozurl); ecore_x_selection_parser_add("_NETSCAPE_URL", _ecore_x_selection_parser_files); ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS, @@ -316,6 +322,8 @@ _ecore_x_selection_target_atom_get(const char *target) x_target = ECORE_X_ATOM_UTF8_STRING; else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME)) x_target = ECORE_X_ATOM_FILE_NAME; + else if (!strcmp(target, ECORE_X_SELECTION_TARGET_X_MOZ_URL)) + x_target = ECORE_X_ATOM_X_MOZ_URL; else x_target = ecore_x_atom_get(target); @@ -335,6 +343,8 @@ _ecore_x_selection_target_get(Ecore_X_Atom target) return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING); else if (target == ECORE_X_ATOM_TEXT) return strdup(ECORE_X_SELECTION_TARGET_TEXT); + else if (target == ECORE_X_ATOM_X_MOZ_URL) + return strdup(ECORE_X_SELECTION_TARGET_X_MOZ_URL); else return XGetAtomName(_ecore_x_disp, target); } @@ -941,6 +951,65 @@ _ecore_x_selection_parser_text(const char *target EINA_UNUSED, return sel; } +static int +_ecore_x_selection_data_xmozurl_free(void *data) +{ + Ecore_X_Selection_Data_X_Moz_Url *sel = data; + char **buf; + + buf = eina_inarray_nth(sel->links, 0); + free(*buf); + eina_inarray_free(sel->links); + eina_inarray_free(sel->link_names); + free(sel); + return 1; +} +#ifdef HAVE_ICONV +# include +# include +#endif +static void * +_ecore_x_selection_parser_xmozurl(const char *target EINA_UNUSED, + void *_data, + int size, + int format EINA_UNUSED) +{ + Ecore_X_Selection_Data_X_Moz_Url *sel; + char *prev, *n, *buf, *data = _data; + size_t sz; + int num = 0; + + buf = eina_str_convert_len("UTF-16LE", "UTF-8", data, size, &sz); + if (!buf) return NULL; + sel = calloc(1, sizeof(Ecore_X_Selection_Data_X_Moz_Url)); + if (!sel) + { + free(buf); + return NULL; + } + sz = strlen(buf); + sel->links = eina_inarray_new(sizeof(char*), 0); + sel->link_names = eina_inarray_new(sizeof(char*), 0); + prev = buf; + for (n = memchr(buf, '\n', sz); n; n = memchr(prev, '\n', sz - (prev - buf))) + { + n[0] = 0; + if (num % 2 == 0) + eina_inarray_push(sel->links, &prev); + else + eina_inarray_push(sel->link_names, &prev); + num++; + prev = n + 1; + } + eina_inarray_push(sel->link_names, &prev); + + ECORE_X_SELECTION_DATA(sel)->length = size; + ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_X_MOZ_URL; + ECORE_X_SELECTION_DATA(sel)->data = (void*)data; + ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_xmozurl_free; + return sel; +} + static int _ecore_x_selection_data_text_free(void *data) {