summaryrefslogtreecommitdiff
path: root/src/lib/ecore_wayland/ecore_wl_dnd.c
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2013-05-28 11:44:53 +0100
committerChris Michael <cp.michael@samsung.com>2013-05-28 11:48:51 +0100
commit6d0cc0d9bff55194a102f27f0472a9872715c183 (patch)
tree16f8eae703c1a1a91d413522a15339042f794c6e /src/lib/ecore_wayland/ecore_wl_dnd.c
parentb7ac7bdfd95c7cc1b9415a29835ae35dfa28a340 (diff)
Deprecate old dnd functions (useless, improperly named, etc)
Add shiny new Drag-N-Drop code ;) Signed-off-by: Chris Michael <cp.michael@samsung.com>
Diffstat (limited to 'src/lib/ecore_wayland/ecore_wl_dnd.c')
-rw-r--r--src/lib/ecore_wayland/ecore_wl_dnd.c691
1 files changed, 469 insertions, 222 deletions
diff --git a/src/lib/ecore_wayland/ecore_wl_dnd.c b/src/lib/ecore_wayland/ecore_wl_dnd.c
index 403e3b9f6b..444e1e10a5 100644
--- a/src/lib/ecore_wayland/ecore_wl_dnd.c
+++ b/src/lib/ecore_wayland/ecore_wl_dnd.c
@@ -6,6 +6,7 @@
6#include <sys/epoll.h> 6#include <sys/epoll.h>
7#include "ecore_wl_private.h" 7#include "ecore_wl_private.h"
8 8
9/* local structures */
9struct _dnd_task 10struct _dnd_task
10{ 11{
11 void *data; 12 void *data;
@@ -19,273 +20,486 @@ struct _dnd_read_ctx
19}; 20};
20 21
21/* local function prototypes */ 22/* local function prototypes */
22static void _ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, const char *type); 23static void _ecore_wl_dnd_selection_data_receive(Ecore_Wl_Dnd_Source *source, const char *type);
23static void _ecore_wl_dnd_cb_enter_free(void *data EINA_UNUSED, void *event); 24static Eina_Bool _ecore_wl_dnd_selection_data_read(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED);
25static void _ecore_wl_dnd_selection_data_ready_cb_free(void *data EINA_UNUSED, void *event);
26static Eina_Bool _ecore_wl_dnd_selection_cb_idle(void *data);
24 27
25static void _ecore_wl_dnd_data_source_target(void *data, struct wl_data_source *source, const char *mime_type); 28static void _ecore_wl_dnd_source_cb_target(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type EINA_UNUSED);
26static void _ecore_wl_dnd_data_source_send(void *data, struct wl_data_source *source, const char *mime_type, int32_t fd); 29static void _ecore_wl_dnd_source_cb_send(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type, int32_t fd);
27static void _ecore_wl_dnd_data_source_cancelled(void *data, struct wl_data_source *source); 30static void _ecore_wl_dnd_source_cb_send_free(void *data EINA_UNUSED, void *event);
28static void _ecore_wl_dnd_source_receive_data(Ecore_Wl_Dnd_Source *source, const char *type); 31static void _ecore_wl_dnd_source_cb_cancelled(void *data EINA_UNUSED, struct wl_data_source *source);
29 32
30/* wayland listeners */ 33static void _ecore_wl_dnd_offer_cb_offer(void *data, struct wl_data_offer *data_offer EINA_UNUSED, const char *type);
31static const struct wl_data_offer_listener _ecore_wl_data_offer_listener = 34
35/* local wayland interfaces */
36static const struct wl_data_source_listener
37_ecore_wl_dnd_source_listener =
32{ 38{
33 _ecore_wl_dnd_offer, 39 _ecore_wl_dnd_source_cb_target,
40 _ecore_wl_dnd_source_cb_send,
41 _ecore_wl_dnd_source_cb_cancelled
34}; 42};
35 43
36static const struct wl_data_source_listener _ecore_wl_data_source_listener = 44static const struct wl_data_offer_listener
45_ecore_wl_dnd_offer_listener =
37{ 46{
38 _ecore_wl_dnd_data_source_target, 47 _ecore_wl_dnd_offer_cb_offer
39 _ecore_wl_dnd_data_source_send,
40 _ecore_wl_dnd_data_source_cancelled
41}; 48};
42 49
43extern Ecore_Wl_Dnd *glb_dnd; 50/**
51 * @deprecated use ecore_wl_dnd_selection_set
52 * @since 1.7
53*/
54EINA_DEPRECATED EAPI Eina_Bool
55ecore_wl_dnd_set_selection(Ecore_Wl_Dnd *dnd, const char **types_offered)
56{
57 return ecore_wl_dnd_selection_set(dnd->input, types_offered);
58}
59
60/**
61 * @deprecated use ecore_wl_dnd_selection_get
62 * @since 1.7
63*/
64EINA_DEPRECATED EAPI Eina_Bool
65ecore_wl_dnd_get_selection(Ecore_Wl_Dnd *dnd, const char *type)
66{
67 return ecore_wl_dnd_selection_get(dnd->input, type);
68}
44 69
45EAPI Ecore_Wl_Dnd * 70/**
46ecore_wl_dnd_get() 71 * @deprecated Do Not Use
72 * @since 1.7
73 */
74EINA_DEPRECATED EAPI Ecore_Wl_Dnd *
75ecore_wl_dnd_get(void)
47{ 76{
48 return glb_dnd; 77 return NULL;
49} 78}
50 79
51EAPI Eina_Bool 80/**
81 * @deprecated use ecore_wl_dnd_drag_start
82 * @since 1.7
83 */
84EINA_DEPRECATED EAPI Eina_Bool
52ecore_wl_dnd_start_drag(Ecore_Wl_Dnd *dnd EINA_UNUSED) 85ecore_wl_dnd_start_drag(Ecore_Wl_Dnd *dnd EINA_UNUSED)
53{ 86{
54 //TODO: 87 return EINA_FALSE;
55 return EINA_TRUE;
56} 88}
57 89
58EAPI Eina_Bool 90/**
59ecore_wl_dnd_set_selection(Ecore_Wl_Dnd *dnd, const char **types_offered) 91 * @deprecated use ecore_wl_dnd_selection_owner_has
92 * @since 1.7
93 */
94EINA_DEPRECATED EAPI Eina_Bool
95ecore_wl_dnd_selection_has_owner(Ecore_Wl_Dnd *dnd)
96{
97 return ecore_wl_dnd_selection_owner_has(dnd->input);
98}
99
100/**
101 * @ingroup Ecore_Wl_Dnd_Group
102 * @since 1.8
103 */
104EAPI Eina_Bool
105ecore_wl_dnd_selection_set(Ecore_Wl_Input *input, const char **types_offered)
60{ 106{
61 char **p; 107 struct wl_data_device_manager *man;
62 const char **type; 108 const char **type;
109 char **t;
63 110
64 dnd->data_source = _ecore_wl_create_data_source(dnd->ewd); 111 if (!input) return EINA_FALSE;
65 112
66 /* free old types */ 113 man = input->display->wl.data_device_manager;
67 if (dnd->types_offered.data) 114
115 /* free any old types offered */
116 if (input->data_types.data)
68 { 117 {
69 wl_array_for_each(p, &dnd->types_offered) 118 wl_array_for_each(t, &input->data_types)
70 free(*p); 119 free(*t);
71 wl_array_release(&dnd->types_offered); 120 wl_array_release(&input->data_types);
72 wl_array_init(&dnd->types_offered); 121 wl_array_init(&input->data_types);
73 } 122 }
74 123
75 for (type = types_offered; *type; type++) 124 /* destroy any existing data source */
125 if (input->data_source) wl_data_source_destroy(input->data_source);
126 input->data_source = NULL;
127
128 /* try to create a new data source */
129 if (!(input->data_source = wl_data_device_manager_create_data_source(man)))
130 return EINA_FALSE;
131
132 /* add these types to the data source */
133 for (type = types_offered; *type; type++)
76 { 134 {
77 p = wl_array_add(&dnd->types_offered, sizeof(*p)); 135 t = wl_array_add(&input->data_types, sizeof(*t));
78 *p = strdup(*type); 136 *t = strdup(*type);
79 wl_data_source_offer(dnd->data_source, *p); 137 wl_data_source_offer(input->data_source, *t);
80 } 138 }
81 139
82 wl_data_source_add_listener(dnd->data_source, &_ecore_wl_data_source_listener, dnd); 140 /* add a listener for data source events */
141 wl_data_source_add_listener(input->data_source,
142 &_ecore_wl_dnd_source_listener, input);
83 143
84 _ecore_wl_input_set_selection(dnd->input, dnd->data_source); 144 /* set the selection */
145 wl_data_device_set_selection(input->data_device, input->data_source,
146 input->display->serial);
85 147
86 return EINA_TRUE; 148 return EINA_TRUE;
87} 149}
88 150
89EAPI Eina_Bool 151/**
90ecore_wl_dnd_get_selection(Ecore_Wl_Dnd *dnd, const char *type) 152 * @ingroup Ecore_Wl_Dnd_Group
153 * @since 1.8
154 */
155EAPI Eina_Bool
156ecore_wl_dnd_selection_get(Ecore_Wl_Input *input, const char *type)
91{ 157{
92 char **p; 158 char **t;
93 Ecore_Wl_Input *input;
94
95 input = dnd->input;
96 159
97 if (!input->selection_source) return EINA_FALSE; 160 /* check for valid input and selection source */
161 if ((!input) || (!input->selection_source)) return EINA_FALSE;
98 162
99 wl_array_for_each(p, &input->selection_source->types) 163 wl_array_for_each(t, &input->selection_source->types)
100 if (strcmp(type, *p) == 0) break; 164 if (!strcmp(type, *t)) break;
101 165
102 if (!*p) return EINA_FALSE; 166 if (!*t) return EINA_FALSE;
103 167
104 _ecore_wl_dnd_source_receive_data(input->selection_source, type); 168 _ecore_wl_dnd_selection_data_receive(input->selection_source, type);
105 169
106 return EINA_TRUE; 170 return EINA_TRUE;
107} 171}
108 172
109EAPI Eina_Bool 173/**
110ecore_wl_dnd_selection_has_owner(Ecore_Wl_Dnd *dnd) 174 * @ingroup Ecore_Wl_Dnd_Group
175 * @since 1.8
176 */
177EAPI Eina_Bool
178ecore_wl_dnd_selection_owner_has(Ecore_Wl_Input *input)
111{ 179{
112 Ecore_Wl_Input *input; 180 if (!input) return EINA_FALSE;
113
114 input = dnd->input;
115 return (input->selection_source != NULL); 181 return (input->selection_source != NULL);
116} 182}
117 183
118/* local functions */ 184/**
119static void 185 * @ingroup Ecore_Wl_Dnd_Group
120_ecore_wl_dnd_data_source_target(void *data EINA_UNUSED, struct wl_data_source *source EINA_UNUSED, const char *mime_type EINA_UNUSED) 186 * @since 1.8
187 */
188EAPI Eina_Bool
189ecore_wl_dnd_selection_clear(Ecore_Wl_Input *input)
121{ 190{
122 //TODO: 191 /* check for valid input */
192 if (!input) return EINA_FALSE;
193
194 /* set the selection to NULL */
195 wl_data_device_set_selection(input->data_device, NULL,
196 input->display->serial);
197
198 return EINA_TRUE;
123} 199}
124 200
125static void 201/**
126_ecore_wl_dnd_cb_data_source_send_free(void *data EINA_UNUSED, void *event) 202 * @ingroup Ecore_Wl_Dnd_Group
203 * @since 1.8
204 */
205EAPI void
206ecore_wl_dnd_drag_start(Ecore_Wl_Input *input, Ecore_Wl_Window *win, Ecore_Wl_Window *dragwin, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED)
127{ 207{
128 Ecore_Wl_Event_Data_Source_Send *ev; 208 struct wl_surface *drag_surface;
209
210 /* check for valid input. if not, get the default one */
211 if (!input) input = _ecore_wl_disp->input;
212
213 /* check for valid data source */
214 if (!input->data_source) return;
215
216 /* get the surface from this drag window */
217 drag_surface = ecore_wl_window_surface_get(dragwin);
218
219 /* release any existing grabs */
220 ecore_wl_input_ungrab(input);
221
222 /* add a listener for data source events */
223 wl_data_source_add_listener(input->data_source,
224 &_ecore_wl_dnd_source_listener, input);
225
226 /* start the drag */
227 wl_data_device_start_drag(input->data_device, input->data_source,
228 ecore_wl_window_surface_get(win),
229 drag_surface, input->display->serial);
230
231 /* set pointer image */
232 ecore_wl_input_cursor_from_name_set(input, "move");
233
234 /* NB: Below code disabled for now
235 *
236 * This Was for adjusting the "drag icon" to be centered on the mouse
237 * based on the hotspot, but it crashes for some reason :(
238 */
239
240 /* struct wl_buffer *drag_buffer; */
241 /* struct wl_cursor_image *cursor; */
242 /* int cx = 0, cy = 0; */
243 /* drag_buffer = wl_surface_get_user_data(drag_surface); */
244 /* cursor = input->cursor->images[input->cursor_current_index]; */
245 /* cx = cursor->hotspot_x - x; */
246 /* cy = cursor->hotspot_y - y; */
247 /* wl_surface_attach(drag_surface, drag_buffer, cx, cy); */
248 /* wl_surface_damage(drag_surface, 0, 0, w, h); */
249 /* wl_surface_commit(drag_surface); */
250}
129 251
130 LOGFN(__FILE__, __LINE__, __FUNCTION__); 252/**
253 * @ingroup Ecore_Wl_Dnd_Group
254 * @since 1.8
255 */
256EAPI void
257ecore_wl_dnd_drag_end(Ecore_Wl_Input *input)
258{
259 Ecore_Wl_Event_Dnd_End *ev;
131 260
132 if (!(ev = event)) return; 261 /* check for valid input. if not, get the default one */
262 if (!input) input = _ecore_wl_disp->input;
133 263
134 free(ev->type); 264 if (input->data_types.data)
135 free(ev); 265 {
266 char **t;
267
268 wl_array_for_each(t, &input->data_types)
269 free(*t);
270 wl_array_release(&input->data_types);
271 wl_array_init(&input->data_types);
272 }
273
274 /* if (input->drag_source) _ecore_wl_dnd_del(input->drag_source); */
275 /* input->drag_source = NULL; */
276
277 /* destroy any existing data source */
278 if (input->data_source) wl_data_source_destroy(input->data_source);
279 input->data_source = NULL;
280
281 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_End)))) return;
282
283 if (input->pointer_focus)
284 ev->win = input->pointer_focus->id;
285
286 if (input->keyboard_focus)
287 ev->source = input->keyboard_focus->id;
288
289 ecore_event_add(ECORE_WL_EVENT_DND_END, ev, NULL, NULL);
136} 290}
137 291
138static void 292/**
139_ecore_wl_dnd_data_source_send(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type, int32_t fd) 293 * @ingroup Ecore_Wl_Dnd_Group
294 * @since 1.8
295 */
296EAPI Eina_Bool
297ecore_wl_dnd_drag_get(Ecore_Wl_Input *input, const char *type)
140{ 298{
141 Ecore_Wl_Event_Data_Source_Send *event; 299 char **t;
142 300
143 LOGFN(__FILE__, __LINE__, __FUNCTION__); 301 /* check for valid input and drag source */
302 if ((!input) || (!input->drag_source)) return EINA_FALSE;
144 303
145 if (!data) return; 304 wl_array_for_each(t, &input->drag_source->types)
305 if (!strcmp(type, *t)) break;
146 306
147 if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Data_Source_Send)))) return; 307 if (!*t) return EINA_FALSE;
148 308
149 event->type = strdup(mime_type); 309 _ecore_wl_dnd_selection_data_receive(input->drag_source, type);
150 event->fd = fd;
151 310
152 ecore_event_add(ECORE_WL_EVENT_DATA_SOURCE_SEND, event, _ecore_wl_dnd_cb_data_source_send_free, NULL); 311 return EINA_TRUE;
153} 312}
154 313
155static void 314/**
156_ecore_wl_dnd_data_source_cancelled(void *data EINA_UNUSED, struct wl_data_source *source) 315 * @ingroup Ecore_Wl_Dnd_Group
316 * @since 1.8
317 */
318EAPI void
319ecore_wl_dnd_drag_types_set(Ecore_Wl_Input *input, const char **types_offered)
157{ 320{
158 wl_data_source_destroy(source); 321 struct wl_data_device_manager *man;
322 const char **type;
323 char **t;
324
325 /* check for valid input. if not, get the default one */
326 if (!input) input = _ecore_wl_disp->input;
327
328 man = input->display->wl.data_device_manager;
329
330 /* free any old types offered */
331 if (input->data_types.data)
332 {
333 wl_array_for_each(t, &input->data_types)
334 free(*t);
335 wl_array_release(&input->data_types);
336 wl_array_init(&input->data_types);
337 }
338
339 /* destroy any existing data source */
340 if (input->data_source) wl_data_source_destroy(input->data_source);
341 input->data_source = NULL;
342
343 /* try to create a new data source */
344 if (!(input->data_source = wl_data_device_manager_create_data_source(man)))
345 {
346 printf("Failed to create new data source for drag\n");
347 return;
348 }
349
350 /* add these types to the data source */
351 for (type = types_offered; *type; type++)
352 {
353 t = wl_array_add(&input->data_types, sizeof(*t));
354 *t = strdup(*type);
355 wl_data_source_offer(input->data_source, *t);
356 }
357}
358
359/**
360 * @ingroup Ecore_Wl_Dnd_Group
361 * @since 1.8
362 */
363EAPI struct wl_array *
364ecore_wl_dnd_drag_types_get(Ecore_Wl_Input *input)
365{
366 /* check for valid input. if not, get the default one */
367 if (!input) input = _ecore_wl_disp->input;
368
369 return &input->data_types;
159} 370}
160 371
372/* private functions */
161void 373void
162_ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer) 374_ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer)
163{ 375{
164 Ecore_Wl_Dnd_Source *source; 376 Ecore_Wl_Dnd_Source *source;
165 377
166 LOGFN(__FILE__, __LINE__, __FUNCTION__); 378 if (!(source = malloc(sizeof(Ecore_Wl_Dnd_Source))))
379 return;
167 380
168 if (!(source = malloc(sizeof(Ecore_Wl_Dnd_Source)))) return;
169 wl_array_init(&source->types); 381 wl_array_init(&source->types);
170 source->refcount = 1; 382 source->refcount = 1;
171 source->input = input; 383 source->input = input;
172 source->offer = offer; 384 source->data_offer = offer;
173 wl_data_offer_add_listener(source->offer, 385
174 &_ecore_wl_data_offer_listener, source); 386 wl_data_offer_add_listener(source->data_offer,
387 &_ecore_wl_dnd_offer_listener, source);
175} 388}
176 389
177void 390void
178_ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device EINA_UNUSED, unsigned int timestamp EINA_UNUSED, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer) 391_ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device EINA_UNUSED, unsigned int timestamp, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer)
179{ 392{
180 Ecore_Wl_Event_Dnd_Enter *event; 393 Ecore_Wl_Event_Dnd_Enter *ev;
181 Ecore_Wl_Input *input;
182 Ecore_Wl_Window *win; 394 Ecore_Wl_Window *win;
183 char **p; 395 Ecore_Wl_Input *input;
184 396 char **types;
185 LOGFN(__FILE__, __LINE__, __FUNCTION__); 397 int num = 0;
186
187 if ((!(input = data)) || (!offer)) return;
188 398
189 if (!(input->drag_source = wl_data_offer_get_user_data(offer))) 399 if (!(input = data)) return;
190 return;
191 400
192 win = wl_surface_get_user_data(surface); 401 win = ecore_wl_window_surface_find(surface);
193// input->pointer_focus = win;
194 402
195 p = wl_array_add(&input->drag_source->types, sizeof(*p)); 403 input->pointer_enter_serial = timestamp;
196 *p = NULL; 404 input->pointer_focus = win;
197 405
198 if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Enter)))) return; 406 if (offer)
407 {
408 input->drag_source = wl_data_offer_get_user_data(offer);
199 409
200 event->win = win->id; 410 num = (input->drag_source->types.size / sizeof(char *));
201 if (input->drag_source->input) 411 types = input->drag_source->types.data;
412 }
413 else
202 { 414 {
203 if (input->drag_source->input->keyboard_focus) 415 input->drag_source = NULL;
204 event->source = input->drag_source->input->keyboard_focus->id; 416 types = NULL;
205 } 417 }
206 418
207 event->position.x = wl_fixed_to_int(x); 419 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Enter)))) return;
208 event->position.y = wl_fixed_to_int(y); 420
209 event->num_types = input->drag_source->types.size; 421 if (win)
210 event->types = input->drag_source->types.data; 422 ev->win = win->id;
423
424 if (input->keyboard_focus)
425 ev->source = input->keyboard_focus->id;
426
427 ev->offer = offer;
428 ev->serial = timestamp;
429 ev->position.x = wl_fixed_to_int(x);
430 ev->position.y = wl_fixed_to_int(y);
431 ev->num_types = num;
432 ev->types = types;
211 433
212 ecore_event_add(ECORE_WL_EVENT_DND_ENTER, event, 434 ecore_event_add(ECORE_WL_EVENT_DND_ENTER, ev, NULL, NULL);
213 _ecore_wl_dnd_cb_enter_free, NULL);
214} 435}
215 436
216void 437void
217_ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device EINA_UNUSED) 438_ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device EINA_UNUSED)
218{ 439{
440 Ecore_Wl_Event_Dnd_Leave *ev;
219 Ecore_Wl_Input *input; 441 Ecore_Wl_Input *input;
220 442
221 LOGFN(__FILE__, __LINE__, __FUNCTION__);
222
223 if (!(input = data)) return; 443 if (!(input = data)) return;
224 /* FIXME: NB: This MAY need to raise a wl_event_dnd_leave for the 444
225 * source window */ 445 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Leave)))) return;
226 _ecore_wl_dnd_del(input->drag_source); 446
227 input->drag_source = NULL; 447 if (input->pointer_focus)
448 ev->win = input->pointer_focus->id;
449
450 if (input->keyboard_focus)
451 ev->source = input->keyboard_focus->id;
452
453 ecore_event_add(ECORE_WL_EVENT_DND_LEAVE, ev, NULL, NULL);
228} 454}
229 455
230void 456void
231_ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device EINA_UNUSED, unsigned int timestamp EINA_UNUSED, wl_fixed_t x, wl_fixed_t y) 457_ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device EINA_UNUSED, unsigned int timestamp EINA_UNUSED, int x, int y)
232{ 458{
233 Ecore_Wl_Event_Dnd_Position *event; 459 Ecore_Wl_Event_Dnd_Position *ev;
234 Ecore_Wl_Input *input; 460 Ecore_Wl_Input *input;
235 461
236 LOGFN(__FILE__, __LINE__, __FUNCTION__);
237
238 if (!(input = data)) return; 462 if (!(input = data)) return;
239 463
240 input->sx = wl_fixed_to_int(x); 464 input->sx = wl_fixed_to_int(x);
241 input->sy = wl_fixed_to_int(y); 465 input->sy = wl_fixed_to_int(y);
242 466
243 if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return; 467 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return;
244 468
245 if (input->drag_source) 469 if (input->pointer_focus)
246 { 470 ev->win = input->pointer_focus->id;
247 if (input->drag_source->input)
248 {
249 if (input->drag_source->input->pointer_focus)
250 event->win = input->drag_source->input->pointer_focus->id;
251 if (input->drag_source->input->keyboard_focus)
252 event->source = input->drag_source->input->keyboard_focus->id;
253 }
254 }
255 471
256 event->position.x = input->sx; 472 if (input->keyboard_focus)
257 event->position.y = input->sy; 473 ev->source = input->keyboard_focus->id;
258 474
259 ecore_event_add(ECORE_WL_EVENT_DND_POSITION, event, NULL, NULL); 475 ev->position.x = input->sx;
476 ev->position.y = input->sy;
477
478 ecore_event_add(ECORE_WL_EVENT_DND_POSITION, ev, NULL, NULL);
260} 479}
261 480
262void 481void
263_ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device EINA_UNUSED) 482_ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device EINA_UNUSED)
264{ 483{
265 Ecore_Wl_Event_Dnd_Drop *event; 484 Ecore_Wl_Event_Dnd_Drop *ev;
266 Ecore_Wl_Input *input; 485 Ecore_Wl_Input *input;
267 486
268 LOGFN(__FILE__, __LINE__, __FUNCTION__);
269
270 if (!(input = data)) return; 487 if (!(input = data)) return;
271 488
272 if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Drop)))) return; 489 if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Drop)))) return;
273 490
274 if (input->drag_source) 491 if (input->drag_source)
275 { 492 {
276 if (input->drag_source->input) 493 if (input->pointer_focus)
277 { 494 ev->win = input->pointer_focus->id;
278 if (input->drag_source->input->pointer_focus) 495 if (input->keyboard_focus)
279 event->win = input->drag_source->input->pointer_focus->id; 496 ev->source = input->keyboard_focus->id;
280 if (input->drag_source->input->keyboard_focus)
281 event->source = input->drag_source->input->keyboard_focus->id;
282 }
283 } 497 }
284 498
285 event->position.x = input->sx; 499 ev->position.x = input->sx;
286 event->position.y = input->sy; 500 ev->position.y = input->sy;
287 501
288 ecore_event_add(ECORE_WL_EVENT_DND_DROP, event, NULL, NULL); 502 ecore_event_add(ECORE_WL_EVENT_DND_DROP, ev, NULL, NULL);
289} 503}
290 504
291void 505void
@@ -293,35 +507,30 @@ _ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device EINA_UNUS
293{ 507{
294 Ecore_Wl_Input *input; 508 Ecore_Wl_Input *input;
295 509
296 LOGFN(__FILE__, __LINE__, __FUNCTION__);
297
298 if (!(input = data)) return; 510 if (!(input = data)) return;
511
299 if (input->selection_source) _ecore_wl_dnd_del(input->selection_source); 512 if (input->selection_source) _ecore_wl_dnd_del(input->selection_source);
300 input->selection_source = NULL; 513
301 if (offer) 514 if (offer)
302 { 515 {
303 char **p; 516 char **t;
304 517
305 input->selection_source = wl_data_offer_get_user_data(offer); 518 input->selection_source = wl_data_offer_get_user_data(offer);
306 p = wl_array_add(&input->selection_source->types, sizeof(*p)); 519 t = wl_array_add(&input->selection_source->types, sizeof(*t));
307 *p = NULL; 520 *t = NULL;
308 } 521 }
522 else
523 input->selection_source = NULL;
309} 524}
310 525
311void 526void
312_ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source) 527_ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source)
313{ 528{
314 LOGFN(__FILE__, __LINE__, __FUNCTION__);
315
316 if (!source) return; 529 if (!source) return;
317 source->refcount--; 530 source->refcount--;
318 if (source->refcount == 0) 531 if (source->refcount == 0)
319 { 532 {
320 char **p; 533 wl_data_offer_destroy(source->data_offer);
321
322 wl_data_offer_destroy(source->offer);
323 for (p = source->types.data; *p; p++)
324 free(*p);
325 wl_array_release(&source->types); 534 wl_array_release(&source->types);
326 free(source); 535 free(source);
327 } 536 }
@@ -329,47 +538,65 @@ _ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source)
329 538
330/* local functions */ 539/* local functions */
331static void 540static void
332_ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer EINA_UNUSED, const char *type) 541_ecore_wl_dnd_selection_data_receive(Ecore_Wl_Dnd_Source *source, const char *type)
333{ 542{
334 Ecore_Wl_Dnd_Source *source; 543 int epoll_fd;
335 char **p; 544 struct epoll_event *ep = NULL;
545 struct _dnd_task *task = NULL;
546 struct _dnd_read_ctx *read_ctx = NULL;
547 int p[2];
336 548
337 LOGFN(__FILE__, __LINE__, __FUNCTION__); 549 if (pipe2(p, O_CLOEXEC) == -1)
550 return;
338 551
339 if (!(source = data)) return; 552 wl_data_offer_receive(source->data_offer, type, p[1]);
340 p = wl_array_add(&source->types, sizeof(*p)); 553 close(p[1]);
341 *p = strdup(type);
342}
343 554
344static void 555 /* Due to http://trac.enlightenment.org/e/ticket/1208,
345_ecore_wl_dnd_cb_enter_free(void *data EINA_UNUSED, void *event) 556 * use epoll and idle handler instead of ecore_main_fd_handler_add() */
346{
347 Ecore_Wl_Event_Dnd_Enter *ev;
348 557
349 LOGFN(__FILE__, __LINE__, __FUNCTION__); 558 ep = calloc(1, sizeof(struct epoll_event));
559 if (!ep) goto err;
350 560
351 if (!(ev = event)) return; 561 task = calloc(1, sizeof(struct _dnd_task));
352 free(ev); 562 if (!task) goto err;
353}
354 563
355static void 564 read_ctx = calloc(1, sizeof(struct _dnd_read_ctx));
356_ecore_wl_dnd_cb_selection_data_ready_free(void *data EINA_UNUSED, void *event) 565 if (!read_ctx) goto err;
357{
358 Ecore_Wl_Event_Selection_Data_Ready *ev;
359 566
360 LOGFN(__FILE__, __LINE__, __FUNCTION__); 567 epoll_fd = epoll_create1(0);
568 if (epoll_fd < 0) goto err;
361 569
362 if (!(ev = event)) return; 570 task->data = source;
571 task->cb = _ecore_wl_dnd_selection_data_read;
572 ep->events = EPOLLIN;
573 ep->data.ptr = task;
363 574
364 free(ev->data); 575 if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, p[0], ep) < 0) goto err;
365 free(ev); 576
577 read_ctx->epoll_fd = epoll_fd;
578 read_ctx->ep = ep;
579
580 if (!ecore_idler_add(_ecore_wl_dnd_selection_cb_idle, read_ctx)) goto err;
581
582 source->refcount++;
583 source->fd = p[0];
584
585 return;
586
587err:
588 if (ep) free(ep);
589 if (task) free(task);
590 if (read_ctx) free(read_ctx);
591 close(p[0]);
592 return;
366} 593}
367 594
368static Eina_Bool 595static Eina_Bool
369_ecore_wl_dnd_read_data(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED) 596_ecore_wl_dnd_selection_data_read(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
370{ 597{
371 int len; 598 int len;
372 char buffer[4096]; 599 char buffer[PATH_MAX];
373 Ecore_Wl_Dnd_Source *source; 600 Ecore_Wl_Dnd_Source *source;
374 Ecore_Wl_Event_Selection_Data_Ready *event; 601 Ecore_Wl_Event_Selection_Data_Ready *event;
375 Eina_Bool ret; 602 Eina_Bool ret;
@@ -402,13 +629,26 @@ _ecore_wl_dnd_read_data(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
402 } 629 }
403 630
404 ecore_event_add(ECORE_WL_EVENT_SELECTION_DATA_READY, event, 631 ecore_event_add(ECORE_WL_EVENT_SELECTION_DATA_READY, event,
405 _ecore_wl_dnd_cb_selection_data_ready_free, NULL); 632 _ecore_wl_dnd_selection_data_ready_cb_free, NULL);
633
406 return ret; 634 return ret;
407} 635}
408 636
637static void
638_ecore_wl_dnd_selection_data_ready_cb_free(void *data EINA_UNUSED, void *event)
639{
640 Ecore_Wl_Event_Selection_Data_Ready *ev;
641
642 LOGFN(__FILE__, __LINE__, __FUNCTION__);
643
644 if (!(ev = event)) return;
645
646 free(ev->data);
647 free(ev);
648}
409 649
410static Eina_Bool 650static Eina_Bool
411_ecore_wl_dnd_idler_cb(void *data) 651_ecore_wl_dnd_selection_cb_idle(void *data)
412{ 652{
413 struct _dnd_read_ctx *ctx; 653 struct _dnd_read_ctx *ctx;
414 struct _dnd_task *task; 654 struct _dnd_task *task;
@@ -430,56 +670,63 @@ _ecore_wl_dnd_idler_cb(void *data)
430 return ECORE_CALLBACK_RENEW; 670 return ECORE_CALLBACK_RENEW;
431} 671}
432 672
433static void 673static void
434_ecore_wl_dnd_source_receive_data(Ecore_Wl_Dnd_Source *source, const char *type) 674_ecore_wl_dnd_source_cb_target(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type EINA_UNUSED)
435{ 675{
436 int epoll_fd; 676 Ecore_Wl_Input *input;
437 struct epoll_event *ep = NULL;
438 struct _dnd_task *task = NULL;
439 struct _dnd_read_ctx *read_ctx = NULL;
440 int p[2];
441 677
442 if (pipe2(p, O_CLOEXEC) == -1) 678 if (!(input = data)) return;
443 return;
444 679
445 wl_data_offer_receive(source->offer, type, p[1]); 680 printf("Dnd Source Target\n");
446 close(p[1]); 681}
447 682
448 /* Due to http://trac.enlightenment.org/e/ticket/1208, 683static void
449 * use epoll and idle handler instead of ecore_main_fd_handler_add() */ 684_ecore_wl_dnd_source_cb_send(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type, int32_t fd)
685{
686 Ecore_Wl_Event_Data_Source_Send *event;
687 Ecore_Wl_Input *input;
450 688
451 ep = calloc(1, sizeof(struct epoll_event)); 689 LOGFN(__FILE__, __LINE__, __FUNCTION__);
452 if (!ep) goto err;
453 690
454 task = calloc(1, sizeof(struct _dnd_task)); 691 if (!(input = data)) return;
455 if (!task) goto err;
456 692
457 read_ctx = calloc(1, sizeof(struct _dnd_read_ctx)); 693 if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Data_Source_Send)))) return;
458 if (!read_ctx) goto err;
459 694
460 epoll_fd = epoll_create1(0); 695 event->type = strdup(mime_type);
461 if (epoll_fd < 0) goto err; 696 event->fd = fd;
462 697
463 task->data = source; 698 ecore_event_add(ECORE_WL_EVENT_DATA_SOURCE_SEND, event,
464 task->cb = _ecore_wl_dnd_read_data; 699 _ecore_wl_dnd_source_cb_send_free, NULL);
465 ep->events = EPOLLIN; 700}
466 ep->data.ptr = task;
467 701
468 if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, p[0], ep) < 0) goto err; 702static void
703_ecore_wl_dnd_source_cb_send_free(void *data EINA_UNUSED, void *event)
704{
705 Ecore_Wl_Event_Data_Source_Send *ev;
469 706
470 read_ctx->epoll_fd = epoll_fd; 707 LOGFN(__FILE__, __LINE__, __FUNCTION__);
471 read_ctx->ep = ep;
472 708
473 if (!ecore_idler_add(_ecore_wl_dnd_idler_cb, read_ctx)) goto err; 709 if (!(ev = event)) return;
474 710
475 source->refcount++; 711 free(ev->type);
476 source->fd = p[0]; 712 free(ev);
477 return; 713}
478 714
479err: 715static void
480 if (ep) free(ep); 716_ecore_wl_dnd_source_cb_cancelled(void *data EINA_UNUSED, struct wl_data_source *source)
481 if (task) free(task); 717{
482 if (read_ctx) free(read_ctx); 718 /* FIXME: Raise an Ecore_Wl_Event here */
483 close(p[0]); 719 wl_data_source_destroy(source);
484 return; 720}
721
722static void
723_ecore_wl_dnd_offer_cb_offer(void *data, struct wl_data_offer *data_offer EINA_UNUSED, const char *type)
724{
725 Ecore_Wl_Dnd_Source *source;
726 char **t;
727
728 if (!(source = data)) return;
729
730 t = wl_array_add(&source->types, sizeof(*t));
731 *t = strdup(type);
485} 732}