summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2020-03-03 11:06:04 +0100
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2020-03-04 17:26:30 +0100
commit9abd2604fa9b7f5a2275eafdf749dc8fffa12fef (patch)
treeb665a78b592773d917b00eec4327e4c666bd0ebe
parent61075d45cc540549a8bfee4515b8f0817a9a95b5 (diff)
port cnp on Windows
Test Plan: Ctrl-c and Ctrl-Vworking Reviewers: raster, zmike Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D11439
-rw-r--r--src/lib/ecore_win32/Ecore_Win32.h47
-rw-r--r--src/lib/ecore_win32/ecore_win32_clipboard.c221
-rw-r--r--src/lib/ecore_win32/ecore_win32_event.c118
-rw-r--r--src/modules/ecore_evas/engines/win32/ecore_evas_win32.c305
4 files changed, 443 insertions, 248 deletions
diff --git a/src/lib/ecore_win32/Ecore_Win32.h b/src/lib/ecore_win32/Ecore_Win32.h
index 91274ba74a..722f0aa124 100644
--- a/src/lib/ecore_win32/Ecore_Win32.h
+++ b/src/lib/ecore_win32/Ecore_Win32.h
@@ -216,21 +216,6 @@ typedef enum
216} Ecore_Win32_DnD_State; 216} Ecore_Win32_DnD_State;
217 217
218/** 218/**
219 * @typedef Ecore_Win32_Selection
220 * Type of the selection.
221 *
222 * @since 1.16
223 */
224typedef enum
225{
226 ECORE_WIN32_SELECTION_PRIMARY,
227 ECORE_WIN32_SELECTION_SECONDARY,
228 ECORE_WIN32_SELECTION_DND,
229 ECORE_WIN32_SELECTION_CLIPBOARD,
230 ECORE_WIN32_SELECTION_OTHER
231} Ecore_Win32_Selection;
232
233/**
234 * @typedef Ecore_Win32_Window 219 * @typedef Ecore_Win32_Window
235 * Abstract type for a window. 220 * Abstract type for a window.
236 */ 221 */
@@ -326,7 +311,7 @@ typedef struct _Ecore_Win32_Event_Window_Delete_Request Ecore_Win32_Event_Window
326 * @typedef Ecore_Win32_Event_Selection_Clear 311 * @typedef Ecore_Win32_Event_Selection_Clear
327 * Event sent when the content of the clipboard has been removed. 312 * Event sent when the content of the clipboard has been removed.
328 * 313 *
329 * @since 1.16 314 * @since 1.24
330 */ 315 */
331typedef struct _Ecore_Win32_Event_Selection_Clear Ecore_Win32_Event_Selection_Clear; 316typedef struct _Ecore_Win32_Event_Selection_Clear Ecore_Win32_Event_Selection_Clear;
332 317
@@ -334,7 +319,7 @@ typedef struct _Ecore_Win32_Event_Selection_Clear Ecore_Win32_Event_Selection_Cl
334 * @typedef Ecore_Win32_Event_Selection_Notify 319 * @typedef Ecore_Win32_Event_Selection_Notify
335 * Event sent when the content of the clipboard has been added. 320 * Event sent when the content of the clipboard has been added.
336 * 321 *
337 * @since 1.16 322 * @since 1.24
338 */ 323 */
339typedef struct _Ecore_Win32_Event_Selection_Notify Ecore_Win32_Event_Selection_Notify; 324typedef struct _Ecore_Win32_Event_Selection_Notify Ecore_Win32_Event_Selection_Notify;
340 325
@@ -490,26 +475,26 @@ struct _Ecore_Win32_Event_Window_Delete_Request
490 * @struct _Ecore_Win32_Event_Selection_Clear 475 * @struct _Ecore_Win32_Event_Selection_Clear
491 * Event sent when the content of the clipboard has been removed. 476 * Event sent when the content of the clipboard has been removed.
492 * 477 *
493 * @since 1.16 478 * @since 1.24
494 */ 479 */
495struct _Ecore_Win32_Event_Selection_Clear 480struct _Ecore_Win32_Event_Selection_Clear
496{ 481{
497 Ecore_Win32_Window *window; /**< The window that received the event */ 482 Ecore_Win32_Window *window; /**< The window that received the event */
498 unsigned long timestamp; /**< The time the event occurred */ 483 unsigned long timestamp; /**< The time the event occurred */
499 Ecore_Win32_Selection selection; /**< The type of the selection */ 484 char *selection; /**< The type of the selection */
500}; 485};
501 486
502/** 487/**
503 * @struct _Ecore_Win32_Event_Selection_Notify 488 * @struct _Ecore_Win32_Event_Selection_Notify
504 * Event sent when the content of the clipboard has been added. 489 * Event sent when the content of the clipboard has been added.
505 * 490 *
506 * @since 1.16 491 * @since 1.24
507 */ 492 */
508struct _Ecore_Win32_Event_Selection_Notify 493struct _Ecore_Win32_Event_Selection_Notify
509{ 494{
510 Ecore_Win32_Window *window; /**< The window that received the event */ 495 Ecore_Win32_Window *window; /**< The window that received the event */
511 unsigned long timestamp; /**< The time the event occurred */ 496 unsigned long timestamp; /**< The time the event occurred */
512 Ecore_Win32_Selection selection; /**< The type of the selection */ 497 char *selection; /**< The type of the selection */
513 void *data; /**< The data of the selection */ 498 void *data; /**< The data of the selection */
514}; 499};
515 500
@@ -698,6 +683,7 @@ EAPI void ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window
698 * @param[in] window The window that owns the clipboard. 683 * @param[in] window The window that owns the clipboard.
699 * @param[in] data The data to set. 684 * @param[in] data The data to set.
700 * @param[in] size The size of the data. 685 * @param[in] size The size of the data.
686 * @param[in] mime_type The mime type describing the data in the clipboard.
701 * @return #EINA_TRUE on success, #EINA_FALSE otherwise. 687 * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
702 * 688 *
703 * This function sets @p data of size @p size in the clipboard owned by 689 * This function sets @p data of size @p size in the clipboard owned by
@@ -705,11 +691,12 @@ EAPI void ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window
705 * #EINA_FALSE otherwise. If @p window or @p data are @c NULL, or @p size 691 * #EINA_FALSE otherwise. If @p window or @p data are @c NULL, or @p size
706 * is less than or equal to 0, this function returns #EINA_FALSE. 692 * is less than or equal to 0, this function returns #EINA_FALSE.
707 * 693 *
708 * @since 1.16 694 * @since 1.24
709 */ 695 */
710EAPI Eina_Bool ecore_win32_clipboard_set(const Ecore_Win32_Window *window, 696EAPI Eina_Bool ecore_win32_clipboard_set(const Ecore_Win32_Window *window,
711 const void *data, 697 const void *data,
712 int size); 698 size_t size,
699 const char *mime_type);
713 700
714/** 701/**
715 * @brief Get data from the clipboard. 702 * @brief Get data from the clipboard.
@@ -717,6 +704,7 @@ EAPI Eina_Bool ecore_win32_clipboard_set(const Ecore_Win32_Window *window,
717 * @param[in] window The window that owns the clipboard. 704 * @param[in] window The window that owns the clipboard.
718 * @param[out] data The retrieved data. 705 * @param[out] data The retrieved data.
719 * @param[out] size The size of the data. 706 * @param[out] size The size of the data.
707 * @param[in] mime_type The mime type describing the data in the clipboard.
720 * @return #EINA_TRUE on success, #EINA_FALSE otherwise. 708 * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
721 * 709 *
722 * This function gets @p data of size @p size from the clipboard owned by 710 * This function gets @p data of size @p size from the clipboard owned by
@@ -724,25 +712,24 @@ EAPI Eina_Bool ecore_win32_clipboard_set(const Ecore_Win32_Window *window,
724 * #EINA_FALSE otherwise. If @p window is @c NULL, this function returns 712 * #EINA_FALSE otherwise. If @p window is @c NULL, this function returns
725 * #EINA_FALSE. @p data and @p size must be valid buffers. 713 * #EINA_FALSE. @p data and @p size must be valid buffers.
726 * 714 *
727 * @since 1.16 715 * @since 1.24
728 */ 716 */
729EAPI Eina_Bool ecore_win32_clipboard_get(const Ecore_Win32_Window *window, 717EAPI void * ecore_win32_clipboard_get(const Ecore_Win32_Window *window,
730 void **data, 718 size_t *size,
731 int *size); 719 const char *mime_type);
732 720
733/** 721/**
734 * @brief Cleat the clipboard. 722 * @brief Cleat the clipboard.
735 * 723 *
736 * @param[in] window The window that owns the clipboard. 724 * @param[in] window The window that owns the clipboard.
737 * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
738 * 725 *
739 * This function clears the clipboard owned by @p window. This 726 * This function clears the clipboard owned by @p window. This
740 * function returns #EINA_TRUE on success, and #EINA_FALSE otherwise. 727 * function returns #EINA_TRUE on success, and #EINA_FALSE otherwise.
741 * If @p window is @c NULL, this function returns #EINA_FALSE. 728 * If @p window is @c NULL, this function returns #EINA_FALSE.
742 * 729 *
743 * @since 1.16 730 * @since 1.24
744 */ 731 */
745EAPI Eina_Bool ecore_win32_clipboard_clear(const Ecore_Win32_Window *window); 732EAPI void ecore_win32_clipboard_clear(const Ecore_Win32_Window *window);
746 733
747/** 734/**
748 * @typedef Ecore_Win32_Monitor 735 * @typedef Ecore_Win32_Monitor
diff --git a/src/lib/ecore_win32/ecore_win32_clipboard.c b/src/lib/ecore_win32/ecore_win32_clipboard.c
index a20be680c0..73a0cf1506 100644
--- a/src/lib/ecore_win32/ecore_win32_clipboard.c
+++ b/src/lib/ecore_win32/ecore_win32_clipboard.c
@@ -6,6 +6,7 @@
6#include <windows.h> 6#include <windows.h>
7#undef WIN32_LEAN_AND_MEAN 7#undef WIN32_LEAN_AND_MEAN
8 8
9#include <evil_private.h> /* utf-8 and utf-16 conversion */
9#include <Eina.h> 10#include <Eina.h>
10 11
11#include "Ecore_Win32.h" 12#include "Ecore_Win32.h"
@@ -39,10 +40,12 @@
39EAPI Eina_Bool 40EAPI Eina_Bool
40ecore_win32_clipboard_set(const Ecore_Win32_Window *window, 41ecore_win32_clipboard_set(const Ecore_Win32_Window *window,
41 const void *data, 42 const void *data,
42 int size) 43 size_t size,
44 const char *mime_type)
43{ 45{
44 HGLOBAL global; 46 HGLOBAL global;
45 char *d; 47 char *d;
48 Eina_Bool res = EINA_FALSE;
46 49
47 /* 50 /*
48 * See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms649016%28v=vs.85%29.aspx#_win32_Copying_Information_to_the_Clipboard 51 * See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms649016%28v=vs.85%29.aspx#_win32_Copying_Information_to_the_Clipboard
@@ -54,47 +57,78 @@ ecore_win32_clipboard_set(const Ecore_Win32_Window *window,
54 57
55 INF("setting data to the clipboard"); 58 INF("setting data to the clipboard");
56 59
57 if (!window || !data || (size <= 0)) 60 if (!eina_str_has_prefix(mime_type, "text/"))
58 return EINA_FALSE; 61 {
62 ERR("Mimetype %s is not handled yet", mime_type);
63 return EINA_FALSE;
64 }
59 65
60 if (!OpenClipboard(window->window)) 66 if (!window || !data || (size <= 0) || !OpenClipboard(window->window))
61 return EINA_FALSE; 67 return EINA_FALSE;
62 68
63 if (!EmptyClipboard()) 69 if (!EmptyClipboard())
64 goto close_clipboard; 70 goto close_clipboard;
65 71
66 global = GlobalAlloc(GMEM_MOVEABLE, size + 1); 72 if (eina_str_has_prefix(mime_type, "text/"))
67 if (!global) 73 {
68 goto close_clipboard; 74 wchar_t *text16;
69 75 size_t size16;
70 d = (char *)GlobalLock(global); 76
71 if (!d) 77 /* CF_TEXT (UTF-8) */
72 goto unlock_global; 78
73 79 global = GlobalAlloc(GMEM_MOVEABLE, size);
74 memcpy(d, data, size); 80 if (global)
75 d[size] = '\0'; 81 {
76 GlobalUnlock(global); 82 d = (char *)GlobalLock(global);
77 SetClipboardData(CF_TEXT, global); 83 if (d)
78 CloseClipboard(); 84 {
85 memcpy(d, data, size);
86 GlobalUnlock(global);
87 SetClipboardData(CF_TEXT, global);
88 res = EINA_TRUE;
89 }
90 GlobalUnlock(global);
91 }
92
93 /* CF_UNICODETEXT (UTF-16) */
94
95 text16 = evil_utf8_to_utf16(data);
96 if (text16)
97 {
98 size16 = (wcslen(text16) + 1) * sizeof(wchar_t);
99
100 global = GlobalAlloc(GMEM_MOVEABLE, size16);
101 if (global)
102 {
103 d = (char *)GlobalLock(global);
104 if (d)
105 {
106 memcpy(d, text16, size16);
107 SetClipboardData(CF_UNICODETEXT, global);
108 free(text16);
109 res = EINA_TRUE;
110 }
111 GlobalUnlock(global);
112 }
113
114 free(text16);
115 }
116 }
79 117
80 return EINA_TRUE;
81
82 unlock_global:
83 GlobalUnlock(global);
84 close_clipboard: 118 close_clipboard:
85 CloseClipboard(); 119 CloseClipboard();
86 120
87 return EINA_FALSE; 121 return res;
88} 122}
89 123
90EAPI Eina_Bool 124EAPI void *
91ecore_win32_clipboard_get(const Ecore_Win32_Window *window, 125ecore_win32_clipboard_get(const Ecore_Win32_Window *window,
92 void **data, 126 size_t *size,
93 int *size) 127 const char *mime_type)
94{ 128{
95 HGLOBAL global; 129 HGLOBAL global;
130 void *data;
96 void *d; 131 void *d;
97 void *p;
98 132
99 /* 133 /*
100 * See https://msdn.microsoft.com/en-us/library/windows/desktop/ms649016%28v=vs.85%29.aspx#_win32_Pasting_Information_from_the_Clipboard 134 * 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,93 @@ ecore_win32_clipboard_get(const Ecore_Win32_Window *window,
107 141
108 INF("getting data from the clipboard"); 142 INF("getting data from the clipboard");
109 143
110 if (!window) 144 *size = 0;
111 return EINA_FALSE;
112
113 if (!IsClipboardFormatAvailable(CF_TEXT))
114 return EINA_FALSE;
115
116 if (!OpenClipboard(window->window))
117 goto set_val;
118
119 /* { */
120 /* UINT fmt = 0; */
121
122 /* while (1) */
123 /* { */
124 /* fmt = EnumClipboardFormats(fmt); */
125 /* printf(" $ Format : %x\n", fmt); */
126 /* if (!fmt) */
127 /* break; */
128 /* } */
129 /* } */
130
131 global = GetClipboardData(CF_TEXT);
132 if (!global)
133 goto close_clipboard;
134
135 d = GlobalLock(global);
136 if (!d)
137 goto unlock_global;
138
139 *size = strlen(d);
140 p = malloc(*size);
141 if (!p)
142 goto unlock_global;
143 145
144 memcpy(p, d, *size); 146 if (!eina_str_has_prefix(mime_type, "text/"))
145 *data = p; 147 {
146 GlobalUnlock(global); 148 ERR("Mimetype %s is not handled yet", mime_type);
147 CloseClipboard(); 149 return NULL;
150 }
151
152 if (!window || !OpenClipboard(window->window))
153 return NULL;
154
155#if 0
156 {
157 UINT fmt = 0;
158
159 while (1)
160 {
161 fmt = EnumClipboardFormats(fmt);
162 fprintf(stderr, " $ Format : %x\n", fmt);
163 fflush(stderr);
164 if (!fmt)
165 break;
166 }
167 }
168#endif
148 169
149 return EINA_TRUE; 170 if (eina_str_has_prefix(mime_type, "text/"))
171 {
172 /* first check if UTF-16 text is available */
173 global = GetClipboardData(CF_UNICODETEXT);
174 if (global)
175 {
176 d = GlobalLock(global);
177 if (d)
178 {
179 data = evil_utf16_to_utf8(d);
180 if (data)
181 {
182 *size = strlen(data);
183 GlobalUnlock(global);
184 CloseClipboard();
185 return data;
186 }
187 }
188 /* otherwise, we unlock global and try CF_TEXT (UTF-8/ANSI) */
189 GlobalUnlock(global);
190 }
191
192 /* secondly check if UTF-8/ANSI text is available */
193 global = GetClipboardData(CF_TEXT);
194 if (global)
195 {
196 d = GlobalLock(global);
197 if (d)
198 {
199 *size = strlen(d) + 1;
200 data = malloc(*size);
201 if (data)
202 {
203 memcpy(data, d, *size);
204 GlobalUnlock(global);
205 CloseClipboard();
206 return data;
207 }
208 else
209 *size = 0;
210 }
211
212 GlobalUnlock(global);
213 }
214 }
150 215
151 unlock_global:
152 GlobalUnlock(global);
153 close_clipboard:
154 CloseClipboard(); 216 CloseClipboard();
155 set_val:
156 *data = NULL;
157 *size = 0;
158 217
159 return EINA_FALSE; 218 return NULL;
160} 219}
161 220
162EAPI Eina_Bool 221EAPI void
163ecore_win32_clipboard_clear(const Ecore_Win32_Window *window) 222ecore_win32_clipboard_clear(const Ecore_Win32_Window *window)
164{ 223{
165 INF("clearing the clipboard"); 224 INF("clearing the clipboard");
166 225
167 if (!window) 226 if (!window || !OpenClipboard(window->window))
168 return EINA_FALSE; 227 return;
169
170 if (!OpenClipboard(window->window))
171 return EINA_FALSE;
172 228
173 if (!EmptyClipboard()) 229 EmptyClipboard();
174 goto close_clipboard;
175
176 CloseClipboard();
177
178 return EINA_TRUE;
179
180 close_clipboard:
181 CloseClipboard(); 230 CloseClipboard();
182
183 return EINA_FALSE;
184} 231}
185 232
186/** 233/**
diff --git a/src/lib/ecore_win32/ecore_win32_event.c b/src/lib/ecore_win32/ecore_win32_event.c
index 0c232e7bc3..078ea06ec5 100644
--- a/src/lib/ecore_win32/ecore_win32_event.c
+++ b/src/lib/ecore_win32/ecore_win32_event.c
@@ -1958,66 +1958,104 @@ _ecore_win32_event_handle_selection_notify(Ecore_Win32_Callback_Data *msg)
1958{ 1958{
1959 Ecore_Win32_Event_Selection_Notify *e; 1959 Ecore_Win32_Event_Selection_Notify *e;
1960 HGLOBAL global; 1960 HGLOBAL global;
1961 char *str;
1962 1961
1963 INF("selection_notify"); 1962 INF("selection_notify");
1964 1963
1964 e = calloc(1, sizeof(Ecore_Win32_Event_Selection_Notify));
1965 if (!e) return;
1966
1967 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
1968 e->timestamp = _ecore_win32_event_last_time;
1969
1965 /* 1970 /*
1966 * we have text data in clipboard but no data before, 1971 * we have data in clipboard but no data before,
1967 * so text data has just been added 1972 * so data has just been added
1968 */ 1973 */
1969 if (IsClipboardFormatAvailable(CF_TEXT) && !_ecore_win32_clipboard_has_data) 1974 if (!_ecore_win32_clipboard_has_data)
1970 { 1975 {
1971 e = calloc(1, sizeof(Ecore_Win32_Event_Selection_Notify)); 1976 /* if case someone else is owning the clipboard, we can't do anything */
1972 if (!e) return;
1973
1974 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA);
1975 e->timestamp = _ecore_win32_event_last_time;
1976 e->selection = ECORE_WIN32_SELECTION_CLIPBOARD;
1977
1978 if (!OpenClipboard(msg->window)) 1977 if (!OpenClipboard(msg->window))
1979 goto free_e; 1978 {
1980 1979 free(e);
1981 global = GetClipboardData(CF_TEXT); 1980 return;
1982 if (!global) 1981 }
1983 goto close_clipboard;
1984 1982
1985 str = GlobalLock(global); 1983 if (IsClipboardFormatAvailable(CF_UNICODETEXT))
1986 if (str)
1987 { 1984 {
1988 e->data = strdup(str); 1985 global = GetClipboardData(CF_UNICODETEXT);
1989 GlobalUnlock(global); 1986 if (global)
1987 {
1988 e->selection = strdup("text/plain;charset=utf-8");
1989 if (e->selection)
1990 {
1991 wchar_t *d;
1992
1993 d = (wchar_t *)GlobalLock(global);
1994 if (d)
1995 e->data = evil_utf16_to_utf8(d);
1996
1997 GlobalUnlock(global);
1998 if (e->data)
1999 {
2000 ecore_event_add(ECORE_WIN32_EVENT_SELECTION_NOTIFY, e, NULL, NULL);
2001 _ecore_win32_clipboard_has_data = EINA_TRUE;
2002 CloseClipboard();
2003 return;
2004 }
2005 }
2006 }
1990 } 2007 }
1991 2008
2009 if (IsClipboardFormatAvailable(CF_TEXT))
2010 {
2011 global = GetClipboardData(CF_TEXT);
2012 if (global)
2013 {
2014 e->selection = strdup("text/plain;charset=utf-8");
2015 if (e->selection)
2016 {
2017 char *d;
2018
2019 d = (char *)GlobalLock(global);
2020 if (d)
2021 e->data = strdup(d);
2022
2023 GlobalUnlock(global);
2024 if (e->data)
2025 {
2026 ecore_event_add(ECORE_WIN32_EVENT_SELECTION_NOTIFY, e, NULL, NULL);
2027
2028 _ecore_win32_clipboard_has_data = EINA_TRUE;
2029 CloseClipboard();
2030 return;
2031 }
2032 }
2033 }
2034 }
2035 free(e->data);
2036 free(e->selection);
2037 free(e);
1992 CloseClipboard(); 2038 CloseClipboard();
1993
1994 ecore_event_add(ECORE_WIN32_EVENT_SELECTION_NOTIFY, e, NULL, NULL);
1995
1996 _ecore_win32_clipboard_has_data = EINA_TRUE;
1997 } 2039 }
1998 2040
1999 /* 2041 /*
2000 * we have no more text data in clipboard and data before, 2042 * we have no more text data in clipboard and data before,
2001 * so text data has just been removed 2043 * so text data has just been removed
2002 */ 2044 */
2003 if (!IsClipboardFormatAvailable(CF_TEXT) && _ecore_win32_clipboard_has_data) 2045 if (_ecore_win32_clipboard_has_data)
2004 { 2046 {
2005 e = calloc(1, sizeof(Ecore_Win32_Event_Selection_Clear)); 2047 if (!IsClipboardFormatAvailable(CF_UNICODETEXT) ||
2006 if (!e) return; 2048 !IsClipboardFormatAvailable(CF_TEXT))
2007 2049 {
2008 e->window = (void *)GetWindowLongPtr(msg->window, GWLP_USERDATA); 2050 e->selection = strdup("text/plain;charset=utf-8");
2009 e->timestamp = _ecore_win32_event_last_time; 2051 if (e->selection)
2010 e->selection = ECORE_WIN32_SELECTION_CLIPBOARD; 2052 {
2011 2053 ecore_event_add(ECORE_WIN32_EVENT_SELECTION_CLEAR, e, NULL, NULL);
2012 ecore_event_add(ECORE_WIN32_EVENT_SELECTION_CLEAR, e, NULL, NULL); 2054 _ecore_win32_clipboard_has_data = EINA_FALSE;
2013 2055 return;
2014 _ecore_win32_clipboard_has_data = EINA_FALSE; 2056 }
2057 }
2015 } 2058 }
2016 2059
2017 return;
2018
2019 close_clipboard:
2020 CloseClipboard();
2021 free_e:
2022 free(e); 2060 free(e);
2023} 2061}
diff --git a/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c b/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c
index 6198ed4bac..d0686c535c 100644
--- a/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c
+++ b/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c
@@ -62,11 +62,15 @@ static const int interface_win32_version = 1;
62 62
63typedef struct _Ecore_Evas_Engine_Data_Win32 Ecore_Evas_Engine_Data_Win32; 63typedef struct _Ecore_Evas_Engine_Data_Win32 Ecore_Evas_Engine_Data_Win32;
64 64
65struct _Ecore_Evas_Engine_Data_Win32 { 65struct _Ecore_Evas_Engine_Data_Win32
66{
66 Ecore_Win32_Window *parent; 67 Ecore_Win32_Window *parent;
67 struct { 68 Ecore_Evas_Selection_Callbacks clipboard;
68 unsigned char region : 1; 69 Eina_Future *delivery;
69 unsigned char fullscreen : 1; 70 struct
71 {
72 unsigned char region : 1;
73 unsigned char fullscreen : 1;
70 } state; 74 } state;
71}; 75};
72 76
@@ -1197,96 +1201,215 @@ _ecore_evas_win32_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi)
1197 *ydpi = y_dpi; 1201 *ydpi = y_dpi;
1198} 1202}
1199 1203
1204static Eina_Value
1205_delivery(void *data, const Eina_Value value EINA_UNUSED, const Eina_Future *dead_future EINA_UNUSED)
1206{
1207 Ecore_Evas *ee = data;
1208 Ecore_Evas_Engine_Data_Win32 *edata = ee->engine.data;
1209 Eina_Rw_Slice slice;
1210 const char *mime_type = NULL;
1211
1212 EINA_SAFETY_ON_NULL_GOTO(edata->delivery, end);
1213
1214 for (unsigned int i = 0; i < eina_array_count(edata->clipboard.available_types); ++i)
1215 {
1216 mime_type = eina_array_data_get(edata->clipboard.available_types, i);
1217 if (eina_str_has_prefix(mime_type, "text/"))
1218 break;
1219 }
1220 if (mime_type)
1221 {
1222 edata->clipboard.delivery(ee, 0, ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER, mime_type, &slice);
1223 EINA_SAFETY_ON_FALSE_GOTO(ecore_win32_clipboard_set((Ecore_Win32_Window *)ee->prop.window, slice.mem, slice.len, mime_type), end);
1224 }
1225 else
1226 {
1227 ERR("No compatible mime type found");
1228 }
1229
1230end:
1231 return EINA_VALUE_EMPTY;
1232}
1233
1234static Eina_Bool
1235_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)
1236{
1237 if (selection != ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
1238 return EINA_FALSE;
1239
1240 if (!delivery && !cancel)
1241 {
1242 ecore_win32_clipboard_clear((Ecore_Win32_Window *)ee->prop.window);
1243 return EINA_TRUE;
1244 }
1245 else
1246 {
1247 Ecore_Evas_Engine_Data_Win32 *edata = ee->engine.data;
1248
1249 if (edata->clipboard.cancel)
1250 {
1251 edata->clipboard.cancel(ee, seat, selection);
1252 eina_array_free(edata->clipboard.available_types);
1253 }
1254
1255 edata->delivery = efl_loop_job(efl_main_loop_get());
1256 eina_future_then(edata->delivery, _delivery, ee);
1257 edata->clipboard.delivery = delivery;
1258 edata->clipboard.cancel = cancel;
1259 edata->clipboard.available_types = available_types;
1260 return EINA_TRUE;
1261 }
1262}
1263
1264Eina_Future*
1265_ecore_evas_win32_selection_request(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection, Eina_Array *acceptable_type)
1266{
1267 Eina_Future *future;
1268 Eina_Promise *promise;
1269 const char *mime_type = NULL;
1270
1271 if (selection != ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
1272 return eina_future_rejected(efl_loop_future_scheduler_get(efl_main_loop_get()), ecore_evas_no_selection);
1273
1274 promise = efl_loop_promise_new(efl_main_loop_get());
1275 future = eina_future_new(promise);
1276
1277 for (unsigned int i = 0; i < eina_array_count(acceptable_type); ++i)
1278 {
1279 mime_type = eina_array_data_get(acceptable_type, i);
1280 if (eina_str_has_prefix(mime_type, "text/"))
1281 break;
1282 }
1283 if (!mime_type)
1284 {
1285 eina_promise_reject(promise, ecore_evas_no_matching_type);
1286 }
1287 else
1288 {
1289 size_t size;
1290 void *data;
1291 Eina_Content *content;
1292 Eina_Rw_Slice slice;
1293
1294 data = ecore_win32_clipboard_get((Ecore_Win32_Window *)ee->prop.window, &size, mime_type);
1295 if (eina_str_has_prefix(mime_type, "text/"))
1296 {
1297 //ensure that we always have a \0 at the end, there is no assertion that \0 is included here.
1298 slice.len = size + 1;
1299 slice.mem = eina_memdup(data, size, EINA_TRUE);
1300 }
1301 else
1302 {
1303 slice.len = size;
1304 slice.mem = data;
1305 }
1306 content = eina_content_new(eina_rw_slice_slice_get(slice), mime_type);
1307 if (!content) // construction can fail because of some validation reasons
1308 eina_promise_reject(promise, ecore_evas_no_matching_type);
1309 else
1310 eina_promise_resolve(promise, eina_value_content_init(content));
1311 }
1312 return future;
1313}
1314
1315static Eina_Bool
1316_ecore_evas_win32_selection_has_owner(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection)
1317{
1318 return (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER);
1319}
1320
1200static Ecore_Evas_Engine_Func _ecore_win32_engine_func = 1321static Ecore_Evas_Engine_Func _ecore_win32_engine_func =
1201{ 1322{
1202 _ecore_evas_win32_free, 1323 _ecore_evas_win32_free,
1203 NULL, 1324 NULL,
1204 NULL, 1325 NULL,
1205 NULL, 1326 NULL,
1206 NULL, 1327 NULL,
1207 _ecore_evas_win32_callback_delete_request_set, 1328 _ecore_evas_win32_callback_delete_request_set,
1208 NULL, 1329 NULL,
1209 NULL, 1330 NULL,
1210 NULL, 1331 NULL,
1211 NULL, 1332 NULL,
1212 NULL, 1333 NULL,
1213 NULL, 1334 NULL,
1214 NULL, 1335 NULL,
1215 NULL, 1336 NULL,
1216 NULL, 1337 NULL,
1217 _ecore_evas_win32_move, 1338 _ecore_evas_win32_move,
1218 NULL, 1339 NULL,
1219 _ecore_evas_win32_resize, 1340 _ecore_evas_win32_resize,
1220 _ecore_evas_win32_move_resize, 1341 _ecore_evas_win32_move_resize,
1221 _ecore_evas_win32_rotation_set, 1342 _ecore_evas_win32_rotation_set,
1222 _ecore_evas_win32_shaped_set, 1343 _ecore_evas_win32_shaped_set,
1223 _ecore_evas_win32_show, 1344 _ecore_evas_win32_show,
1224 _ecore_evas_win32_hide, 1345 _ecore_evas_win32_hide,
1225 _ecore_evas_win32_raise, 1346 _ecore_evas_win32_raise,
1226 _ecore_evas_win32_lower, 1347 _ecore_evas_win32_lower,
1227 _ecore_evas_win32_activate, 1348 _ecore_evas_win32_activate,
1228 _ecore_evas_win32_title_set, 1349 _ecore_evas_win32_title_set,
1229 NULL, /* _ecore_evas_x_name_class_set */ 1350 NULL, /* _ecore_evas_x_name_class_set */
1230 _ecore_evas_win32_size_min_set, 1351 _ecore_evas_win32_size_min_set,
1231 _ecore_evas_win32_size_max_set, 1352 _ecore_evas_win32_size_max_set,
1232 _ecore_evas_win32_size_base_set, 1353 _ecore_evas_win32_size_base_set,
1233 _ecore_evas_win32_size_step_set, 1354 _ecore_evas_win32_size_step_set,
1234 _ecore_evas_win32_object_cursor_set, 1355 _ecore_evas_win32_object_cursor_set,
1235 _ecore_evas_win32_object_cursor_unset, 1356 _ecore_evas_win32_object_cursor_unset,
1236 NULL, /* _ecore_evas_x_layer_set */ 1357 NULL, /* _ecore_evas_x_layer_set */
1237 _ecore_evas_win32_focus_set, 1358 _ecore_evas_win32_focus_set,
1238 _ecore_evas_win32_iconified_set, 1359 _ecore_evas_win32_iconified_set,
1239 _ecore_evas_win32_borderless_set, 1360 _ecore_evas_win32_borderless_set,
1240 _ecore_evas_win32_override_set, 1361 _ecore_evas_win32_override_set,
1241 NULL, 1362 NULL,
1242 _ecore_evas_win32_fullscreen_set, 1363 _ecore_evas_win32_fullscreen_set,
1243 NULL, /* _ecore_evas_x_avoid_damage_set */ 1364 NULL, /* _ecore_evas_x_avoid_damage_set */
1244 NULL, /* _ecore_evas_x_withdrawn_set */ 1365 NULL, /* _ecore_evas_x_withdrawn_set */
1245 NULL, /* _ecore_evas_x_sticky_set */ 1366 NULL, /* _ecore_evas_x_sticky_set */
1246 NULL, /* _ecore_evas_x_ignore_events_set */ 1367 NULL, /* _ecore_evas_x_ignore_events_set */
1247 _ecore_evas_win32_alpha_set, 1368 _ecore_evas_win32_alpha_set,
1248 NULL, //transparent 1369 NULL, //transparent
1249 NULL, // profiles_set 1370 NULL, // profiles_set
1250 NULL, // profile_set 1371 NULL, // profile_set
1251 1372
1252 NULL, 1373 NULL,
1253 NULL, 1374 NULL,
1254 NULL, 1375 NULL,
1255 NULL, 1376 NULL,
1256 NULL, 1377 NULL,
1257 NULL, 1378 NULL,
1258 1379
1259 NULL, // render 1380 NULL, // render
1260 _ecore_evas_win32_screen_geometry_get, 1381 _ecore_evas_win32_screen_geometry_get,
1261 _ecore_evas_win32_screen_dpi_get, 1382 _ecore_evas_win32_screen_dpi_get,
1262 NULL, 1383 NULL,
1263 NULL, // msg_send 1384 NULL, // msg_send
1264 1385
1265 NULL, // pointer_xy_get 1386 NULL, // pointer_xy_get
1266 NULL, // pointer_warp 1387 NULL, // pointer_warp
1267 1388
1268 NULL, // wm_rot_preferred_rotation_set 1389 NULL, // wm_rot_preferred_rotation_set
1269 NULL, // wm_rot_available_rotations_set 1390 NULL, // wm_rot_available_rotations_set
1270 NULL, // wm_rot_manual_rotation_done_set 1391 NULL, // wm_rot_manual_rotation_done_set
1271 NULL, // wm_rot_manual_rotation_done 1392 NULL, // wm_rot_manual_rotation_done
1272 1393
1273 NULL, // aux_hints_set 1394 NULL, // aux_hints_set
1274 1395
1275 NULL, // fn_animator_register 1396 NULL, // fn_animator_register
1276 NULL, // fn_animator_unregister 1397 NULL, // fn_animator_unregister
1277 1398
1278 NULL, // fn_evas_changed 1399 NULL, // fn_evas_changed
1279 NULL, //fn_focus_device_set 1400 NULL, //fn_focus_device_set
1280 NULL, //fn_callback_focus_device_in_set 1401 NULL, //fn_callback_focus_device_in_set
1281 NULL, //fn_callback_focus_device_out_set 1402 NULL, //fn_callback_focus_device_out_set
1282 NULL, //fn_callback_device_mouse_in_set 1403 NULL, //fn_callback_device_mouse_in_set
1283 NULL, //fn_callback_device_mouse_out_set 1404 NULL, //fn_callback_device_mouse_out_set
1284 NULL, //fn_pointer_device_xy_get 1405 NULL, //fn_pointer_device_xy_get
1285 NULL, //fn_prepare 1406 NULL, //fn_prepare
1286 NULL, //fn_last_tick_get 1407 NULL, //fn_last_tick_get
1287 NULL, //fn_selection_claim 1408 _ecore_evas_win32_selection_claim, //fn_selection_claim
1288 NULL, //fn_selection_has_owner 1409 _ecore_evas_win32_selection_has_owner, //fn_selection_has_owner
1289 NULL, //fn_selection_request 1410 _ecore_evas_win32_selection_request, //fn_selection_request
1411 NULL, //fn_dnd_start
1412 NULL, //fn_dnd_stop
1290}; 1413};
1291 1414
1292#endif /* BUILD_ECORE_EVAS_WIN32 */ 1415#endif /* BUILD_ECORE_EVAS_WIN32 */