[PATCH 2/3] elem_cnp: Add Copy and Paste support for wayland.

zhiwen.wu at linux.intel.com zhiwen.wu at linux.intel.com
Fri Aug 3 01:02:23 PDT 2012


From: Alex Wu <zhiwen.wu at linux.intel.com>

Just support type of ELM_SEL_TYPE_CLIPBOARD. Use
HAVE_ELEMENTARY_WAYLAND macro to build againt wayland engine, and use
elm_win_wl_window_get() run-time engine check.
---
 trunk/elementary/src/lib/elm_cnp.c |  121 +++++++++++++++++++++++++++++++++++-
 1 file changed, 119 insertions(+), 2 deletions(-)

diff --git a/trunk/elementary/src/lib/elm_cnp.c b/trunk/elementary/src/lib/elm_cnp.c
index 6da63ad..e28a861 100644
--- a/trunk/elementary/src/lib/elm_cnp.c
+++ b/trunk/elementary/src/lib/elm_cnp.c
@@ -410,6 +410,28 @@ static Ecore_Event_Handler *handler_drop = NULL;
 static Ecore_Event_Handler *handler_enter = NULL;
 static Ecore_Event_Handler *handler_status = NULL;
 
+#elif defined HAVE_ELEMENTARY_WAYLAND
+static int _elm_cnp_init_count = 0;
+static Eina_Bool _elm_cnp_init(void);
+typedef struct _Cnp_Selection Cnp_Selection;
+
+struct _Cnp_Selection
+{
+   char *selbuf;
+   int buflen;
+   
+   Evas_Object *widget;
+   Evas_Object *requestwidget;
+};
+
+static Cnp_Selection cnp_selection = {0, };
+
+static void
+_sel_obj_del2(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Cnp_Selection *sel = data;
+   if (sel->requestwidget == obj) sel->requestwidget = NULL;
+}
 #endif
 
 /* Stringshared, so I can just compare pointers later */
@@ -521,6 +543,25 @@ elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type selection,
      sel->selbuf = NULL;
 
    return EINA_TRUE;
+#elif defined HAVE_ELEMENTARY_WAYLAND
+   char *types[10] = {0, };
+
+   if (elm_win_wl_window_get(obj) == NULL) return EINA_FALSE;
+   if (!_elm_cnp_init_count) _elm_cnp_init();
+
+   /* TODO: other EML_SEL_TYPE and ELM_SEL_FORMAT */
+   if (ELM_SEL_TYPE_CLIPBOARD == selection) 
+     {
+        types[0] = "text/plain;charset=utf-8";
+        ecore_wl_dnd_set_selection(ecore_wl_dnd_get(), types);
+
+        if (cnp_selection.selbuf) free(cnp_selection.selbuf);
+        cnp_selection.selbuf = strdup((char*)selbuf);
+        cnp_selection.buflen = buflen;
+        return EINA_TRUE;
+     }
+   
+   return EINA_FALSE;
 #else
    return EINA_FALSE;
 #endif
@@ -610,6 +651,22 @@ elm_cnp_selection_get(Evas_Object *obj, Elm_Sel_Type selection,
      (sel->requestwidget, EVAS_CALLBACK_DEL, _sel_obj_del2, sel);
    
    return EINA_TRUE;
+#elif defined HAVE_ELEMENTARY_WAYLAND
+   if (elm_win_wl_window_get(obj) == NULL) return EINA_FALSE;
+   if (!_elm_cnp_init_count) _elm_cnp_init();
+   
+   /* For now, just avoid overlapped request */
+   if (cnp_selection.requestwidget) return EINA_FALSE;
+   
+   /* TODO: other EML_SEL_TYPE and ELM_SEL_FORMAT */
+   if (ELM_SEL_TYPE_CLIPBOARD == selection)
+     {
+        cnp_selection.requestwidget = obj;
+        evas_object_event_callback_add(cnp_selection.requestwidget, EVAS_CALLBACK_DEL,
+                                       _sel_obj_del2, &cnp_selection);
+        ecore_wl_dnd_get_selection(ecore_wl_dnd_get(), "text/plain;charset=utf-8");
+     }
+   return EINA_TRUE;
 #else
    return EINA_FALSE;
 #endif
@@ -1768,8 +1825,68 @@ tmpinfo_free(Tmp_Info *info)
    return 0;
 }
 
-#else
-/* Stubs for windows */
+#elif defined HAVE_ELEMENTARY_WAYLAND
+static Eina_Bool
+selection_send(void *udata, int type __UNUSED__, void *event)
+{
+   char *buf;
+   int ret, len_remained;
+   int len_written = 0;
+   Cnp_Selection *cnp_selection = udata;
+   Ecore_Wl_Event_Data_Source_Send *ev = event;
+   
+   len_remained = cnp_selection->buflen;
+   buf = cnp_selection->selbuf;
+   
+   while (len_written < cnp_selection->buflen)
+     {
+        ret = write(ev->fd, buf, len_remained);
+        if (ret == -1) break;
+        buf += ret;
+        len_written += ret;
+        len_remained -= ret;
+     }
+
+   close(ev->fd);
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+selection_receive(void *udata, int type __UNUSED__, void *event)
+{
+   Cnp_Selection *cnp_selection = udata;
+   Ecore_Wl_Event_Selection_Data_Ready *ev = event;
+   
+   if (cnp_selection->requestwidget)
+     {
+        if (!ev->done)
+          {
+             /* TODO BUG: should never NEVER assume it's an elm_entry! */
+             _elm_entry_entry_paste(cnp_selection->requestwidget, ev->data);
+          }
+        else
+          {
+             evas_object_event_callback_del_full(cnp_selection->requestwidget, EVAS_CALLBACK_DEL,
+                                                 _sel_obj_del2, cnp_selection);
+             cnp_selection->requestwidget = NULL;
+          }
+     }
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_elm_cnp_init(void)
+{
+   if (_elm_cnp_init_count++) return EINA_TRUE;
+
+   ecore_event_handler_add(ECORE_WL_EVENT_DATA_SOURCE_SEND, selection_send, &cnp_selection);
+   ecore_event_handler_add(ECORE_WL_EVENT_SELECTION_DATA_READY, selection_receive, &cnp_selection);
+
+   return EINA_TRUE;
+}
+
+/* Stubs for wayland */
 Eina_Bool
 elm_drag_start(Evas_Object *o, Elm_Sel_Format f, const char *d, void (*donecb)(void *, Evas_Object *),void *cbdata)
 {
-- 
1.7.9.5



More information about the wayland-devel mailing list