port cnp on Windows
authorMarcel Hollerbach <mail@marcel-hollerbach.de>
Sun, 8 Mar 2020 09:46:09 +0000 (10:46 +0100)
committerTaehyub Kim <taehyub.kim@samsung.com>
Tue, 10 Mar 2020 11:08:51 +0000 (20:08 +0900)
Test Plan: Ctrl-c and Ctrl-Vworking

Reviewers: raster, zmike

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D11439

src/lib/ecore_win32/Ecore_Win32.h
src/lib/ecore_win32/ecore_win32_clipboard.c
src/lib/ecore_win32/ecore_win32_event.c
src/modules/ecore_evas/engines/win32/ecore_evas_win32.c

index d9fa81c..8f36b27 100644 (file)
@@ -216,21 +216,6 @@ typedef enum
 } Ecore_Win32_DnD_State;
 
 /**
- * @typedef Ecore_Win32_Selection
- * Type of the selection.
- *
- * @since 1.16
- */
-typedef enum
-{
-   ECORE_WIN32_SELECTION_PRIMARY,
-   ECORE_WIN32_SELECTION_SECONDARY,
-   ECORE_WIN32_SELECTION_DND,
-   ECORE_WIN32_SELECTION_CLIPBOARD,
-   ECORE_WIN32_SELECTION_OTHER
-} Ecore_Win32_Selection;
-
-/**
  * @typedef Ecore_Win32_Window
  * Abstract type for a window.
  */
@@ -326,7 +311,7 @@ typedef struct _Ecore_Win32_Event_Window_Delete_Request Ecore_Win32_Event_Window
  * @typedef Ecore_Win32_Event_Selection_Clear
  * Event sent when the content of the clipboard has been removed.
  *
- * @since 1.16
+ * @since 1.24
  */
 typedef struct _Ecore_Win32_Event_Selection_Clear Ecore_Win32_Event_Selection_Clear;
 
@@ -334,7 +319,7 @@ typedef struct _Ecore_Win32_Event_Selection_Clear Ecore_Win32_Event_Selection_Cl
  * @typedef Ecore_Win32_Event_Selection_Notify
  * Event sent when the content of the clipboard has been added.
  *
- * @since 1.16
+ * @since 1.24
  */
 typedef struct _Ecore_Win32_Event_Selection_Notify Ecore_Win32_Event_Selection_Notify;
 
@@ -490,26 +475,26 @@ struct _Ecore_Win32_Event_Window_Delete_Request
  * @struct _Ecore_Win32_Event_Selection_Clear
  * Event sent when the content of the clipboard has been removed.
  *
- * @since 1.16
+ * @since 1.24
  */
 struct _Ecore_Win32_Event_Selection_Clear
 {
    Ecore_Win32_Window   *window; /**< The window that received the event */
    unsigned long         timestamp; /**< The time the event occurred */
-   Ecore_Win32_Selection selection; /**< The type of the selection */
+   char                 *selection; /**< The type of the selection */
 };
 
 /**
  * @struct _Ecore_Win32_Event_Selection_Notify
  * Event sent when the content of the clipboard has been added.
  *
- * @since 1.16
+ * @since 1.24
  */
 struct _Ecore_Win32_Event_Selection_Notify
 {
    Ecore_Win32_Window   *window; /**< The window that received the event */
    unsigned long         timestamp; /**< The time the event occurred */
-   Ecore_Win32_Selection selection; /**< The type of the selection */
+   char                 *selection; /**< The type of the selection */
    void                 *data; /**< The data of the selection */
 };
 
@@ -702,6 +687,7 @@ EAPI void      ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window
  * @param[in] window The window that owns the clipboard.
  * @param[in] data The data to set.
  * @param[in] size The size of the data.
+ * @param[in] mime_type The mime type describing the data in the clipboard.
  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
  *
  * This function sets @p data of size @p size in the clipboard owned by
@@ -709,11 +695,12 @@ EAPI void      ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window
  * #EINA_FALSE otherwise. If @p window or @p data are @c NULL, or @p size
  * is less than or equal to 0, this function returns #EINA_FALSE.
  *
