e_input: move kbd structure to e_comp_input_intern.h
[platform/upstream/enlightenment.git] / src / bin / e_comp_wl_data.c
1 #include "e_comp_wl_data_intern.h"
2 #include "e_comp_wl_input_intern.h"
3 #include "e_comp_canvas_intern.h"
4 #include "e_comp_wl_intern.h"
5 #include "e_dnd_intern.h"
6 #include "e_comp_input_intern.h"
7
8 #include <fcntl.h>
9 #include <unistd.h>
10
11 #define EXECUTIVE_MODE_ENABLED
12
13 typedef struct {
14    int src_fd;
15    int dst_fd;
16 } E_Comp_Wl_Thread_Data;
17
18 static void _e_comp_wl_data_source_cancelled_send(E_Comp_Wl_Data_Source *source);
19
20 static void
21 _mime_types_free(E_Comp_Wl_Data_Source *source)
22 {
23    if (!source->mime_types) return;
24    while (eina_array_count(source->mime_types))
25      eina_stringshare_del(eina_array_pop(source->mime_types));
26    eina_array_free(source->mime_types);
27 }
28
29 static void
30 _e_comp_wl_data_offer_cb_accept(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *mime_type)
31 {
32    E_Comp_Wl_Data_Offer *offer;
33
34    DBG("Data Offer Accept");
35    if (!(offer = wl_resource_get_user_data(resource)))
36      return;
37
38    if (offer->source && e_comp_wl->drag_offer == offer)
39      {
40         offer->source->target(offer->source, serial, mime_type);
41         offer->source->accepted = !!mime_type;
42      }
43 }
44
45 static void
46 _e_comp_wl_data_pipe_run(void *data, Ecore_Thread *th)
47 {
48    E_Comp_Wl_Thread_Data *td;
49    char *p = NULL;
50    int read_len = 0, write_len = 0;
51    int retry_position, retry_cnt = 0;
52
53    if (!(td = data)) return;
54
55    eina_thread_name_set(eina_thread_self(), "e_comp_wl_data_pipe");
56
57    if (ecore_thread_check(th)) return;
58
59    DBG("_e_comp_wl_data_pipe_run. th:%p", th);
60
61    p = (char *)calloc(sizeof(char), CLIPBOARD_CHUNK);
62    if (!p) return;
63
64    while (1)
65      {
66         read_len = read(td->src_fd, p, CLIPBOARD_CHUNK);
67         if (read_len == -1)
68           {
69              if (errno == EINTR || errno == EAGAIN)
70                {
71                   DBG("IO error in _e_comp_wl_dnd_offer_mediate READ. try again");
72                   retry_cnt++;
73                   if (retry_cnt > 10000)
74                     {
75                        ERR("retry over 10000. break");
76                        goto cleanup;
77                     }
78                   continue;
79                }
80              else
81                {
82                   DBG("IO error in _e_comp_wl_dnd_offer_mediate READ.(%d)", errno);
83                   goto cleanup;
84                }
85           }
86
87         retry_position = 0;
88         while (1)
89           {
90              write_len = write(td->dst_fd, p + retry_position, read_len - retry_position);
91              if (write_len == -1)
92                {
93                   if (errno == EINTR || errno == EAGAIN)
94                     {
95                        DBG("IO error in _e_comp_wl_dnd_offer_mediate WRITE. try again");
96                        continue;
97                     }
98                   else
99                     {
100                        ERR("IO error in _e_comp_wl_dnd_offer_mediate WRITE.(%d)", errno);
101                        goto cleanup;
102                     }
103                }
104              else if (read_len - retry_position == write_len)
105                {
106                   break;
107                }
108              else
109                {
110                   retry_position = read_len - write_len;
111                   continue;
112                }
113           }
114
115         if (p[read_len - 1] == '\0')
116           {
117              DBG("mediate done. read and write done");
118              break;
119           }
120         retry_cnt = 0;
121      }
122
123 cleanup:
124       if (p) free(p);
125 }
126
127 static void
128 _e_comp_wl_data_pipe_close(E_Comp_Wl_Thread_Data *td)
129 {
130    close(td->src_fd);
131    close(td->dst_fd);
132
133    E_FREE(td);
134 }
135
136 static void
137 _e_comp_wl_data_pipe_done(void *data, Ecore_Thread *th)
138 {
139    E_Comp_Wl_Thread_Data *td = data;
140
141    if (!td) return;
142
143    DBG("_e_comp_wl_data_pipe_done. th:%p", th);
144
145    _e_comp_wl_data_pipe_close(td);
146 }
147
148 static void
149 _e_comp_wl_data_pipe_cancel(void *data, Ecore_Thread *th)
150 {
151    E_Comp_Wl_Thread_Data *td = data;
152
153    if (!td) return;
154
155    DBG("_e_comp_wl_data_pipe_cancel. th:%p", th);
156
157    _e_comp_wl_data_pipe_close(td);
158 }
159
160 static Eina_Bool
161 _e_comp_wl_dnd_offer_mediate(void *data, Ecore_Fd_Handler *handler)
162 {
163    E_Comp_Wl_Data_Offer *offer = NULL;
164    E_Comp_Wl_Thread_Data *td;
165    int source_fd = -1;
166
167    if (!(offer = (E_Comp_Wl_Data_Offer*)data))
168      return ECORE_CALLBACK_CANCEL;
169    EINA_SAFETY_ON_NULL_RETURN_VAL(offer->source, ECORE_CALLBACK_CANCEL);
170
171    source_fd = ecore_main_fd_handler_fd_get(handler);
172    if (source_fd < 0) goto cleanup;
173    if (offer->fd < 0) goto cleanup;
174
175    td = E_NEW(E_Comp_Wl_Thread_Data, 1);
176    if (!td) return ECORE_CALLBACK_RENEW;
177
178    td->src_fd = source_fd;
179    td->dst_fd = offer->fd;
180    offer->th = ecore_thread_run(_e_comp_wl_data_pipe_run,
181                                 _e_comp_wl_data_pipe_done,
182                                 _e_comp_wl_data_pipe_cancel,
183                                 td);
184    if (offer->th == NULL)
185      goto cleanup;
186
187    ecore_main_fd_handler_del(handler);
188    offer->source->fd_handler = NULL;
189
190    DBG("create thread for pipe th:%p,  src:%d, dst:%d", offer->th, td->src_fd, td->dst_fd);
191
192    return ECORE_CALLBACK_DONE;
193
194 cleanup:
195    if (offer->fd > 0)
196      {
197         close(offer->fd);
198         offer->fd = 0;
199      }
200    if (source_fd > 0) close(source_fd);
201    ecore_main_fd_handler_del(handler);
202    offer->source->fd_handler = NULL;
203
204    return ECORE_CALLBACK_DONE;
205 }
206
207 static int
208 _e_comp_wl_dnd_offer_mediator_init(E_Comp_Wl_Data_Offer* offer, int fd)
209 {
210    EINA_SAFETY_ON_NULL_RETURN_VAL(offer, -1);
211    EINA_SAFETY_ON_NULL_RETURN_VAL(offer->source, -1);
212
213    if (pipe2(offer->source->fd, O_CLOEXEC|O_DIRECT|O_NONBLOCK) == -1)
214      {
215         ERR("Could not create unidirectional pipe for dnd: %m");
216         return -1;
217      }
218
219    offer->fd = fd;
220    offer->source->fd_handler =
221       ecore_main_fd_handler_add(offer->source->fd[0], ECORE_FD_READ,
222                                 _e_comp_wl_dnd_offer_mediate, offer,
223                                 NULL, NULL);
224
225    DBG("_e_comp_wl_dnd_offer_mediate:: init mediator, offer_fd: %d / source_fd: %d, %d", fd, offer->source->fd[0], offer->source->fd[1]);
226    return offer->source->fd[1];
227 }
228
229 static void
230 _e_comp_wl_data_source_notify_finish(E_Comp_Wl_Data_Source *source)
231 {
232    E_Comp_Wl_Data_Offer *drag_offer;
233
234    if (!source->actions_set)
235      return;
236
237    drag_offer = e_comp_wl->drag_offer;
238
239    if (drag_offer && drag_offer->in_ask &&
240        wl_resource_get_version(source->resource) >= WL_DATA_SOURCE_ACTION_SINCE_VERSION)
241      {
242         wl_data_source_send_action(source->resource, source->current_dnd_action);
243      }
244
245    if (wl_resource_get_version(source->resource) >= WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
246      {
247         wl_data_source_send_dnd_finished(source->resource);
248      }
249
250    e_comp_wl->drag_offer = NULL;
251 }
252
253 static uint32_t
254 _e_comp_wl_data_offer_choose_action(E_Comp_Wl_Data_Offer *offer)
255 {
256    uint32_t available_actions, preferred_action = 0;
257    uint32_t source_actions, offer_actions;
258
259    EINA_SAFETY_ON_NULL_RETURN_VAL(offer->source, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE);
260
261    if (wl_resource_get_version(offer->resource) >= WL_DATA_OFFER_ACTION_SINCE_VERSION)
262      {
263         offer_actions = offer->dnd_actions;
264         preferred_action = offer->preferred_dnd_action;
265      }
266    else
267      {
268         offer_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
269      }
270
271    if (wl_resource_get_version(offer->source->resource) >= WL_DATA_SOURCE_ACTION_SINCE_VERSION)
272      source_actions = offer->source->dnd_actions;
273    else
274      source_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
275
276    available_actions = offer_actions & source_actions;
277
278    if (!available_actions)
279      return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
280
281    if (offer->source->compositor_action & available_actions)
282      return offer->source->compositor_action;
283
284    /* If the dest side has a preferred DnD action, use it */
285    if (preferred_action & available_actions)
286      return preferred_action;
287
288    /* Use the first found action, in bit order */
289    return 1 << (ffs(available_actions) - 1);
290 }
291
292 static void
293 _e_comp_wl_data_offer_update_action(E_Comp_Wl_Data_Offer *offer)
294 {
295    uint32_t action;
296
297    if (!offer->source || !offer->source->actions_set)
298      return;
299
300    action = _e_comp_wl_data_offer_choose_action(offer);
301
302    if (offer->source->current_dnd_action == action)
303      return;
304
305    offer->source->current_dnd_action = action;
306
307    if (offer->in_ask)
308      return;
309
310    if (wl_resource_get_version(offer->source->resource) >= WL_DATA_SOURCE_ACTION_SINCE_VERSION)
311      wl_data_source_send_action(offer->source->resource, action);
312
313    if (wl_resource_get_version(offer->resource) >= WL_DATA_OFFER_ACTION_SINCE_VERSION)
314      wl_data_offer_send_action(offer->resource, action);
315 }
316
317 static void
318 _e_comp_wl_data_offer_cb_receive(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type, int32_t fd)
319 {
320    E_Comp_Wl_Data_Offer *offer;
321    int new_fd;
322
323    DBG("Data Offer Receive FD:%d", fd);
324
325    if (!(offer = wl_resource_get_user_data(resource)))
326      {
327         close(fd);
328         return;
329      }
330
331    new_fd = _e_comp_wl_dnd_offer_mediator_init(offer, fd);
332    if (new_fd < 0)
333      {
334         DBG("_e_comp_wl_dnd_offer_mediator_init failed, close fd:%d", fd);
335         close(fd);
336         return;
337      }
338
339    if (offer->source)
340      offer->source->send(offer->source, mime_type, new_fd);
341    close(new_fd);
342 }
343
344 /* called by wl_data_offer_destroy */
345 static void
346 _e_comp_wl_data_offer_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
347 {
348    DBG("Data Offer Destroy");
349    wl_resource_destroy(resource);
350 }
351
352 /* called by wl_resource_destroy */
353 static void
354 _e_comp_wl_data_offer_cb_resource_destroy(struct wl_resource *resource)
355 {
356    E_Comp_Wl_Data_Offer *offer;
357
358    if (!(offer = wl_resource_get_user_data(resource)))
359      return;
360
361    if (offer->source)
362      {
363         wl_list_remove(&offer->source_destroy_listener.link);
364         if (offer->source->fd_handler)
365           ecore_main_fd_handler_del(offer->source->fd_handler);
366
367         if (wl_resource_get_version(offer->resource) < WL_DATA_OFFER_ACTION_SINCE_VERSION)
368           _e_comp_wl_data_source_notify_finish(offer->source);
369         else if (offer->dropped && offer->source != e_comp_wl->drag_source)
370           _e_comp_wl_data_source_cancelled_send(offer->source);
371      }
372
373    if (offer == e_comp_wl->drag_offer)
374      e_comp_wl->drag_offer = NULL;
375
376    if ((offer->th != NULL) && !ecore_thread_check(offer->th))
377      {
378         ecore_thread_cancel(offer->th);
379         offer->th = NULL;
380      }
381
382    free(offer);
383 }
384
385 /* called by emission of source->destroy_signal */
386 static void
387 _e_comp_wl_data_offer_cb_source_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
388 {
389    E_Comp_Wl_Data_Offer *offer;
390
391    DBG("Data Offer Source Destroy");
392    offer = container_of(listener, E_Comp_Wl_Data_Offer,
393                         source_destroy_listener);
394    if (!offer) return;
395
396    offer->source = NULL;
397 }
398
399 static void
400 _e_comp_wl_data_offer_cb_finish(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
401 {
402    E_Comp_Wl_Data_Offer *offer;
403
404    DBG("Data Offer finished");
405    if (!(offer = wl_resource_get_user_data(resource)))
406      return;
407
408    if (!offer->source || !offer->source->accepted)
409      {
410         wl_resource_post_error(offer->resource,
411                                WL_DATA_OFFER_ERROR_INVALID_FINISH,
412                                "premature finish request");
413         return;
414      }
415
416    switch (offer->source->current_dnd_action)
417      {
418        case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE:
419        case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK:
420            wl_resource_post_error(offer->resource,
421                                   WL_DATA_OFFER_ERROR_INVALID_OFFER,
422                                   "offer finished with an invalid action");
423            return;
424        default :
425            break;
426      }
427    _e_comp_wl_data_source_notify_finish(offer->source);
428 }
429
430 static void
431 _e_comp_wl_data_offer_cb_set_actions(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t dnd_actions, uint32_t preferred_action)
432 {
433    E_Comp_Wl_Data_Offer *offer;
434
435    DBG("Data Offer set actions: actions:%u, preferred_action:%u", dnd_actions, preferred_action);
436    if (!(offer = wl_resource_get_user_data(resource)))
437      return;
438
439    if (dnd_actions & ~(WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY |
440                        WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE |
441                        WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK))
442      {
443         wl_resource_post_error(offer->resource,
444                                WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK,
445                                "invalid action mask %x", dnd_actions);
446         return;
447      }
448
449    if (preferred_action &&
450        (!(preferred_action & dnd_actions) ||
451         __builtin_popcount(preferred_action) > 1))
452      {
453         wl_resource_post_error(offer->resource,
454                                WL_DATA_OFFER_ERROR_INVALID_ACTION,
455                                "invalid action %x", preferred_action);
456         return;
457      }
458
459    offer->dnd_actions = dnd_actions;
460    offer->preferred_dnd_action = preferred_action;
461    _e_comp_wl_data_offer_update_action(offer);
462 }
463
464 static const struct wl_data_offer_interface _e_data_offer_interface =
465 {
466    _e_comp_wl_data_offer_cb_accept,
467    _e_comp_wl_data_offer_cb_receive,
468    _e_comp_wl_data_offer_cb_destroy,
469    _e_comp_wl_data_offer_cb_finish,
470    _e_comp_wl_data_offer_cb_set_actions,
471 };
472
473 static void
474 _e_comp_wl_data_source_cb_offer(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type)
475 {
476    E_Comp_Wl_Data_Source *source;
477
478    DBG("Data Source Offer");
479    if (!(source = wl_resource_get_user_data(resource)))
480      return;
481
482    if (!source->mime_types)
483      source->mime_types = eina_array_new(1);
484
485    EINA_SAFETY_ON_NULL_RETURN(source->mime_types);
486
487    eina_array_push(source->mime_types, eina_stringshare_add(mime_type));
488 }
489
490 /* called by wl_data_source_destroy */
491 static void
492 _e_comp_wl_data_source_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
493 {
494    DBG("Data Source Destroy");
495    wl_resource_destroy(resource);
496 }
497
498 /* called by wl_resource_destroy */
499 static void
500 _e_comp_wl_data_source_cb_resource_destroy(struct wl_resource *resource)
501 {
502    E_Comp_Wl_Data_Source *source;
503
504    if (!(source = wl_resource_get_user_data(resource)))
505      return;
506
507    wl_signal_emit(&source->destroy_signal, source);
508
509    if (e_comp_wl->drag_source == source)
510      {
511         e_comp_wl->drag_source = NULL;
512         e_comp_override_del();
513         e_drag_end(e_comp_wl->drag, E_DND_DRAG_TYPE_CANCELLED);
514      }
515
516    _mime_types_free(source);
517    free(source);
518 }
519
520 static void
521 _e_comp_wl_data_source_cb_set_actions(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t dnd_actions)
522 {
523    E_Comp_Wl_Data_Source *source;
524
525    DBG("Data Source Offer");
526    if (!(source = wl_resource_get_user_data(resource)))
527      return;
528
529    if (source->actions_set)
530      {
531         wl_resource_post_error(source->resource,
532                                WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
533                                "cannot set actions more than once");
534         return;
535      }
536
537    if (dnd_actions & ~(WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY |
538                        WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE |
539                        WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK))
540      {
541         wl_resource_post_error(source->resource,
542                                WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
543                                "invalid action mask %x", dnd_actions);
544         return;
545      }
546    source->dnd_actions = dnd_actions;
547    source->actions_set = 1;
548 }
549
550 static void
551 _e_comp_wl_data_source_target_send(E_Comp_Wl_Data_Source *source, uint32_t serial EINA_UNUSED, const char* mime_type)
552 {
553    DBG("Data Source Target Send");
554    wl_data_source_send_target(source->resource, mime_type);
555 }
556
557 static void
558 _e_comp_wl_data_source_send_send(E_Comp_Wl_Data_Source *source, const char* mime_type, int32_t fd)
559 {
560    DBG("Data Source Source Send");
561    wl_data_source_send_send(source->resource, mime_type, fd);
562 }
563
564 static void
565 _e_comp_wl_data_source_cancelled_send(E_Comp_Wl_Data_Source *source)
566 {
567    DBG("Data Source Cancelled Send");
568    wl_data_source_send_cancelled(source->resource);
569 }
570
571 static const struct wl_data_source_interface _e_data_source_interface =
572 {
573    _e_comp_wl_data_source_cb_offer,
574    _e_comp_wl_data_source_cb_destroy,
575    _e_comp_wl_data_source_cb_set_actions,
576 };
577
578 static void
579 _e_comp_wl_data_device_destroy_selection_data_source(struct wl_listener *listener EINA_UNUSED, void *data)
580 {
581    E_Comp_Wl_Data_Source *source;
582    struct wl_resource *data_device_res = NULL, *focus = NULL;
583    struct wl_client *source_client, *cbhm_client = NULL;
584
585    DBG("Data Device Destroy Selection Source");
586    if (!(source = (E_Comp_Wl_Data_Source*)data))
587      return;
588
589    e_comp_wl->selection.data_source = NULL;
590
591    source_client = wl_resource_get_client(source->resource);
592    if (e_comp_wl->selection.cbhm)
593      cbhm_client =  wl_resource_get_client(e_comp_wl->selection.cbhm);
594
595    if ((cbhm_client) && (source_client != cbhm_client))
596      {
597         data_device_res =
598            e_comp_wl_data_find_for_client(wl_resource_get_client(e_comp_wl->selection.cbhm));
599
600         if (data_device_res)
601           wl_data_device_send_selection(data_device_res, NULL);
602
603         return;
604      }
605
606    if (e_comp_input_key->kbd.enabled)
607      focus = e_comp_input_key->kbd.focus;
608
609    if (focus)
610      {
611         data_device_res =
612            e_comp_wl_data_find_for_client(wl_resource_get_client(focus));
613
614         if (data_device_res)
615           wl_data_device_send_selection(data_device_res, NULL);
616      }
617
618    if (e_comp_wl->selection.data_only_list)
619      {
620         struct wl_resource *data_only;
621         Eina_List *l;
622
623         EINA_LIST_FOREACH(e_comp_wl->selection.data_only_list, l, data_only)
624            wl_data_device_send_selection(data_only, NULL);
625      }
626
627    wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
628 }
629
630 static struct wl_resource*
631 _e_comp_wl_data_device_data_offer_create(E_Comp_Wl_Data_Source *source, struct wl_resource *data_device_res)
632 {
633    E_Comp_Wl_Data_Offer *offer;
634    Eina_Iterator *it;
635    char *t;
636
637    DBG("Data Offer Create");
638
639    offer = E_NEW(E_Comp_Wl_Data_Offer, 1);
640    if (!offer) return NULL;
641
642    offer->resource =
643        wl_resource_create(wl_resource_get_client(data_device_res),
644                           &wl_data_offer_interface, 3, 0);
645    if (!offer->resource)
646      {
647         free(offer);
648         return NULL;
649      }
650
651    wl_resource_set_implementation(offer->resource,
652                                   &_e_data_offer_interface, offer,
653                                   _e_comp_wl_data_offer_cb_resource_destroy);
654    offer->source = source;
655    offer->source_destroy_listener.notify =
656      _e_comp_wl_data_offer_cb_source_destroy;
657    wl_signal_add(&source->destroy_signal, &offer->source_destroy_listener);
658
659    wl_data_device_send_data_offer(data_device_res, offer->resource);
660
661    it = eina_array_iterator_new(source->mime_types);
662    EINA_ITERATOR_FOREACH(it, t)
663      wl_data_offer_send_offer(offer->resource, t);
664    eina_iterator_free(it);
665
666    _e_comp_wl_data_offer_update_action(offer);
667
668    return offer->resource;
669 }
670
671 static Eina_Bool
672 _e_comp_wl_data_secondary_res_check(struct wl_resource *resource)
673 {
674    struct wl_resource *surface;
675    E_Client *ec;
676    Eina_List *l;
677
678    if (resource == NULL)
679      return EINA_FALSE;
680
681    if (e_comp_wl->selection.secondary_list == NULL)
682      return EINA_FALSE;
683
684    EINA_LIST_FOREACH(e_comp_wl->selection.secondary_list, l, ec)
685      {
686         surface = e_comp_wl_client_surface_get(ec);
687         if (!surface) continue;
688
689         if (wl_resource_get_client(surface) == wl_resource_get_client(resource))
690           return EINA_TRUE;
691      }
692
693    return EINA_FALSE;
694 }
695
696 static void
697 _e_comp_wl_data_secondary_send(E_Comp_Wl_Data_Source *source)
698 {
699    struct wl_client *secondary_client;
700    struct wl_resource *surface, *offer_res, *data_device_res;
701    E_Client *ec;
702    Eina_List *l;
703
704    EINA_LIST_FOREACH(e_comp_wl->selection.secondary_list, l, ec)
705      {
706         surface = e_comp_wl_client_surface_get(ec);
707         if (!surface) continue;
708
709         if ((e_comp_wl->selection.secondary_sent != NULL) &&
710             (wl_resource_get_client(surface) == wl_resource_get_client(e_comp_wl->selection.secondary_sent)))
711           continue;
712
713         secondary_client = wl_resource_get_client(surface);
714         if (secondary_client == NULL)
715           {
716              ERR("error get client resource");
717              continue;
718           }
719         data_device_res = e_comp_wl_data_find_for_client(secondary_client);
720         if (data_device_res == NULL)
721           {
722              ERR("error get device resource");
723              continue;
724           }
725
726         if (source)
727           {
728              offer_res = _e_comp_wl_data_device_data_offer_create(source, data_device_res);
729              wl_data_device_send_selection(data_device_res, offer_res);
730           }
731         else
732           wl_data_device_send_selection(data_device_res, NULL);
733      }
734
735    e_comp_wl->selection.secondary_sent = NULL;
736 }
737
738 static void
739 _e_comp_wl_data_device_selection_set(void *data EINA_UNUSED, E_Comp_Wl_Data_Source *source, uint32_t serial)
740 {
741    E_Comp_Wl_Data_Source *sel_source;
742    struct wl_resource *offer_res, *data_device_res, *focus = NULL;
743    struct wl_client *source_client = NULL, *sel_client = NULL, *cbhm_client = NULL;
744
745    sel_source = (E_Comp_Wl_Data_Source*)e_comp_wl->selection.data_source;
746
747    if ((source) && (source->resource))
748      source_client = wl_resource_get_client(source->resource);
749    if ((sel_source) && (sel_source->resource))
750      sel_client = wl_resource_get_client(sel_source->resource);
751    if (e_comp_wl->selection.cbhm)
752      cbhm_client = wl_resource_get_client(e_comp_wl->selection.cbhm);
753
754    if ((sel_source) &&
755        (sel_client == source_client) &&
756        (sel_client != cbhm_client) &&
757        (e_comp_wl->selection.serial - serial < UINT32_MAX / 2))
758      {
759         /* TODO: elm_entry is sending too many request on now,
760          * for those requests, selection.signal is being emitted also a lot.
761          * when it completes to optimize the entry, it should be checked more.
762          */
763         if (e_comp_wl->clipboard.source)
764           wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
765
766         return;
767      }
768
769    if (sel_source)
770      {
771         if (!e_comp_wl->clipboard.xwl_owner)
772           wl_list_remove(&e_comp_wl->selection.data_source_listener.link);
773         if (sel_source->cancelled)
774           sel_source->cancelled(sel_source);
775         e_comp_wl->selection.data_source = NULL;
776      }
777
778    e_comp_wl->selection.data_source = sel_source = source;
779    e_comp_wl->clipboard.xwl_owner = NULL;
780    e_comp_wl->selection.serial = serial;
781
782    if (e_comp_input_key->kbd.enabled)
783      focus = e_comp_input_key->kbd.focus;
784
785    //if source is from cbhm_client do not create data offer for cbhm
786    if ((cbhm_client) && (source_client != cbhm_client))
787      {
788         data_device_res = e_comp_wl_data_find_for_client(cbhm_client);
789         if ((data_device_res) && (source))
790           {
791              offer_res = _e_comp_wl_data_device_data_offer_create(source, data_device_res);
792              wl_data_device_send_selection(data_device_res, offer_res);
793
794              if (_e_comp_wl_data_secondary_res_check(source->resource) == EINA_TRUE)
795                e_comp_wl->selection.secondary_sent = source->resource;
796           }
797      }
798    else
799      {
800         /* send wl_data_device@selection to secondary selection client */
801         if (e_comp_wl->selection.secondary_list != NULL)
802           _e_comp_wl_data_secondary_send(source);
803
804         /* send wl_data_device@selection to focused client */
805         if (focus)
806           {
807              data_device_res =  e_comp_wl_data_find_for_client(wl_resource_get_client(focus));
808              if ((data_device_res) && (source))
809                {
810                   offer_res =
811                      _e_comp_wl_data_device_data_offer_create(source,
812                                                               data_device_res);
813                   wl_data_device_send_selection(data_device_res, offer_res);
814
815                }
816              else if (data_device_res)
817                wl_data_device_send_selection(data_device_res, NULL);
818           }
819
820         /* send wl_data_device@selection to data only clients
821          * because they won't be focused at all
822          */
823         if (e_comp_wl->selection.data_only_list)
824           {
825              struct wl_resource *data_only;
826              Eina_List *l;
827
828              EINA_LIST_FOREACH(e_comp_wl->selection.data_only_list, l, data_only)
829                {
830                   if (source)
831                     {
832                        offer_res =
833                           _e_comp_wl_data_device_data_offer_create(source,
834                                                                    data_only);
835                        wl_data_device_send_selection(data_only, offer_res);
836                     }
837                   else
838                     wl_data_device_send_selection(data_only, NULL);
839                }
840           }
841      }
842
843    wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
844
845    if (source)
846      {
847         e_comp_wl->selection.data_source_listener.notify =
848           _e_comp_wl_data_device_destroy_selection_data_source;
849         wl_signal_add(&source->destroy_signal,
850                       &e_comp_wl->selection.data_source_listener);
851      }
852 }
853
854 static void
855 _e_comp_wl_data_device_drag_finished(E_Drag *drag, E_Dnd_Drop_Type type)
856 {
857    Evas_Object *o;
858
859    o = edje_object_part_swallow_get(drag->comp_object, "e.swallow.content");
860    if (eina_streq(evas_object_type_get(o), "e_comp_object"))
861      edje_object_part_unswallow(drag->comp_object, o);
862    evas_object_hide(o);
863    evas_object_pass_events_set(o, 1);
864
865    if (e_comp_wl->drag != drag) return;
866
867    e_comp_wl->drag = NULL;
868
869    if (e_comp_wl->drag_client->visible)
870      {
871         e_comp_wl->drag_client->changes.visible = 1;
872         e_comp_wl->drag_client->visible = 0;
873         EC_CHANGED(e_comp_wl->drag_client);
874      }
875    e_comp_wl->drag_client = NULL;
876
877    e_comp_override_del();
878    if (e_comp_wl->selection.target)
879      {
880         struct wl_resource *res = NULL;
881         E_Comp_Wl_Data_Source *drag_source;
882         struct wl_resource *surface = e_comp_wl_client_surface_get(e_comp_wl->selection.target);
883         if (surface)
884           res = e_comp_wl_data_find_for_client(wl_resource_get_client(surface));
885
886         if (res)
887           {
888              drag_source = e_comp_wl->drag_source;
889
890              if (drag_source)
891                {
892                   if ((drag_source->accepted) &&
893                       (drag_source->current_dnd_action) &&
894                       (type == E_DND_DRAG_TYPE_DROPPED))
895                     {
896                        wl_data_device_send_drop(res);
897                        if (wl_resource_get_version(drag_source->resource) >= WL_DATA_SOURCE_DND_DROP_PERFORMED_SINCE_VERSION)
898                          wl_data_source_send_dnd_drop_performed(drag_source->resource);
899                        ((E_Comp_Wl_Data_Offer*)e_comp_wl->drag_offer)->in_ask = drag_source->current_dnd_action ==
900                            WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
901                     }
902                   else if(wl_resource_get_version(drag_source->resource) >= WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
903                     _e_comp_wl_data_source_cancelled_send(drag_source);
904                }
905              wl_data_device_send_leave(res);
906           }
907         e_comp_wl->selection.target = NULL;
908         e_comp_wl->drag_source = NULL;
909
910         if (e_comp_wl->drag_offer)
911           ((E_Comp_Wl_Data_Offer*)e_comp_wl->drag_offer)->dropped = EINA_TRUE;
912      }
913
914    e_comp_wl_data_current_device_id_set(-1);
915 }
916
917 static void
918 _e_comp_wl_data_device_cb_drag_start(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, struct wl_resource *source_resource, struct wl_resource *origin_resource, struct wl_resource *icon_resource, uint32_t serial)
919 {
920    E_Comp_Wl_Data_Source *source;
921    Eina_List *l;
922    struct wl_resource *res;
923    E_Client *drag_icon_ec = NULL, *ec = NULL;
924    E_Client *ec_under_pointer = NULL;
925    E_Desk *desk;
926    int x, y;
927
928    DBG("Data Device Drag Start");
929
930    if (e_comp_wl->drag)
931      {
932         ERR("Drag already in progress");
933         return;
934      }
935
936    if (!(source = wl_resource_get_user_data(source_resource)))
937      return;
938
939    e_comp_wl->drag_source = source;
940
941    if (icon_resource)
942      {
943         DBG("\tHave Icon Resource: %p", icon_resource);
944         drag_icon_ec = e_client_from_surface_resource(icon_resource);
945         if (drag_icon_ec && !drag_icon_ec->re_manage)
946           {
947              drag_icon_ec->re_manage = 1;
948              drag_icon_ec->new_client = 1;
949
950              drag_icon_ec->lock_focus_out = drag_icon_ec->override = 1;
951              drag_icon_ec->icccm.title = eina_stringshare_add("noshadow");
952              e_client_layer_set(drag_icon_ec, E_LAYER_CLIENT_DRAG);
953              drag_icon_ec->netwm.type = E_WINDOW_TYPE_DND;
954              EC_CHANGED(drag_icon_ec);
955              e_comp_override_add();
956           }
957         e_comp_wl->drag_client = drag_icon_ec;
958      }
959
960    ec = e_client_from_surface_resource(origin_resource);
961    if (ec && ec->pointer_enter_sent)
962      {
963         EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
964           {
965              if (!e_comp_wl_input_pointer_check(res)) continue;
966              if (wl_resource_get_client(res) != client) continue;
967              if (!ec->comp_data) continue;
968
969              wl_pointer_send_leave(res, serial, e_comp_wl_client_surface_get(ec));
970           }
971
972         ec->pointer_enter_sent = EINA_FALSE;
973      }
974
975    evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
976    e_comp_wl->drag = e_drag_new(x, y, _e_comp_wl_data_device_drag_finished);
977    e_comp_wl->drag->button_mask = evas_pointer_button_down_mask_get(e_comp->evas);
978    if (drag_icon_ec)
979      {
980         e_drag_object_set(e_comp_wl->drag, drag_icon_ec->frame);
981         e_drag_reference_point_set(e_comp_wl->drag, drag_icon_ec->x, drag_icon_ec->y);
982         e_drag_resize(e_comp_wl->drag, drag_icon_ec->w, drag_icon_ec->h);
983      }
984    e_drag_start(e_comp_wl->drag, x, y);
985
986    desk = e_desk_current_get(e_comp_zone_find_by_ec(ec));
987    ec_under_pointer = e_client_under_position_input_get(desk, x, y);
988    if (ec_under_pointer)
989      e_comp_wl_data_device_send_enter(ec_under_pointer);
990
991    e_comp_canvas_feed_mouse_up(0);
992
993    e_comp_wl_data_current_device_id_set(-1);
994 }
995
996 static void
997 _e_comp_wl_data_device_cb_selection_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *source_resource, uint32_t serial)
998 {
999    E_Comp_Wl_Data_Source *source;
1000
1001    DBG("Data Device Selection Set");
1002    if (!source_resource) return;
1003    if (!(source = wl_resource_get_user_data(source_resource))) return;
1004
1005    _e_comp_wl_data_device_selection_set(e_comp->wl_comp_data, source, serial);
1006 }
1007
1008 static void
1009 _e_comp_wl_data_device_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1010 {
1011    DBG("Data Device Release");
1012    wl_resource_destroy(resource);
1013 }
1014
1015 static const struct wl_data_device_interface _e_data_device_interface =
1016 {
1017    _e_comp_wl_data_device_cb_drag_start,
1018    _e_comp_wl_data_device_cb_selection_set,
1019    _e_comp_wl_data_device_cb_release
1020 };
1021
1022 static void
1023 _e_comp_wl_data_device_cb_unbind(struct wl_resource *resource)
1024 {
1025    struct wl_client *wc = wl_resource_get_client(resource);
1026    e_comp_wl->selection.data_only_list =
1027       eina_list_remove(e_comp_wl->selection.data_only_list,
1028                        resource);
1029    eina_hash_del_by_key(e_comp_wl->mgr.data_resources, &wc);
1030 }
1031
1032 static void
1033 _e_comp_wl_data_manager_cb_device_get(struct wl_client *client, struct wl_resource *manager_resource, uint32_t id, struct wl_resource *seat_resource EINA_UNUSED)
1034 {
1035    struct wl_resource *res;
1036
1037    DBG("Data Manager Device Get");
1038
1039
1040    /* try to create the data device resource */
1041    res = wl_resource_create(client, &wl_data_device_interface, 3, id);
1042    if (!res)
1043      {
1044         ERR("Could not create data device resource: %m");
1045         wl_resource_post_no_memory(manager_resource);
1046         return;
1047      }
1048
1049    eina_hash_add(e_comp_wl->mgr.data_resources, &client, res);
1050    wl_resource_set_implementation(res, &_e_data_device_interface, e_comp->wl_comp_data,
1051                                   _e_comp_wl_data_device_cb_unbind);
1052 }
1053
1054 static const struct wl_data_device_manager_interface _e_manager_interface =
1055 {
1056    (void*)e_comp_wl_data_manager_source_create,
1057    _e_comp_wl_data_manager_cb_device_get
1058 };
1059
1060 static void
1061 _e_comp_wl_data_cb_bind_manager(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id)
1062 {
1063    struct wl_resource *res;
1064
1065    /* try to create data manager resource */
1066    e_comp_wl->mgr.resource = res = wl_resource_create(client, &wl_data_device_manager_interface, 3, id);
1067    if (!res)
1068      {
1069         ERR("Could not create data device manager: %m");
1070         wl_client_post_no_memory(client);
1071         return;
1072      }
1073
1074    wl_resource_set_implementation(res, &_e_manager_interface,
1075                                   e_comp->wl_comp_data, NULL);
1076 }
1077
1078 static Eina_Bool
1079 _e_comp_wl_clipboard_offer_load(void *data, Ecore_Fd_Handler *handler)
1080 {
1081    E_Comp_Wl_Clipboard_Offer *offer;
1082    char *p;
1083    size_t size;
1084    int len;
1085    int fd;
1086
1087    if (!(offer = (E_Comp_Wl_Clipboard_Offer*)data))
1088      return ECORE_CALLBACK_CANCEL;
1089
1090    fd = ecore_main_fd_handler_fd_get(handler);
1091    if (fd < 0) return ECORE_CALLBACK_RENEW;
1092
1093    size = offer->source->contents.size;
1094    p = (char *)offer->source->contents.data;
1095    len = write(fd, p + offer->offset, size - offer->offset);
1096    if (len > 0) offer->offset += len;
1097    else if (len == -1)
1098      ERR("Could not write for fd(%d) :%m", fd);
1099
1100    if ((offer->offset == size) || (len <= 0))
1101      {
1102         close(fd);
1103         ecore_main_fd_handler_del(handler);
1104         if (!e_comp_wl_clipboard_source_unref(offer->source))
1105           {
1106              if (e_comp_wl->clipboard.source == offer->source)
1107                e_comp_wl->clipboard.source = NULL;
1108           }
1109         free(offer);
1110      }
1111
1112    return ECORE_CALLBACK_RENEW;
1113 }
1114
1115 static void
1116 _e_comp_wl_clipboard_offer_create(E_Comp_Wl_Clipboard_Source* source, int fd)
1117 {
1118    E_Comp_Wl_Clipboard_Offer *offer;
1119
1120    offer = E_NEW(E_Comp_Wl_Clipboard_Offer, 1);
1121    if (!offer) return;
1122
1123    offer->offset = 0;
1124    offer->source = source;
1125
1126    e_comp_wl_clipboard_source_ref(source);
1127
1128    offer->fd_handler =
1129       ecore_main_fd_handler_add(fd, ECORE_FD_WRITE,
1130                                 _e_comp_wl_clipboard_offer_load, offer,
1131                                 NULL, NULL);
1132 }
1133
1134 static Eina_Bool
1135 _e_comp_wl_clipboard_source_save(void *data EINA_UNUSED, Ecore_Fd_Handler *handler)
1136 {
1137    E_Comp_Wl_Clipboard_Source *source;
1138    char *p;
1139    int len, size;
1140
1141
1142    if (!(source = (E_Comp_Wl_Clipboard_Source*)e_comp_wl->clipboard.source))
1143      return ECORE_CALLBACK_CANCEL;
1144
1145    /* allocate contents of array */
1146    if (source->contents.alloc < CLIPBOARD_CHUNK)
1147      wl_array_add(&source->contents, CLIPBOARD_CHUNK);
1148
1149    source->contents.size = 0;
1150    p = (char *)source->contents.data;
1151    size = source->contents.alloc;
1152
1153    while ((len = read(source->fd[0], p, size)))
1154      {
1155         if (len == -1) break;
1156
1157         source->contents.size += len;
1158
1159         //if the array is full
1160         if (len >= size)
1161           wl_array_add(&source->contents, CLIPBOARD_CHUNK);
1162         else
1163           break;
1164
1165         p = (char *)source->contents.data + source->contents.size;
1166         size = source->contents.alloc - source->contents.size;
1167      }
1168
1169    if ((len < 0) && (source->contents.size == 0))
1170      {
1171         ERR("Could not read fd(%d): %m", source->fd[0]);
1172         if (!(e_comp_wl_clipboard_source_unref(source)))
1173           e_comp_wl->clipboard.source = NULL;
1174      }
1175
1176    return ECORE_CALLBACK_RENEW;
1177 }
1178
1179 static void
1180 _e_comp_wl_clipboard_source_target_send(E_Comp_Wl_Data_Source *source EINA_UNUSED, uint32_t serial EINA_UNUSED, const char *mime_type EINA_UNUSED)
1181 {
1182 }
1183
1184 static void
1185 _e_comp_wl_clipboard_source_send_send(E_Comp_Wl_Data_Source *source, const char *mime_type, int fd)
1186 {
1187    E_Comp_Wl_Clipboard_Source* clip_source;
1188    char *t;
1189
1190    clip_source = container_of(source, E_Comp_Wl_Clipboard_Source, data_source);
1191    if (!clip_source) return;
1192
1193    t = eina_array_data_get(source->mime_types, 0);
1194    if ((t) && (!strcmp(mime_type, t)))
1195      _e_comp_wl_clipboard_offer_create(clip_source, fd);
1196    else
1197      close(fd);
1198 }
1199
1200 static void
1201 _e_comp_wl_clipboard_source_cancelled_send(E_Comp_Wl_Data_Source *source EINA_UNUSED)
1202 {
1203 }
1204
1205 static void
1206 _e_comp_wl_clipboard_selection_set(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
1207 {
1208    E_Comp_Wl_Data_Source *sel_source;
1209    E_Comp_Wl_Clipboard_Source *clip_source;
1210    int p[2];
1211    char *mime_type;
1212
1213    sel_source = (E_Comp_Wl_Data_Source*) e_comp_wl->selection.data_source;
1214    clip_source = (E_Comp_Wl_Clipboard_Source*) e_comp_wl->clipboard.source;
1215
1216    if (!sel_source)
1217      {
1218         if (clip_source)
1219           _e_comp_wl_data_device_selection_set(e_comp->wl_comp_data,
1220                                                &clip_source->data_source,
1221                                                clip_source->serial);
1222         return;
1223      }
1224    else if (sel_source->target == _e_comp_wl_clipboard_source_target_send)
1225      return;
1226
1227    mime_type = eina_array_data_get(sel_source->mime_types, 0);
1228
1229    if (!clip_source)
1230      {
1231         /* create unidirectional pipe for clipboard source with below flags.
1232          * O_CLOEXEC : to avoid race condition
1233          * O_DIRECT  : enable 'packet' mode, each write of write end pipe will
1234          *             be read separately on read end pipe. It makes clipboard
1235          *             avoid saving duplicated data.
1236          * O_NONBLOCK: to avoid blocking of no data to read
1237          */
1238         if (pipe2(p, O_CLOEXEC|O_DIRECT|O_NONBLOCK) == -1)
1239           {
1240              ERR("Could not create unidirectional pipe for clipboard: %m");
1241              return;
1242           }
1243
1244         sel_source->send(sel_source, mime_type, p[1]);
1245
1246         e_comp_wl->clipboard.source =
1247            e_comp_wl_clipboard_source_create(mime_type,
1248                                              e_comp_wl->selection.serial, p);
1249         if (!e_comp_wl->clipboard.source)
1250           {
1251              close(p[0]);
1252              close(p[1]);
1253           }
1254      }
1255    else
1256      {
1257         if (clip_source->fd[1] == -1)
1258           {
1259              ERR("clipboard fd is invalid");
1260              return;
1261           }
1262         sel_source->send(sel_source, mime_type, clip_source->fd[1]);
1263      }
1264 }
1265
1266 static void
1267 _e_comp_wl_clipboard_create(void)
1268 {
1269    e_comp_wl->clipboard.listener.notify = _e_comp_wl_clipboard_selection_set;
1270    wl_signal_add(&e_comp_wl->selection.signal, &e_comp_wl->clipboard.listener);
1271 }
1272
1273 static void
1274 _e_comp_wl_data_device_target_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1275 {
1276    E_Client *ec = data;
1277
1278    if (e_comp_wl->selection.target == ec)
1279      e_comp_wl->selection.target = NULL;
1280 }
1281
1282 EINTERN void
1283 e_comp_wl_data_device_send_enter(E_Client *ec)
1284 {
1285    struct wl_resource *data_device_res, *offer_res;
1286    uint32_t serial;
1287    int x, y;
1288
1289    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1290    if (!surface) return;
1291
1292    data_device_res =
1293        e_comp_wl_data_find_for_client(wl_resource_get_client(surface));
1294
1295    if (!data_device_res) return;
1296    offer_res = e_comp_wl_data_device_send_offer(ec);
1297    if (e_comp_wl->drag_source)
1298      {
1299         E_Comp_Wl_Data_Source *drag_source = e_comp_wl->drag_source;
1300         E_Comp_Wl_Data_Offer *new_offer;
1301         E_Comp_Wl_Data_Offer *old_offer = e_comp_wl->drag_offer;
1302
1303         if (!offer_res) return;
1304
1305         if (old_offer &&
1306             (old_offer->source == drag_source))
1307           {
1308              old_offer->dropped = EINA_FALSE;
1309              old_offer->source = NULL;
1310           }
1311         drag_source->accepted = EINA_FALSE;
1312
1313         new_offer = wl_resource_get_user_data(offer_res);
1314         e_comp_wl->drag_offer = new_offer;
1315         if (new_offer)
1316           {
1317              _e_comp_wl_data_offer_update_action(new_offer);
1318              if (wl_resource_get_version(offer_res) >= WL_DATA_OFFER_SOURCE_ACTIONS_SINCE_VERSION)
1319                wl_data_offer_send_source_actions(offer_res, new_offer->source->dnd_actions);
1320           }
1321      }
1322
1323    e_comp_wl->selection.target = ec;
1324    evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_DEL, _e_comp_wl_data_device_target_del, ec);
1325
1326    if (e_client_transform_core_enable_get(ec))
1327      {
1328         int trans_x, trans_y;
1329         e_client_transform_core_input_transform(ec, wl_fixed_to_int(e_comp_wl->ptr.x), wl_fixed_to_int(e_comp_wl->ptr.y), &trans_x, &trans_y);
1330         x = trans_x - ec->client.x;
1331         y = trans_y - ec->client.y;
1332      }
1333    else
1334      {
1335         int ec_x, ec_y;
1336         e_client_geometry_get(ec, &ec_x, &ec_y, NULL, NULL);
1337         x = wl_fixed_to_int(e_comp_wl->ptr.x) - ec_x;
1338         y = wl_fixed_to_int(e_comp_wl->ptr.y) - ec_y;
1339      }
1340
1341    serial = wl_display_next_serial(e_comp_wl->wl.disp);
1342    wl_data_device_send_enter(data_device_res, serial, surface,
1343                              wl_fixed_from_int(x), wl_fixed_from_int(y), offer_res);
1344 }
1345
1346 EINTERN void
1347 e_comp_wl_data_device_send_leave(E_Client *ec)
1348 {
1349    struct wl_resource *res;
1350
1351    evas_object_event_callback_del_full(ec->frame, EVAS_CALLBACK_DEL, _e_comp_wl_data_device_target_del, ec);
1352    if (e_comp_wl->selection.target == ec)
1353      e_comp_wl->selection.target = NULL;
1354    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1355    if (!surface) return;
1356
1357    res = e_comp_wl_data_find_for_client(wl_resource_get_client(surface));
1358    if (res)
1359      wl_data_device_send_leave(res);
1360 }
1361
1362 EINTERN void *
1363 e_comp_wl_data_device_send_offer(E_Client *ec)
1364 {
1365    struct wl_resource *data_device_res, *offer_res = NULL;
1366    E_Comp_Wl_Data_Source *source;
1367
1368    struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1369    if (!surface) return NULL;
1370
1371    data_device_res =
1372       e_comp_wl_data_find_for_client(wl_resource_get_client(surface));
1373    if (!data_device_res) return NULL;
1374    source = e_comp_wl->drag_source;
1375    if (source)
1376      offer_res = _e_comp_wl_data_device_data_offer_create(source, data_device_res);
1377    return offer_res;
1378 }
1379
1380 EINTERN void
1381 e_comp_wl_data_device_keyboard_focus_set(void)
1382 {
1383    struct wl_resource *data_device_res, *offer_res = NULL, *focus;
1384    E_Comp_Wl_Data_Source *source;
1385
1386    if (!e_comp_input_key->kbd.enabled)
1387      {
1388         ERR("Keyboard not enabled");
1389         return;
1390      }
1391
1392    if (!(focus = e_comp_input_key->kbd.focus))
1393      {
1394         ERR("No focused resource");
1395         return;
1396      }
1397    source = (E_Comp_Wl_Data_Source*)e_comp_wl->selection.data_source;
1398
1399    data_device_res =
1400       e_comp_wl_data_find_for_client(wl_resource_get_client(focus));
1401    if (!data_device_res) return;
1402
1403    /* to remove from data_only_list if it is on the list */
1404    e_comp_wl->selection.data_only_list =
1405       eina_list_remove(e_comp_wl->selection.data_only_list,
1406                        data_device_res);
1407
1408    if (source && !source->is_manual)
1409      {
1410         offer_res =
1411            _e_comp_wl_data_device_data_offer_create(source, data_device_res);
1412      }
1413    wl_data_device_send_selection(data_device_res, offer_res);
1414 }
1415
1416 EINTERN Eina_Bool
1417 e_comp_wl_data_manager_init(void)
1418 {
1419    /* try to create global data manager */
1420    e_comp_wl->mgr.global =
1421        wl_global_create(e_comp_wl->wl.disp, &wl_data_device_manager_interface, 3,
1422                         e_comp->wl_comp_data, _e_comp_wl_data_cb_bind_manager);
1423    if (!e_comp_wl->mgr.global)
1424      {
1425         ERR("Could not create global for data device manager: %m");
1426         return EINA_FALSE;
1427      }
1428
1429    wl_signal_init(&e_comp_wl->selection.signal);
1430
1431    /* create clipboard */
1432    _e_comp_wl_clipboard_create();
1433    e_comp_wl->mgr.data_resources = eina_hash_pointer_new(NULL);
1434
1435    return EINA_TRUE;
1436 }
1437
1438 EINTERN void
1439 e_comp_wl_data_manager_shutdown(void)
1440 {
1441    /* destroy the global manager resource */
1442    /* if (e_comp_wl->mgr.global) wl_global_destroy(e_comp_wl->mgr.global); */
1443
1444    wl_list_remove(&e_comp_wl->clipboard.listener.link);
1445    E_FREE_FUNC(e_comp_wl->mgr.data_resources, eina_hash_free);
1446 }
1447
1448 EINTERN struct wl_resource *
1449 e_comp_wl_data_find_for_client(struct wl_client *client)
1450 {
1451    return eina_hash_find(e_comp_wl->mgr.data_resources, &client);
1452 }
1453
1454 EINTERN E_Comp_Wl_Data_Source *
1455 e_comp_wl_data_manager_source_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
1456 {
1457    E_Comp_Wl_Data_Source *source;
1458
1459    DBG("Data Manager Source Create");
1460
1461    source = E_NEW(E_Comp_Wl_Data_Source, 1);
1462    if (!source)
1463      {
1464         wl_resource_post_no_memory(resource);
1465         return NULL;
1466      }
1467
1468    wl_signal_init(&source->destroy_signal);
1469    source->target = _e_comp_wl_data_source_target_send;
1470    source->send = _e_comp_wl_data_source_send_send;
1471    source->cancelled = _e_comp_wl_data_source_cancelled_send;
1472
1473    source->resource =
1474        wl_resource_create(client, &wl_data_source_interface, 3, id);
1475    if (!source->resource)
1476      {
1477         ERR("Could not create data source resource: %m");
1478         free(source);
1479         wl_resource_post_no_memory(resource);
1480         return NULL;
1481      }
1482
1483    wl_resource_set_implementation(source->resource,
1484                                   &_e_data_source_interface, source,
1485                                   _e_comp_wl_data_source_cb_resource_destroy);
1486    return source;
1487 }
1488
1489 EINTERN E_Comp_Wl_Clipboard_Source *
1490 e_comp_wl_clipboard_source_create(const char *mime_type, uint32_t serial, int *fd)
1491 {
1492    E_Comp_Wl_Clipboard_Source *source;
1493
1494    source = E_NEW(E_Comp_Wl_Clipboard_Source, 1);
1495    if (!source) return NULL;
1496
1497    source->fd[0] = source->fd[1] = -1;
1498    source->data_source.resource = NULL;
1499    source->data_source.target = _e_comp_wl_clipboard_source_target_send;
1500    source->data_source.send = _e_comp_wl_clipboard_source_send_send;
1501    source->data_source.cancelled = _e_comp_wl_clipboard_source_cancelled_send;
1502
1503    wl_array_init(&source->contents);
1504    wl_signal_init(&source->data_source.destroy_signal);
1505
1506    source->ref = 1;
1507    source->serial = serial;
1508
1509    if (mime_type)
1510      {
1511         if (!source->data_source.mime_types)
1512           source->data_source.mime_types = eina_array_new(1);
1513
1514         if (source->data_source.mime_types == NULL)
1515           {
1516              E_FREE(source);
1517              return NULL;
1518           }
1519
1520         eina_array_push(source->data_source.mime_types, eina_stringshare_add(mime_type));
1521      }
1522
1523    if ((fd[0] >= 0) && (fd[1] >= 0))
1524      {
1525         source->fd_handler =
1526            ecore_main_fd_handler_add(fd[0], ECORE_FD_READ,
1527                                      _e_comp_wl_clipboard_source_save,
1528                                      e_comp->wl_comp_data, NULL, NULL);
1529         if (!source->fd_handler)
1530           {
1531              E_FREE(source);
1532              return NULL;
1533           }
1534      }
1535    else
1536      {
1537         E_FREE(source);
1538         return NULL;
1539      }
1540
1541    source->fd[0] = fd[0];
1542    source->fd[1] = fd[1];
1543
1544    return source;
1545 }
1546
1547 EINTERN int
1548 e_comp_wl_clipboard_source_ref(E_Comp_Wl_Clipboard_Source *source)
1549 {
1550    source->ref ++;
1551    return source->ref;
1552 }
1553
1554 EINTERN int
1555 e_comp_wl_clipboard_source_unref(E_Comp_Wl_Clipboard_Source *source)
1556 {
1557    EINA_SAFETY_ON_NULL_RETURN_VAL(source, 0);
1558    source->ref--;
1559    if (source->ref > 0)
1560      return source->ref;
1561
1562    if (source->fd_handler)
1563      {
1564         ecore_main_fd_handler_del(source->fd_handler);
1565         close(source->fd[0]);
1566         close(source->fd[1]);
1567      }
1568
1569    _mime_types_free(&source->data_source);
1570
1571    wl_signal_emit(&source->data_source.destroy_signal, &source->data_source);
1572    wl_array_release(&source->contents);
1573    free(source);
1574
1575    return 0;
1576 }
1577
1578 EINTERN void
1579 e_comp_wl_data_device_only_set(struct wl_resource *data_device_res, Eina_Bool set)
1580 {
1581    struct wl_resource *offer_res = NULL, *focus;
1582    E_Comp_Wl_Data_Source *source;
1583
1584    EINA_SAFETY_ON_NULL_RETURN(data_device_res);
1585
1586    if (set)
1587      {
1588         if (eina_list_data_find(e_comp_wl->selection.data_only_list, data_device_res))
1589           return;
1590
1591         e_comp_wl->selection.data_only_list =
1592            eina_list_append(e_comp_wl->selection.data_only_list, data_device_res);
1593
1594         source = (E_Comp_Wl_Data_Source *)e_comp_wl->selection.data_source;
1595         if (source && !source->is_manual)
1596           {
1597              offer_res =
1598                 _e_comp_wl_data_device_data_offer_create(source, data_device_res);
1599           }
1600         wl_data_device_send_selection(data_device_res, offer_res);
1601      }
1602    else
1603      {
1604         e_comp_wl->selection.data_only_list =
1605            eina_list_remove(e_comp_wl->selection.data_only_list, data_device_res);
1606
1607         focus = e_comp_input_key->kbd.focus;
1608         if ((!focus) ||
1609             (wl_resource_get_client(focus) != wl_resource_get_client(data_device_res)))
1610           {
1611              wl_data_device_send_selection(data_device_res, NULL);
1612           }
1613      }
1614 }
1615
1616 static void
1617 _e_comp_wl_data_device_destroy_manual_source(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
1618 {
1619   struct wl_resource *data_device_res = NULL;
1620   struct wl_client *cbhm_client = NULL;
1621
1622   e_comp_wl->selection.data_source = NULL;
1623
1624   if (e_comp_wl->selection.cbhm)
1625      cbhm_client =  wl_resource_get_client(e_comp_wl->selection.cbhm);
1626
1627    if (cbhm_client)
1628      {
1629         data_device_res =
1630            e_comp_wl_data_find_for_client(cbhm_client);
1631
1632         if (data_device_res)
1633           wl_data_device_send_selection(data_device_res, NULL);
1634      }
1635 }
1636
1637 static int
1638 _e_comp_wl_manual_source_ref(E_Comp_Wl_Manual_Data_Source *source)
1639 {
1640    source->ref ++;
1641    return source->ref;
1642 }
1643
1644 static int
1645 _e_comp_wl_manual_source_unref(E_Comp_Wl_Manual_Data_Source *source)
1646 {
1647    EINA_SAFETY_ON_NULL_RETURN_VAL(source, 0);
1648    source->ref --;
1649    if (source->ref > 0)
1650      return source->ref;
1651
1652    _mime_types_free(&source->data_source);
1653
1654    wl_signal_emit(&source->data_source.destroy_signal, &source->data_source);
1655    wl_array_release(&source->contents);
1656    free(source);
1657
1658    return 0;
1659 }
1660
1661 static void
1662 _e_comp_wl_manual_offer_load(E_Comp_Wl_Manual_Data_Source *source, int fd)
1663 {
1664    char *p;
1665    size_t size;
1666    int len;
1667    int offset = 0;
1668
1669    size = source->contents.size;
1670    p = (char *)source->contents.data;
1671    len = write(fd, p, size);
1672    if (len > 0) offset += len;
1673    else if (len == -1)
1674      ERR("could not write for fd(%d) :%m", fd);
1675
1676    if (len <= 0)
1677      {
1678         _e_comp_wl_manual_source_unref(source);
1679      }
1680 }
1681
1682 static void
1683 _e_comp_wl_manual_source_target_send(E_Comp_Wl_Data_Source *source EINA_UNUSED, uint32_t serial EINA_UNUSED, const char *mime_type EINA_UNUSED)
1684 {
1685 }
1686
1687 static void
1688 _e_comp_wl_manual_source_send_send(E_Comp_Wl_Data_Source *source, const char *mime_type, int fd)
1689 {
1690    E_Comp_Wl_Manual_Data_Source *man_source;
1691
1692    man_source = container_of(source, E_Comp_Wl_Manual_Data_Source, data_source);
1693    if (!man_source) return;
1694
1695    _e_comp_wl_manual_offer_load(man_source, fd);
1696    close(fd);
1697 }
1698
1699 static void
1700 _e_comp_wl_manual_source_cancelled_send(E_Comp_Wl_Data_Source *source EINA_UNUSED)
1701 {
1702    E_Comp_Wl_Manual_Data_Source *man_source;
1703
1704    man_source = container_of(source, E_Comp_Wl_Manual_Data_Source, data_source);
1705    if (!man_source) return;
1706
1707    _e_comp_wl_manual_source_unref(man_source);
1708 }
1709
1710 static void
1711 _e_comp_wl_data_device_manual_selection_set(E_Comp_Wl_Data_Source *source, uint32_t serial)
1712 {
1713    E_Comp_Wl_Data_Source *sel_source;
1714    struct wl_resource *offer_res, *data_device_res;
1715    struct wl_client *cbhm_client = NULL;
1716
1717    sel_source = (E_Comp_Wl_Data_Source*)e_comp_wl->selection.data_source;
1718
1719    if (e_comp_wl->selection.cbhm)
1720      cbhm_client = wl_resource_get_client(e_comp_wl->selection.cbhm);
1721
1722    if (sel_source)
1723      {
1724         if (!e_comp_wl->clipboard.xwl_owner)
1725           wl_list_remove(&e_comp_wl->selection.data_source_listener.link);
1726         if (sel_source->cancelled)
1727           sel_source->cancelled(sel_source);
1728         e_comp_wl->selection.data_source = NULL;
1729      }
1730
1731    e_comp_wl->selection.data_source = sel_source = source;
1732    e_comp_wl->clipboard.xwl_owner = NULL;
1733    e_comp_wl->selection.serial = serial;
1734
1735    if (cbhm_client)
1736      {
1737         data_device_res =
1738            e_comp_wl_data_find_for_client(cbhm_client);
1739         if ((data_device_res) && (source))
1740           {
1741              offer_res =
1742                 _e_comp_wl_data_device_data_offer_create(source,
1743                                                          data_device_res);
1744              wl_data_device_send_selection(data_device_res, offer_res);
1745           }
1746      }
1747
1748    //do not notify to internal clipboard
1749    //wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
1750
1751    if (source)
1752      {
1753         e_comp_wl->selection.data_source_listener.notify =
1754            _e_comp_wl_data_device_destroy_manual_source;
1755         wl_signal_add(&source->destroy_signal,
1756                       &e_comp_wl->selection.data_source_listener);
1757      }
1758 }
1759
1760 EINTERN Eina_Bool
1761 e_comp_wl_data_device_manual_selection_set(void *data, size_t size, Eina_List *mime_list)
1762 {
1763    E_Comp_Wl_Manual_Data_Source *man_source;
1764    Eina_List *l;
1765    const char *t;
1766
1767    if ((size <= 0) || (!data) || (!mime_list)) return EINA_FALSE;
1768
1769    man_source = E_NEW(E_Comp_Wl_Manual_Data_Source, 1);
1770    if (!man_source) return EINA_FALSE;
1771
1772    man_source->data_source.resource = NULL;
1773    man_source->data_source.target = _e_comp_wl_manual_source_target_send;
1774    man_source->data_source.send = _e_comp_wl_manual_source_send_send;
1775    man_source->data_source.cancelled = _e_comp_wl_manual_source_cancelled_send;
1776    man_source->data_source.is_manual = EINA_TRUE;
1777
1778    wl_array_init(&man_source->contents);
1779    wl_signal_init(&man_source->data_source.destroy_signal);
1780
1781    man_source->serial = e_comp_wl->selection.serial;
1782
1783    if (!man_source->data_source.mime_types)
1784      man_source->data_source.mime_types = eina_array_new(64);
1785
1786    if (man_source->data_source.mime_types == NULL)
1787      {
1788         wl_array_release(&man_source->contents);
1789         E_FREE(man_source);
1790         return EINA_FALSE;
1791      }
1792
1793    EINA_LIST_FOREACH(mime_list, l, t)
1794       eina_array_push(man_source->data_source.mime_types, eina_stringshare_add(t));
1795
1796    if (man_source->contents.alloc < size)
1797      wl_array_add(&man_source->contents, size);
1798    man_source->contents.size = size;
1799    memcpy(man_source->contents.data, data, size);
1800
1801    _e_comp_wl_manual_source_ref(man_source);
1802    _e_comp_wl_data_device_manual_selection_set(&man_source->data_source, man_source->serial);
1803    return EINA_TRUE;
1804 }
1805
1806 EINTERN void
1807 e_comp_wl_data_current_device_id_set(int id)
1808 {
1809    e_comp_wl->drag_device_id = id;
1810 }
1811
1812 EINTERN int
1813 e_comp_wl_data_current_device_id_get(void)
1814 {
1815    return e_comp_wl->drag_device_id;
1816 }
1817
1818 EINTERN void
1819 e_comp_wl_data_offer_mimetype_action_accept(E_Comp_Wl_Data_Offer *offer)
1820 {
1821    E_Comp_Wl_Data_Source *source;
1822
1823    if (!offer) return;
1824
1825    source = offer->source;
1826    if (!source) return;
1827
1828    // set all mime type to accepted
1829    if (source->mime_types)
1830      source->target(source, 0, eina_array_pop(source->mime_types));
1831    source->accepted = EINA_TRUE;
1832
1833    // set all actions to accepted
1834    offer->dnd_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
1835    offer->preferred_dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
1836    _e_comp_wl_data_offer_update_action(offer);
1837 }
1838
1839 static Eina_Bool
1840 _e_comp_wl_data_secondary_list_check(E_Client *ec)
1841 {
1842    E_Client *tmp;
1843    Eina_List *l;
1844
1845    if (e_comp_wl->selection.secondary_list == NULL)
1846      return EINA_FALSE;
1847
1848    EINA_LIST_FOREACH(e_comp_wl->selection.secondary_list, l, tmp)
1849      {
1850         if (tmp == ec)
1851           return EINA_TRUE;
1852      }
1853
1854    return EINA_FALSE;
1855 }
1856
1857 EINTERN void
1858 e_comp_wl_data_secondary_add(E_Client *ec)
1859 {
1860    EINA_SAFETY_ON_NULL_RETURN(ec);
1861
1862    if (_e_comp_wl_data_secondary_list_check(ec) == EINA_TRUE)
1863      return;
1864
1865    e_comp_wl->selection.secondary_list = eina_list_append(e_comp_wl->selection.secondary_list, ec);
1866    DBG("add secondary %s(%p). listcount(%d)",
1867        e_client_util_name_get(ec), ec, eina_list_count(e_comp_wl->selection.secondary_list));
1868 }
1869
1870 EINTERN void
1871 e_comp_wl_data_secondary_remove(E_Client *ec)
1872 {
1873    EINA_SAFETY_ON_NULL_RETURN(ec);
1874
1875    if (_e_comp_wl_data_secondary_list_check(ec) == EINA_FALSE)
1876      return;
1877
1878    e_comp_wl->selection.secondary_list = eina_list_remove(e_comp_wl->selection.secondary_list, ec);
1879    DBG("remove secondary %s(%p). listcount(%d)",
1880        e_client_util_name_get(ec), ec, eina_list_count(e_comp_wl->selection.secondary_list));
1881
1882    if (eina_list_count(e_comp_wl->selection.secondary_list) == 0)
1883      {
1884         eina_list_free(e_comp_wl->selection.secondary_list);
1885         e_comp_wl->selection.secondary_list = NULL;
1886         e_comp_wl->selection.secondary_sent = NULL;
1887      }
1888 }