add support for text/x-moz-url DND operations
authorMike Blumenkrantz <m.blumenkran@samsung.com>
Wed, 29 May 2013 11:46:51 +0000 (12:46 +0100)
committerMike Blumenkrantz <m.blumenkran@samsung.com>
Wed, 29 May 2013 12:46:11 +0000 (13:46 +0100)
ChangeLog
NEWS
src/lib/ecore_x/Ecore_X.h
src/lib/ecore_x/Ecore_X_Atoms.h
src/lib/ecore_x/ecore_x_atoms_decl.h
src/lib/ecore_x/xcb/ecore_xcb_selection.c
src/lib/ecore_x/xlib/ecore_x_selection.c

index 43896da4286e0633bf55c5a4cd8de0b6f851c10d..ff35f3f5d5897fdabc4a3f29c6cac4d42eacf0d6 100644 (file)
--- 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 1e75370f408c764d4acb053cbe6a7a0f8f655752..3fcda0b5dcd683dd65de86b4b486f543d905d517 100644 (file)
--- 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.
index 876770474fb96f1641393cde181a63f3a1416eab..fa10024a27ff464d70ac59d76c8a8d6128713649 100644 (file)
@@ -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;
index 2048c7488e7a2d0c2c30b65826a13c722c6d82c7..48e01b69850b22c8171ad787e680c997d090612a 100644 (file)
@@ -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;
index e30bc359e88fa5718531e476de68f8824276f2b0..dc405100618f3d74b6d7430e08856c5f17f29ec8 100644 (file)
@@ -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 },
index c75878320ca585eb27c55624f3479c03d5c19b83..338e8450de09f8b4b1014914ac76846545e7614b 100644 (file)
@@ -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);
 }
index ae2d41c5af54dc1ba32a89b4ebc4cb5d416ff2c1..8e2efa411b191d8bf837772e297e436414df0b3f 100644 (file)
@@ -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 <errno.h>
+# include <iconv.h>
+#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)
 {