- * @since 1.16
+ * @since 1.24
  */
 EAPI Eina_Bool ecore_win32_clipboard_set(const Ecore_Win32_Window *window,
                                          const void *data,
-                                         int size);
+                                         size_t size,
+                                         const char *mime_type);
 
 /**
  * @brief Get data from the clipboard.
@@ -721,6 +708,7 @@ EAPI Eina_Bool ecore_win32_clipboard_set(const Ecore_Win32_Window *window,
  * @param[in] window The window that owns the clipboard.
  * @param[out] data The retrieved data.
  * @param[out] size The size of the data.
+ * @param[in] mime_type The mime type describing the data in the clipboard.
  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
  *
  * This function gets @p data of size @p size from the clipboard owned by
@@ -728,25 +716,24 @@ EAPI Eina_Bool ecore_win32_clipboard_set(const Ecore_Win32_Window *window,
  * #EINA_FALSE otherwise. If @p window is @c NULL, this function returns
  * #EINA_FALSE. @p data and @p size must be valid buffers.
  *
- * @since 1.16
+ * @since 1.24
  */
-EAPI Eina_Bool ecore_win32_clipboard_get(const Ecore_Win32_Window *window,
-                                         void **data,
-                                         int *size);
+EAPI void * ecore_win32_clipboard_get(const Ecore_Win32_Window *window,
+                                         size_t *size,
+                                         const char *mime_type);
 
 /**
  * @brief Cleat the clipboard.
  *
  * @param[in] window The window that owns the clipboard.
- * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
  *
  * This function clears the clipboard owned by @p window. This
  * function returns #EINA_TRUE on success, and #EINA_FALSE otherwise.
  * If @p window is @c NULL, this function returns #EINA_FALSE.
  *
- * @since 1.16
+ * @since 1.24
  */
-EAPI Eina_Bool ecore_win32_clipboard_clear(const Ecore_Win32_Window *window);
+EAPI void ecore_win32_clipboard_clear(const Ecore_Win32_Window *window);
 
 /**
  * @typedef Ecore_Win32_Monitor
index a20be68..da49603 100644 (file)
@@ -6,6 +6,7 @@
 #include <windows.h>
 #undef WIN32_LEAN_AND_MEAN
 
+#include <evil_private.h> /* utf-8 and utf-16 conversion */
 #include <Eina.h>
 
 #include "Ecore_Win32.h"
 EAPI Eina_Bool
 ecore_win32_clipboard_set(const Ecore_Win32_Window *window,
                           const void *data,
-                          int size)
+                          size_t size,
+                          const char *mime_type)
 {
    HGLOBAL global;
    char *d;
+   Eina_Bool supported_mime_text;
+   Eina_Bool res = EINA_FALSE;
 
    /*
     * See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms649016%28v=vs.85%29.aspx#_win32_Copying_Information_to_the_Clipboard
@@ -54,47 +58,77 @@ ecore_win32_clipboard_set(const Ecore_Win32_Window *window,
 
    INF("setting data to the clipboard");
 
-   if (!window || !data || (size <= 0))
-     return EINA_FALSE;
+   supported_mime_text = eina_str_has_prefix(mime_type, "text/");
+   if (!supported_mime_text)
+     {
+        ERR("Mimetype %s is not handled yet", mime_type);
+        return EINA_FALSE;
+     }
 
-   if (!OpenClipboard(window->window))
+   if (!window || !data || (size <= 0) || !OpenClipboard(window->window))
      return EINA_FALSE;
 
    if (!EmptyClipboard())
      goto close_clipboard;
 
-   global = GlobalAlloc(GMEM_MOVEABLE, size + 1);
-   if (!global)
-     goto close_clipboard;
-
-   d = (char *)GlobalLock(global);
-   if (!d)
-     goto unlock_global;
-
-   memcpy(d, data, size);
-   d[size] = '\0';
-   GlobalUnlock(global);
-   SetClipboardData(CF_TEXT, global);
-   CloseClipboard();
-
-   return EINA_TRUE;
+   if (supported_mime_text)
+     {
+        wchar_t *text16;
+        size_t size16;
+
+        /* CF_TEXT (UTF-8) */
+
+        global = GlobalAlloc(GMEM_MOVEABLE, size);
+        if (global)
+          {
+             d = (char *)GlobalLock(global);
+             if (d)
+               {
+                  memcpy(d, data, size);
+                  SetClipboardData(CF_TEXT, global);
+                  res = EINA_TRUE;
+                  GlobalUnlock(global);
+               }
+          }
+
+        /* CF_UNICODETEXT (UTF-16) */
+
+        text16 = evil_utf8_to_utf16(data);
+        if (text16)
+          {
+             size16 = (wcslen(text16) + 1) * sizeof(wchar_t);
+
+             global = GlobalAlloc(GMEM_MOVEABLE, size16);
+             if (global)
+               {
+                  d = (char *)GlobalLock(global);
+                  if (d)
+                    {
+                       memcpy(d, text16, size16);
+                       SetClipboardData(CF_UNICODETEXT, global);
+                       res = EINA_TRUE;
+                       GlobalUnlock(global);
+                    }
+               }
+
+             free(text16);
+          }
+     }
 
