thiep pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=1bc9483a82bf18be386e2dde891be20926b5d8bb

commit 1bc9483a82bf18be386e2dde891be20926b5d8bb
Author: Thiep Ha <thie...@gmail.com>
Date:   Tue May 3 09:07:48 2016 +0000

    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.
---
 src/lib/elementary/elm_cnp.c | 218 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 212 insertions(+), 6 deletions(-)

diff --git a/src/lib/elementary/elm_cnp.c b/src/lib/elementary/elm_cnp.c
index 848febe..8288b5e 100644
--- a/src/lib/elementary/elm_cnp.c
+++ b/src/lib/elementary/elm_cnp.c
@@ -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) {
@@ -446,6 +463,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
 #ifdef HAVE_ELEMENTARY_X
         .x_converter = _x11_targets_converter,
 #endif
+#ifdef HAVE_ELEMENTARY_WL2
+        .wl_converter = _wl_targets_converter,
+#endif
    },
    ARRAYINIT(CNP_ATOM_XELM)  {
         .name = "application/x-elementary-markup",
@@ -454,6 +474,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
         .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) {
         .name = "text/uri-list",
@@ -462,6 +485,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
         .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) {
         .name = "text/x-vcard",
@@ -551,6 +577,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
       .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) {
       .name = "text/html",
@@ -559,6 +588,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
       .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_UTF8STRING) {
@@ -568,6 +600,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
         .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) {
         .name = "STRING",
@@ -576,6 +611,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
         .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) {
         .name = "COMPOUND_TEXT",
@@ -584,6 +622,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
         .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) {
         .name = "TEXT",
@@ -592,6 +633,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
         .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) {
         .name = "text/plain;charset=utf-8",
@@ -600,6 +644,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
         .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) {
         .name = "text/plain",
@@ -608,6 +655,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
         .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;

-- 


Reply via email to