- unlock_global:
-   GlobalUnlock(global);
  close_clipboard:
    CloseClipboard();
 
-   return EINA_FALSE;
+   return res;
 }
 
-EAPI Eina_Bool
+EAPI void *
 ecore_win32_clipboard_get(const Ecore_Win32_Window *window,
-                          void **data,
-                          int *size)
+                          size_t *size,
+                          const char *mime_type)
 {
    HGLOBAL global;
+   void *data;
    void *d;
-   void *p;
 
    /*
     * See https://msdn.microsoft.com/en-us/library/windows/desktop/ms649016%28v=vs.85%29.aspx#_win32_Pasting_Information_from_the_Clipboard
@@ -107,80 +141,100 @@ ecore_win32_clipboard_get(const Ecore_Win32_Window *window,
 
    INF("getting data from the clipboard");
 
-   if (!window)
-     return EINA_FALSE;
-
-   if (!IsClipboardFormatAvailable(CF_TEXT))
-     return EINA_FALSE;
-
-   if (!OpenClipboard(window->window))
-     goto set_val;
-
-   /* { */
-   /*   UINT fmt = 0; */
+   if (!eina_str_has_prefix(mime_type, "text/"))
+     {
+        ERR("Mimetype %s is not handled yet", mime_type);
+        return NULL;
+     }
 
-   /*   while (1) */
-   /*     { */
-   /*       fmt = EnumClipboardFormats(fmt); */
-   /*       printf(" $ Format : %x\n", fmt); */
-   /*       if (!fmt) */
-   /*         break; */
-   /*     } */
-   /* } */
+   if (!window || !size || !OpenClipboard(window->window))
+     return NULL;
 
-   global = GetClipboardData(CF_TEXT);
-   if (!global)
-     goto close_clipboard;
-
-   d = GlobalLock(global);
-   if (!d)
-     goto unlock_global;
-
-   *size = strlen(d);
-   p = malloc(*size);
-   if (!p)
-     goto unlock_global;
+   *size = 0;
 
-   memcpy(p, d, *size);
-   *data = p;
-   GlobalUnlock(global);
-   CloseClipboard();
+#if 0
+   {
+     UINT fmt = 0;
+
+     while (1)
+       {
+         char name[4096];
+         int res;
+         fmt = EnumClipboardFormats(fmt);
+         res = GetClipboardFormatName(fmt, name, sizeof(name));
+         fprintf(stderr, " $ Format2 : %x %d\n", fmt, res);
+         if (res)
+           fprintf(stderr, " $ Format2 : %s\n", name);
+         else
+           fprintf(stderr, " $ Format2 : error %ld\n", GetLastError());
+         fflush(stderr);
+         if (!fmt)
+           break;
+       }
+   }
+#endif
 
-   return EINA_TRUE;
+   if (eina_str_has_prefix(mime_type, "text/"))
+     {
+        /* first check if UTF-16 text is available */
+        global = GetClipboardData(CF_UNICODETEXT);
+        if (global)
+          {
+             d = GlobalLock(global);
+             if (d)
+               {
+                  data = evil_utf16_to_utf8(d);
+                  if (data)
+                    {
+                       *size = strlen(data);
+                       GlobalUnlock(global);
+                       CloseClipboard();
+                       return data;
+                    }
+                  GlobalUnlock(global);
+               }
+             /* otherwise, we try CF_TEXT (UTF-8/ANSI) */
+          }
+
+        /* second, check if UTF-8/ANSI text is available */
+        global = GetClipboardData(CF_TEXT);
+        if (global)
+          {
+             d = GlobalLock(global);
+             if (d)
+               {
+                  *size = strlen(d) + 1;
+                  data = malloc(*size);
+                  if (data)
+                    {
+                       memcpy(data, d, *size);
+                       GlobalUnlock(global);
+                       CloseClipboard();
+                       return data;
+                    }
+                  else
+                    *size = 0;
+
+                  GlobalUnlock(global);
+               }
+          }
+     }
 
- unlock_global:
-   GlobalUnlock(global);
- close_clipboard:
    CloseClipboard();
- set_val:
-   *data = NULL;
-   *size = 0;
 
-   return EINA_FALSE;
+   return NULL;
 }
 
-EAPI Eina_Bool
+EAPI void
 ecore_win32_clipboard_clear(const Ecore_Win32_Window *window)
 {
    INF("clearing the clipboard");
 
-   if (!window)
-     return EINA_FALSE;
-
-   if (!OpenClipboard(window->window))
-     return EINA_FALSE;
-
-   if (!EmptyClipboard())
-     goto close_clipboard;
-
-   CloseClipboard();
-
-   return EINA_TRUE;
+   if (!window || !OpenClipboard(window->window))
+     return;
 
- close_clipboard:
+   EmptyClipboard();
    CloseClipboard();
-
-   return EINA_FALSE;
 }
 
 /**
index 0c232e7..28a5b1f 100644 (file)
@@ -1958,66 +1958,103 @@ _ecore_win32_event_handle_selection_notify(Ecore_Win32_Callback_Data *msg)
 {
    Ecore_Win32_Event_Selection_Notify *e;
    HGLOBAL global;
-   char *str;
 
    INF("selection_notify");
 
+   e = calloc(1, sizeof(Ecore_Win32_Event_Selection_Notify));
+   if (!e) return;
+
+   e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
+   e->timestamp = _ecore_win32_event_last_time;
+
    /*
-    * we have text data in clipboard but no data before,
-    * so text data has just been added
+    * we have data in clipboard but no data before,
+    * so data has just been added
     */
-   if (IsClipboardFormatAvailable(CF_TEXT) && !_ecore_win32_clipboard_has_data)
+   if (!_ecore_win32_clipboard_has_data)
      {
-        e = calloc(1, sizeof(Ecore_Win32_Event_Selection_Notify));
-        if (!e) return;
-
-        e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
-        e->timestamp = _ecore_win32_event_last_time;
-        e->selection = ECORE_WIN32_SELECTION_CLIPBOARD;
-
+        /* if case someone else is owning the clipboard, we can't do anything */
         if (!OpenClipboard(msg->window))
-          goto free_e;
-
-        global = GetClipboardData(CF_TEXT);
-        if (!global)
-          goto close_clipboard;
+          {
+             free(e);
+             return;
+          }
 
-        str = GlobalLock(global);
-        if (str)
+        if (IsClipboardFormatAvailable(CF_UNICODETEXT))
           {
-             e->data = strdup(str);
-             GlobalUnlock(global);
+             global = GetClipboardData(CF_UNICODETEXT);
+             if (global)
+               {
+                  e->selection = strdup("text/plain;charset=utf-8");
+                  if (e->selection)
+                    {
+                       wchar_t *d;
+
+                       d = (wchar_t *)GlobalLock(global);
+                       if (d)
+                         e->data = evil_utf16_to_utf8(d);
+
+                       GlobalUnlock(global);
+                       if (e->data)
+                         {
+                            ecore_event_add(ECORE_WIN32_EVENT_SELECTION_NOTIFY, e, NULL, NULL);
+                            _ecore_win32_clipboard_has_data = EINA_TRUE;
+                            CloseClipboard();
+                            return;
+                         }
+                    }
+               }
           }
 
+        if (IsClipboardFormatAvailable(CF_TEXT))
+          {
+             global = GetClipboardData(CF_TEXT);
+             if (global)
+               {
+                  e->selection = strdup("text/plain;charset=utf-8");
+                  if (e->selection)
+                    {
+                       char *d;
+
+                       d = (char *)GlobalLock(global);
+                       if (d)
+                         e->data = strdup(d);
+
+                       GlobalUnlock(global);
+                       if (e->data)
+                         {
+                            ecore_event_add(ECORE_WIN32_EVENT_SELECTION_NOTIFY, e, NULL, NULL);
+
+                            _ecore_win32_clipboard_has_data = EINA_TRUE;
+                            CloseClipboard();
+                            return;
+                         }
+                    }
+               }
+          }
+        free(e->data);
+        free(e->selection);
+        free(e);
         CloseClipboard();
-
-        ecore_event_add(ECORE_WIN32_EVENT_SELECTION_NOTIFY, e, NULL, NULL);
-
-        _ecore_win32_clipboard_has_data = EINA_TRUE;
      }
-
    /*
-    * we have no more text data in clipboard and data before,
+    * otherwise, we have no more text data in clipboard and data before,
     * so text data has just been removed
     */
-   if (!IsClipboardFormatAvailable(CF_TEXT) && _ecore_win32_clipboard_has_data)
+   else
      {
-        e = calloc(1, sizeof(Ecore_Win32_Event_Selection_Clear));
-        if (!e) return;
-
-        e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
-        e->timestamp = _ecore_win32_event_last_time;
-        e->selection = ECORE_WIN32_SELECTION_CLIPBOARD;
-
-        ecore_event_add(ECORE_WIN32_EVENT_SELECTION_CLEAR, e, NULL, NULL);
-
-        _ecore_win32_clipboard_has_data = EINA_FALSE;
+       if (!IsClipboardFormatAvailable(CF_UNICODETEXT) &&
+           !IsClipboardFormatAvailable(CF_TEXT))
+         {
+            e->selection = strdup("text/plain;charset=utf-8");
+            if (e->selection)
+              {
+                ecore_event_add(ECORE_WIN32_EVENT_SELECTION_CLEAR, e, NULL, NULL);
+                _ecore_win32_clipboard_has_data = EINA_FALSE;
+                return;
+              }
+         }
      }
 
-   return;
-
- close_clipboard:
-   CloseClipboard();
- free_e:
    free(e);
 }
index 0870d52..d0686c5 100644 (file)
@@ -62,11 +62,15 @@ static const int   interface_win32_version = 1;
 
 typedef struct _Ecore_Evas_Engine_Data_Win32 Ecore_Evas_Engine_Data_Win32;
 
-struct _Ecore_Evas_Engine_Data_Win32 {
+struct _Ecore_Evas_Engine_Data_Win32
+{
    Ecore_Win32_Window *parent;
-   struct {
-     unsigned char region     : 1;
-     unsigned char fullscreen : 1;
+   Ecore_Evas_Selection_Callbacks clipboard;
+   Eina_Future *delivery;
+   struct
+   {
+      unsigned char region     : 1;
+      unsigned char fullscreen : 1;
    } state;
 };
 
@@ -1197,99 +1201,215 @@ _ecore_evas_win32_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi)
      *ydpi = y_dpi;
 }
 
+static Eina_Value
+_delivery(void *data, const Eina_Value value EINA_UNUSED, const Eina_Future *dead_future EINA_UNUSED)
+{
+   Ecore_Evas *ee = data;
+   Ecore_Evas_Engine_Data_Win32 *edata = ee->engine.data;
+   Eina_Rw_Slice slice;
+   const char *mime_type = NULL;
+
+   EINA_SAFETY_ON_NULL_GOTO(edata->delivery, end);
+
+   for (unsigned int i = 0; i < eina_array_count(edata->clipboard.available_types); ++i)
+     {
+        mime_type = eina_array_data_get(edata->clipboard.available_types, i);
+        if (eina_str_has_prefix(mime_type, "text/"))
+          break;
+     }
+   if (mime_type)
+     {
+        edata->clipboard.delivery(ee, 0, ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER, mime_type, &slice);
+        EINA_SAFETY_ON_FALSE_GOTO(ecore_win32_clipboard_set((Ecore_Win32_Window *)ee->prop.window, slice.mem, slice.len, mime_type), end);
+     }
+   else
+     {
+        ERR("No compatible mime type found");
+     }
+
+end:
+   return EINA_VALUE_EMPTY;
+}
+
+static Eina_Bool
+_ecore_evas_win32_selection_claim(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Internal_Delivery delivery, Ecore_Evas_Internal_Cancel cancel)
+{
+   if (selection != ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+     return EINA_FALSE;
+
+   if (!delivery && !cancel)
+     {
+        ecore_win32_clipboard_clear((Ecore_Win32_Window *)ee->prop.window);
+        return EINA_TRUE;
+     }
+   else
+     {
+        Ecore_Evas_Engine_Data_Win32 *edata = ee->engine.data;
+
+        if (edata->clipboard.cancel)
+          {
+             edata->clipboard.cancel(ee, seat, selection);
+             eina_array_free(edata->clipboard.available_types);
+          }
+
+        edata->delivery = efl_loop_job(efl_main_loop_get());
+        eina_future_then(edata->delivery, _delivery, ee);
+        edata->clipboard.delivery = delivery;
+        edata->clipboard.cancel = cancel;
+        edata->clipboard.available_types = available_types;
+        return EINA_TRUE;
+     }
+}
+
+Eina_Future*
+_ecore_evas_win32_selection_request(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection, Eina_Array *acceptable_type)
+{
+   Eina_Future *future;
+   Eina_Promise *promise;
+   const char *mime_type = NULL;
+
+   if (selection != ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+     return eina_future_rejected(efl_loop_future_scheduler_get(efl_main_loop_get()), ecore_evas_no_selection);
+
+   promise = efl_loop_promise_new(efl_main_loop_get());
+   future = eina_future_new(promise);
+
+   for (unsigned int i = 0; i < eina_array_count(acceptable_type); ++i)
+     {
+        mime_type = eina_array_data_get(acceptable_type, i);
+        if (eina_str_has_prefix(mime_type, "text/"))
+          break;
+     }
+   if (!mime_type)
+     {
+        eina_promise_reject(promise, ecore_evas_no_matching_type);
+     }
+   else
+     {
+        size_t size;
+        void *data;
+        Eina_Content *content;
+        Eina_Rw_Slice slice;
+
+        data = ecore_win32_clipboard_get((Ecore_Win32_Window *)ee->prop.window, &size, mime_type);
+        if (eina_str_has_prefix(mime_type, "text/"))
+          {
+             //ensure that we always have a \0 at the end, there is no assertion that \0 is included here.
+             slice.len = size + 1;
+             slice.mem = eina_memdup(data, size, EINA_TRUE);
+          }
+        else
+          {
+             slice.len = size;
+             slice.mem = data;
+          }
+        content = eina_content_new(eina_rw_slice_slice_get(slice), mime_type);
+        if (!content) // construction can fail because of some validation reasons
+          eina_promise_reject(promise, ecore_evas_no_matching_type);
+        else
+          eina_promise_resolve(promise, eina_value_content_init(content));
+     }
+   return future;
+}
+
+static Eina_Bool
+_ecore_evas_win32_selection_has_owner(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection)
+{
+   return (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER);
+}
+
 static Ecore_Evas_Engine_Func _ecore_win32_engine_func =
 {
    _ecore_evas_win32_free,
-     NULL,
-     NULL,
-     NULL,
-     NULL,
-     _ecore_evas_win32_callback_delete_request_set,
-     NULL,
-     NULL,
-     NULL,
-     NULL,
-     NULL,
-     NULL,
-     NULL,
-     NULL,
-     NULL,
-     _ecore_evas_win32_move,
-     NULL,
-     _ecore_evas_win32_resize,
-     _ecore_evas_win32_move_resize,
-     _ecore_evas_win32_rotation_set,
-     _ecore_evas_win32_shaped_set,
-     _ecore_evas_win32_show,
-     _ecore_evas_win32_hide,
-     _ecore_evas_win32_raise,
-     _ecore_evas_win32_lower,
-     _ecore_evas_win32_activate,
-     _ecore_evas_win32_title_set,
-     NULL, /* _ecore_evas_x_name_class_set */
-     _ecore_evas_win32_size_min_set,
-     _ecore_evas_win32_size_max_set,
-     _ecore_evas_win32_size_base_set,
-     _ecore_evas_win32_size_step_set,
-     _ecore_evas_win32_object_cursor_set,
-     _ecore_evas_win32_object_cursor_unset,
-     NULL, /* _ecore_evas_x_layer_set */
-     _ecore_evas_win32_focus_set,
-     _ecore_evas_win32_iconified_set,
-     _ecore_evas_win32_borderless_set,
-     _ecore_evas_win32_override_set,
-     NULL,
-     _ecore_evas_win32_fullscreen_set,
-     NULL, /* _ecore_evas_x_avoid_damage_set */
-     NULL, /* _ecore_evas_x_withdrawn_set */
-     NULL, /* _ecore_evas_x_sticky_set */
-     NULL, /* _ecore_evas_x_ignore_events_set */
-     _ecore_evas_win32_alpha_set,
-     NULL, //transparent
-     NULL, // profiles_set
-     NULL, // profile_set
-
-     NULL,
-     NULL,
-     NULL,
-     NULL,
-     NULL,
-     NULL,
-
-     NULL, // render
-     _ecore_evas_win32_screen_geometry_get,
-     _ecore_evas_win32_screen_dpi_get,
-     NULL,
-     NULL,  // msg_send
-
-     NULL, // pointer_xy_get
-     NULL, // pointer_warp
-
-     NULL, // wm_rot_preferred_rotation_set
-     NULL, // wm_rot_available_rotations_set
-     NULL, // wm_rot_manual_rotation_done_set
-     NULL, // wm_rot_manual_rotation_done
-
-     NULL, // aux_hints_set
-
-     NULL, // fn_animator_register
-     NULL, // fn_animator_unregister
-
-     NULL, // fn_evas_changed
-     NULL, //fn_focus_device_set
-     NULL, //fn_callback_focus_device_in_set
-     NULL, //fn_callback_focus_device_out_set
-     NULL, //fn_callback_device_mouse_in_set
-     NULL, //fn_callback_device_mouse_out_set
-     NULL, //fn_pointer_device_xy_get
-     NULL, //fn_prepare
-     NULL, //fn_last_tick_get
-     //TIZEN_ONLY(20171218) : Add to free evas engine rsc before free evas
-     NULL, //fn_evas_engine_rsc_free
-
-     NULL, //fn_selection_claim
-     NULL, //fn_selection_has_owner
-     NULL, //fn_selection_request
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   _ecore_evas_win32_callback_delete_request_set,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   _ecore_evas_win32_move,
+   NULL,
+   _ecore_evas_win32_resize,
+   _ecore_evas_win32_move_resize,
+   _ecore_evas_win32_rotation_set,
+   _ecore_evas_win32_shaped_set,
+   _ecore_evas_win32_show,
+   _ecore_evas_win32_hide,
+   _ecore_evas_win32_raise,
+   _ecore_evas_win32_lower,
+   _ecore_evas_win32_activate,
+   _ecore_evas_win32_title_set,
+   NULL, /* _ecore_evas_x_name_class_set */
+   _ecore_evas_win32_size_min_set,
+   _ecore_evas_win32_size_max_set,
+   _ecore_evas_win32_size_base_set,
+   _ecore_evas_win32_size_step_set,
+   _ecore_evas_win32_object_cursor_set,
+   _ecore_evas_win32_object_cursor_unset,
+   NULL, /* _ecore_evas_x_layer_set */
+   _ecore_evas_win32_focus_set,
+   _ecore_evas_win32_iconified_set,
+   _ecore_evas_win32_borderless_set,
+   _ecore_evas_win32_override_set,
+   NULL,
+   _ecore_evas_win32_fullscreen_set,
+   NULL, /* _ecore_evas_x_avoid_damage_set */
+   NULL, /* _ecore_evas_x_withdrawn_set */
+   NULL, /* _ecore_evas_x_sticky_set */
+   NULL, /* _ecore_evas_x_ignore_events_set */
+   _ecore_evas_win32_alpha_set,
+   NULL, //transparent
+   NULL, // profiles_set
+   NULL, // profile_set
+
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+
+   NULL, // render
+   _ecore_evas_win32_screen_geometry_get,
+   _ecore_evas_win32_screen_dpi_get,
+   NULL,
+   NULL,  // msg_send
+
+   NULL, // pointer_xy_get
+   NULL, // pointer_warp
+
+   NULL, // wm_rot_preferred_rotation_set
+   NULL, // wm_rot_available_rotations_set
+   NULL, // wm_rot_manual_rotation_done_set
+   NULL, // wm_rot_manual_rotation_done
+
+   NULL, // aux_hints_set
+
+   NULL, // fn_animator_register
+   NULL, // fn_animator_unregister
+
+   NULL, // fn_evas_changed
+   NULL, //fn_focus_device_set
+   NULL, //fn_callback_focus_device_in_set
+   NULL, //fn_callback_focus_device_out_set
+   NULL, //fn_callback_device_mouse_in_set
+   NULL, //fn_callback_device_mouse_out_set
+   NULL, //fn_pointer_device_xy_get
+   NULL, //fn_prepare
+   NULL, //fn_last_tick_get
+   _ecore_evas_win32_selection_claim, //fn_selection_claim
+   _ecore_evas_win32_selection_has_owner, //fn_selection_has_owner
+   _ecore_evas_win32_selection_request, //fn_selection_request
+   NULL, //fn_dnd_start
+   NULL, //fn_dnd_stop
 };
 
 #endif /* BUILD_ECORE_EVAS_WIN32 */