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"
11 #define EXECUTIVE_MODE_ENABLED
16 } E_Comp_Wl_Thread_Data;
18 static void _e_comp_wl_data_source_cancelled_send(E_Comp_Wl_Data_Source *source);
21 _mime_types_free(E_Comp_Wl_Data_Source *source)
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);
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)
32 E_Comp_Wl_Data_Offer *offer;
34 DBG("Data Offer Accept");
35 if (!(offer = wl_resource_get_user_data(resource)))
38 if (offer->source && e_comp_wl->drag_offer == offer)
40 offer->source->target(offer->source, serial, mime_type);
41 offer->source->accepted = !!mime_type;
46 _e_comp_wl_data_pipe_run(void *data, Ecore_Thread *th)
48 E_Comp_Wl_Thread_Data *td;
50 int read_len = 0, write_len = 0;
51 int retry_position, retry_cnt = 0;
53 if (!(td = data)) return;
55 eina_thread_name_set(eina_thread_self(), "e_comp_wl_data_pipe");
57 if (ecore_thread_check(th)) return;
59 DBG("_e_comp_wl_data_pipe_run. th:%p", th);
61 p = (char *)calloc(sizeof(char), CLIPBOARD_CHUNK);
66 read_len = read(td->src_fd, p, CLIPBOARD_CHUNK);
69 if (errno == EINTR || errno == EAGAIN)
71 DBG("IO error in _e_comp_wl_dnd_offer_mediate READ. try again");
73 if (retry_cnt > 10000)
75 ERR("retry over 10000. break");
82 DBG("IO error in _e_comp_wl_dnd_offer_mediate READ.(%d)", errno);
90 write_len = write(td->dst_fd, p + retry_position, read_len - retry_position);
93 if (errno == EINTR || errno == EAGAIN)
95 DBG("IO error in _e_comp_wl_dnd_offer_mediate WRITE. try again");
100 ERR("IO error in _e_comp_wl_dnd_offer_mediate WRITE.(%d)", errno);
104 else if (read_len - retry_position == write_len)
110 retry_position = read_len - write_len;
115 if (p[read_len - 1] == '\0')
117 DBG("mediate done. read and write done");
128 _e_comp_wl_data_pipe_close(E_Comp_Wl_Thread_Data *td)
137 _e_comp_wl_data_pipe_done(void *data, Ecore_Thread *th)
139 E_Comp_Wl_Thread_Data *td = data;
143 DBG("_e_comp_wl_data_pipe_done. th:%p", th);
145 _e_comp_wl_data_pipe_close(td);
149 _e_comp_wl_data_pipe_cancel(void *data, Ecore_Thread *th)
151 E_Comp_Wl_Thread_Data *td = data;
155 DBG("_e_comp_wl_data_pipe_cancel. th:%p", th);
157 _e_comp_wl_data_pipe_close(td);
161 _e_comp_wl_dnd_offer_mediate(void *data, Ecore_Fd_Handler *handler)
163 E_Comp_Wl_Data_Offer *offer = NULL;
164 E_Comp_Wl_Thread_Data *td;
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);
171 source_fd = ecore_main_fd_handler_fd_get(handler);
172 if (source_fd < 0) goto cleanup;
173 if (offer->fd < 0) goto cleanup;
175 td = E_NEW(E_Comp_Wl_Thread_Data, 1);
176 if (!td) return ECORE_CALLBACK_RENEW;
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,
184 if (offer->th == NULL)
187 ecore_main_fd_handler_del(handler);
188 offer->source->fd_handler = NULL;
190 DBG("create thread for pipe th:%p, src:%d, dst:%d", offer->th, td->src_fd, td->dst_fd);
192 return ECORE_CALLBACK_DONE;
200 if (source_fd > 0) close(source_fd);
201 ecore_main_fd_handler_del(handler);
202 offer->source->fd_handler = NULL;
204 return ECORE_CALLBACK_DONE;
208 _e_comp_wl_dnd_offer_mediator_init(E_Comp_Wl_Data_Offer* offer, int fd)
210 EINA_SAFETY_ON_NULL_RETURN_VAL(offer, -1);
211 EINA_SAFETY_ON_NULL_RETURN_VAL(offer->source, -1);
213 if (pipe2(offer->source->fd, O_CLOEXEC|O_DIRECT|O_NONBLOCK) == -1)
215 ERR("Could not create unidirectional pipe for dnd: %m");
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,
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];
230 _e_comp_wl_data_source_notify_finish(E_Comp_Wl_Data_Source *source)
232 E_Comp_Wl_Data_Offer *drag_offer;
234 if (!source->actions_set)
237 drag_offer = e_comp_wl->drag_offer;
239 if (drag_offer && drag_offer->in_ask &&
240 wl_resource_get_version(source->resource) >= WL_DATA_SOURCE_ACTION_SINCE_VERSION)
242 wl_data_source_send_action(source->resource, source->current_dnd_action);
245 if (wl_resource_get_version(source->resource) >= WL_DATA_SOURCE_DND_FINISHED_SINCE_VERSION)
247 wl_data_source_send_dnd_finished(source->resource);
250 e_comp_wl->drag_offer = NULL;
254 _e_comp_wl_data_offer_choose_action(E_Comp_Wl_Data_Offer *offer)
256 uint32_t available_actions, preferred_action = 0;
257 uint32_t source_actions, offer_actions;
259 EINA_SAFETY_ON_NULL_RETURN_VAL(offer->source, WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE);
261 if (wl_resource_get_version(offer->resource) >= WL_DATA_OFFER_ACTION_SINCE_VERSION)
263 offer_actions = offer->dnd_actions;
264 preferred_action = offer->preferred_dnd_action;
268 offer_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
271 if (wl_resource_get_version(offer->source->resource) >= WL_DATA_SOURCE_ACTION_SINCE_VERSION)
272 source_actions = offer->source->dnd_actions;
274 source_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
276 available_actions = offer_actions & source_actions;
278 if (!available_actions)
279 return WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
281 if (offer->source->compositor_action & available_actions)
282 return offer->source->compositor_action;
284 /* If the dest side has a preferred DnD action, use it */
285 if (preferred_action & available_actions)
286 return preferred_action;
288 /* Use the first found action, in bit order */
289 return 1 << (ffs(available_actions) - 1);
293 _e_comp_wl_data_offer_update_action(E_Comp_Wl_Data_Offer *offer)
297 if (!offer->source || !offer->source->actions_set)
300 action = _e_comp_wl_data_offer_choose_action(offer);
302 if (offer->source->current_dnd_action == action)
305 offer->source->current_dnd_action = action;
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);
313 if (wl_resource_get_version(offer->resource) >= WL_DATA_OFFER_ACTION_SINCE_VERSION)
314 wl_data_offer_send_action(offer->resource, action);
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)
320 E_Comp_Wl_Data_Offer *offer;
323 DBG("Data Offer Receive FD:%d", fd);
325 if (!(offer = wl_resource_get_user_data(resource)))
331 new_fd = _e_comp_wl_dnd_offer_mediator_init(offer, fd);
334 DBG("_e_comp_wl_dnd_offer_mediator_init failed, close fd:%d", fd);
340 offer->source->send(offer->source, mime_type, new_fd);
344 /* called by wl_data_offer_destroy */
346 _e_comp_wl_data_offer_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
348 DBG("Data Offer Destroy");
349 wl_resource_destroy(resource);
352 /* called by wl_resource_destroy */
354 _e_comp_wl_data_offer_cb_resource_destroy(struct wl_resource *resource)
356 E_Comp_Wl_Data_Offer *offer;
358 if (!(offer = wl_resource_get_user_data(resource)))
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);
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);
373 if (offer == e_comp_wl->drag_offer)
374 e_comp_wl->drag_offer = NULL;
376 if ((offer->th != NULL) && !ecore_thread_check(offer->th))
378 ecore_thread_cancel(offer->th);
385 /* called by emission of source->destroy_signal */
387 _e_comp_wl_data_offer_cb_source_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
389 E_Comp_Wl_Data_Offer *offer;
391 DBG("Data Offer Source Destroy");
392 offer = container_of(listener, E_Comp_Wl_Data_Offer,
393 source_destroy_listener);
396 offer->source = NULL;
400 _e_comp_wl_data_offer_cb_finish(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
402 E_Comp_Wl_Data_Offer *offer;
404 DBG("Data Offer finished");
405 if (!(offer = wl_resource_get_user_data(resource)))
408 if (!offer->source || !offer->source->accepted)
410 wl_resource_post_error(offer->resource,
411 WL_DATA_OFFER_ERROR_INVALID_FINISH,
412 "premature finish request");
416 switch (offer->source->current_dnd_action)
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");
427 _e_comp_wl_data_source_notify_finish(offer->source);
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)
433 E_Comp_Wl_Data_Offer *offer;
435 DBG("Data Offer set actions: actions:%u, preferred_action:%u", dnd_actions, preferred_action);
436 if (!(offer = wl_resource_get_user_data(resource)))
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))
443 wl_resource_post_error(offer->resource,
444 WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK,
445 "invalid action mask %x", dnd_actions);
449 if (preferred_action &&
450 (!(preferred_action & dnd_actions) ||
451 __builtin_popcount(preferred_action) > 1))
453 wl_resource_post_error(offer->resource,
454 WL_DATA_OFFER_ERROR_INVALID_ACTION,
455 "invalid action %x", preferred_action);
459 offer->dnd_actions = dnd_actions;
460 offer->preferred_dnd_action = preferred_action;
461 _e_comp_wl_data_offer_update_action(offer);
464 static const struct wl_data_offer_interface _e_data_offer_interface =
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,
474 _e_comp_wl_data_source_cb_offer(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type)
476 E_Comp_Wl_Data_Source *source;
478 DBG("Data Source Offer");
479 if (!(source = wl_resource_get_user_data(resource)))
482 if (!source->mime_types)
483 source->mime_types = eina_array_new(1);
485 EINA_SAFETY_ON_NULL_RETURN(source->mime_types);
487 eina_array_push(source->mime_types, eina_stringshare_add(mime_type));
490 /* called by wl_data_source_destroy */
492 _e_comp_wl_data_source_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
494 DBG("Data Source Destroy");
495 wl_resource_destroy(resource);
498 /* called by wl_resource_destroy */
500 _e_comp_wl_data_source_cb_resource_destroy(struct wl_resource *resource)
502 E_Comp_Wl_Data_Source *source;
504 if (!(source = wl_resource_get_user_data(resource)))
507 wl_signal_emit(&source->destroy_signal, source);
509 if (e_comp_wl->drag_source == source)
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);
516 _mime_types_free(source);
521 _e_comp_wl_data_source_cb_set_actions(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t dnd_actions)
523 E_Comp_Wl_Data_Source *source;
525 DBG("Data Source Offer");
526 if (!(source = wl_resource_get_user_data(resource)))
529 if (source->actions_set)
531 wl_resource_post_error(source->resource,
532 WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
533 "cannot set actions more than once");
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))
541 wl_resource_post_error(source->resource,
542 WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK,
543 "invalid action mask %x", dnd_actions);
546 source->dnd_actions = dnd_actions;
547 source->actions_set = 1;
551 _e_comp_wl_data_source_target_send(E_Comp_Wl_Data_Source *source, uint32_t serial EINA_UNUSED, const char* mime_type)
553 DBG("Data Source Target Send");
554 wl_data_source_send_target(source->resource, mime_type);
558 _e_comp_wl_data_source_send_send(E_Comp_Wl_Data_Source *source, const char* mime_type, int32_t fd)
560 DBG("Data Source Source Send");
561 wl_data_source_send_send(source->resource, mime_type, fd);
565 _e_comp_wl_data_source_cancelled_send(E_Comp_Wl_Data_Source *source)
567 DBG("Data Source Cancelled Send");
568 wl_data_source_send_cancelled(source->resource);
571 static const struct wl_data_source_interface _e_data_source_interface =
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,
579 _e_comp_wl_data_device_destroy_selection_data_source(struct wl_listener *listener EINA_UNUSED, void *data)
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;
585 DBG("Data Device Destroy Selection Source");
586 if (!(source = (E_Comp_Wl_Data_Source*)data))
589 e_comp_wl->selection.data_source = NULL;
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);
595 if ((cbhm_client) && (source_client != cbhm_client))
598 e_comp_wl_data_find_for_client(wl_resource_get_client(e_comp_wl->selection.cbhm));
601 wl_data_device_send_selection(data_device_res, NULL);
606 if (e_comp_input_key->kbd.enabled)
607 focus = e_comp_input_key->kbd.focus;
612 e_comp_wl_data_find_for_client(wl_resource_get_client(focus));
615 wl_data_device_send_selection(data_device_res, NULL);
618 if (e_comp_wl->selection.data_only_list)
620 struct wl_resource *data_only;
623 EINA_LIST_FOREACH(e_comp_wl->selection.data_only_list, l, data_only)
624 wl_data_device_send_selection(data_only, NULL);
627 wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
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)
633 E_Comp_Wl_Data_Offer *offer;
637 DBG("Data Offer Create");
639 offer = E_NEW(E_Comp_Wl_Data_Offer, 1);
640 if (!offer) return NULL;
643 wl_resource_create(wl_resource_get_client(data_device_res),
644 &wl_data_offer_interface, 3, 0);
645 if (!offer->resource)
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);
659 wl_data_device_send_data_offer(data_device_res, offer->resource);
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);
666 _e_comp_wl_data_offer_update_action(offer);
668 return offer->resource;
672 _e_comp_wl_data_secondary_res_check(struct wl_resource *resource)
674 struct wl_resource *surface;
678 if (resource == NULL)
681 if (e_comp_wl->selection.secondary_list == NULL)
684 EINA_LIST_FOREACH(e_comp_wl->selection.secondary_list, l, ec)
686 surface = e_comp_wl_client_surface_get(ec);
687 if (!surface) continue;
689 if (wl_resource_get_client(surface) == wl_resource_get_client(resource))
697 _e_comp_wl_data_secondary_send(E_Comp_Wl_Data_Source *source)
699 struct wl_client *secondary_client;
700 struct wl_resource *surface, *offer_res, *data_device_res;
704 EINA_LIST_FOREACH(e_comp_wl->selection.secondary_list, l, ec)
706 surface = e_comp_wl_client_surface_get(ec);
707 if (!surface) continue;
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)))
713 secondary_client = wl_resource_get_client(surface);
714 if (secondary_client == NULL)
716 ERR("error get client resource");
719 data_device_res = e_comp_wl_data_find_for_client(secondary_client);
720 if (data_device_res == NULL)
722 ERR("error get device resource");
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);
732 wl_data_device_send_selection(data_device_res, NULL);
735 e_comp_wl->selection.secondary_sent = NULL;
739 _e_comp_wl_data_device_selection_set(void *data EINA_UNUSED, E_Comp_Wl_Data_Source *source, uint32_t serial)
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;
745 sel_source = (E_Comp_Wl_Data_Source*)e_comp_wl->selection.data_source;
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);
755 (sel_client == source_client) &&
756 (sel_client != cbhm_client) &&
757 (e_comp_wl->selection.serial - serial < UINT32_MAX / 2))
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.
763 if (e_comp_wl->clipboard.source)
764 wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
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;
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;
782 if (e_comp_input_key->kbd.enabled)
783 focus = e_comp_input_key->kbd.focus;
785 //if source is from cbhm_client do not create data offer for cbhm
786 if ((cbhm_client) && (source_client != cbhm_client))
788 data_device_res = e_comp_wl_data_find_for_client(cbhm_client);
789 if ((data_device_res) && (source))
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);
794 if (_e_comp_wl_data_secondary_res_check(source->resource) == EINA_TRUE)
795 e_comp_wl->selection.secondary_sent = source->resource;
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);
804 /* send wl_data_device@selection to focused client */
807 data_device_res = e_comp_wl_data_find_for_client(wl_resource_get_client(focus));
808 if ((data_device_res) && (source))
811 _e_comp_wl_data_device_data_offer_create(source,
813 wl_data_device_send_selection(data_device_res, offer_res);
816 else if (data_device_res)
817 wl_data_device_send_selection(data_device_res, NULL);
820 /* send wl_data_device@selection to data only clients
821 * because they won't be focused at all
823 if (e_comp_wl->selection.data_only_list)
825 struct wl_resource *data_only;
828 EINA_LIST_FOREACH(e_comp_wl->selection.data_only_list, l, data_only)
833 _e_comp_wl_data_device_data_offer_create(source,
835 wl_data_device_send_selection(data_only, offer_res);
838 wl_data_device_send_selection(data_only, NULL);
843 wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
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);
855 _e_comp_wl_data_device_drag_finished(E_Drag *drag, E_Dnd_Drop_Type type)
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);
863 evas_object_pass_events_set(o, 1);
865 if (e_comp_wl->drag != drag) return;
867 e_comp_wl->drag = NULL;
869 if (e_comp_wl->drag_client->visible)
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);
875 e_comp_wl->drag_client = NULL;
877 e_comp_override_del();
878 if (e_comp_wl->selection.target)
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);
884 res = e_comp_wl_data_find_for_client(wl_resource_get_client(surface));
888 drag_source = e_comp_wl->drag_source;
892 if ((drag_source->accepted) &&
893 (drag_source->current_dnd_action) &&
894 (type == E_DND_DRAG_TYPE_DROPPED))
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;
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);
905 wl_data_device_send_leave(res);
907 e_comp_wl->selection.target = NULL;
908 e_comp_wl->drag_source = NULL;
910 if (e_comp_wl->drag_offer)
911 ((E_Comp_Wl_Data_Offer*)e_comp_wl->drag_offer)->dropped = EINA_TRUE;
914 e_comp_wl_data_current_device_id_set(-1);
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)
920 E_Comp_Wl_Data_Source *source;
922 struct wl_resource *res;
923 E_Client *drag_icon_ec = NULL, *ec = NULL;
924 E_Client *ec_under_pointer = NULL;
928 DBG("Data Device Drag Start");
932 ERR("Drag already in progress");
936 if (!(source = wl_resource_get_user_data(source_resource)))
939 e_comp_wl->drag_source = source;
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)
947 drag_icon_ec->re_manage = 1;
948 drag_icon_ec->new_client = 1;
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();
957 e_comp_wl->drag_client = drag_icon_ec;
960 ec = e_client_from_surface_resource(origin_resource);
961 if (ec && ec->pointer_enter_sent)
963 EINA_LIST_FOREACH(e_comp_wl->ptr.resources, l, res)
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;
969 wl_pointer_send_leave(res, serial, e_comp_wl_client_surface_get(ec));
972 ec->pointer_enter_sent = EINA_FALSE;
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);
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);
984 e_drag_start(e_comp_wl->drag, x, y);
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);
991 e_comp_canvas_feed_mouse_up(0);
993 e_comp_wl_data_current_device_id_set(-1);
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)
999 E_Comp_Wl_Data_Source *source;
1001 DBG("Data Device Selection Set");
1002 if (!source_resource) return;
1003 if (!(source = wl_resource_get_user_data(source_resource))) return;
1005 _e_comp_wl_data_device_selection_set(e_comp->wl_comp_data, source, serial);
1009 _e_comp_wl_data_device_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1011 DBG("Data Device Release");
1012 wl_resource_destroy(resource);
1015 static const struct wl_data_device_interface _e_data_device_interface =
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
1023 _e_comp_wl_data_device_cb_unbind(struct wl_resource *resource)
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,
1029 eina_hash_del_by_key(e_comp_wl->mgr.data_resources, &wc);
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)
1035 struct wl_resource *res;
1037 DBG("Data Manager Device Get");
1040 /* try to create the data device resource */
1041 res = wl_resource_create(client, &wl_data_device_interface, 3, id);
1044 ERR("Could not create data device resource: %m");
1045 wl_resource_post_no_memory(manager_resource);
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);
1054 static const struct wl_data_device_manager_interface _e_manager_interface =
1056 (void*)e_comp_wl_data_manager_source_create,
1057 _e_comp_wl_data_manager_cb_device_get
1061 _e_comp_wl_data_cb_bind_manager(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id)
1063 struct wl_resource *res;
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);
1069 ERR("Could not create data device manager: %m");
1070 wl_client_post_no_memory(client);
1074 wl_resource_set_implementation(res, &_e_manager_interface,
1075 e_comp->wl_comp_data, NULL);
1079 _e_comp_wl_clipboard_offer_load(void *data, Ecore_Fd_Handler *handler)
1081 E_Comp_Wl_Clipboard_Offer *offer;
1087 if (!(offer = (E_Comp_Wl_Clipboard_Offer*)data))
1088 return ECORE_CALLBACK_CANCEL;
1090 fd = ecore_main_fd_handler_fd_get(handler);
1091 if (fd < 0) return ECORE_CALLBACK_RENEW;
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;
1098 ERR("Could not write for fd(%d) :%m", fd);
1100 if ((offer->offset == size) || (len <= 0))
1103 ecore_main_fd_handler_del(handler);
1104 if (!e_comp_wl_clipboard_source_unref(offer->source))
1106 if (e_comp_wl->clipboard.source == offer->source)
1107 e_comp_wl->clipboard.source = NULL;
1112 return ECORE_CALLBACK_RENEW;
1116 _e_comp_wl_clipboard_offer_create(E_Comp_Wl_Clipboard_Source* source, int fd)
1118 E_Comp_Wl_Clipboard_Offer *offer;
1120 offer = E_NEW(E_Comp_Wl_Clipboard_Offer, 1);
1124 offer->source = source;
1126 e_comp_wl_clipboard_source_ref(source);
1129 ecore_main_fd_handler_add(fd, ECORE_FD_WRITE,
1130 _e_comp_wl_clipboard_offer_load, offer,
1135 _e_comp_wl_clipboard_source_save(void *data EINA_UNUSED, Ecore_Fd_Handler *handler)
1137 E_Comp_Wl_Clipboard_Source *source;
1142 if (!(source = (E_Comp_Wl_Clipboard_Source*)e_comp_wl->clipboard.source))
1143 return ECORE_CALLBACK_CANCEL;
1145 /* allocate contents of array */
1146 if (source->contents.alloc < CLIPBOARD_CHUNK)
1147 wl_array_add(&source->contents, CLIPBOARD_CHUNK);
1149 source->contents.size = 0;
1150 p = (char *)source->contents.data;
1151 size = source->contents.alloc;
1153 while ((len = read(source->fd[0], p, size)))
1155 if (len == -1) break;
1157 source->contents.size += len;
1159 //if the array is full
1161 wl_array_add(&source->contents, CLIPBOARD_CHUNK);
1165 p = (char *)source->contents.data + source->contents.size;
1166 size = source->contents.alloc - source->contents.size;
1169 if ((len < 0) && (source->contents.size == 0))
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;
1176 return ECORE_CALLBACK_RENEW;
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)
1185 _e_comp_wl_clipboard_source_send_send(E_Comp_Wl_Data_Source *source, const char *mime_type, int fd)
1187 E_Comp_Wl_Clipboard_Source* clip_source;
1190 clip_source = container_of(source, E_Comp_Wl_Clipboard_Source, data_source);
1191 if (!clip_source) return;
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);
1201 _e_comp_wl_clipboard_source_cancelled_send(E_Comp_Wl_Data_Source *source EINA_UNUSED)
1206 _e_comp_wl_clipboard_selection_set(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
1208 E_Comp_Wl_Data_Source *sel_source;
1209 E_Comp_Wl_Clipboard_Source *clip_source;
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;
1219 _e_comp_wl_data_device_selection_set(e_comp->wl_comp_data,
1220 &clip_source->data_source,
1221 clip_source->serial);
1224 else if (sel_source->target == _e_comp_wl_clipboard_source_target_send)
1227 mime_type = eina_array_data_get(sel_source->mime_types, 0);
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
1238 if (pipe2(p, O_CLOEXEC|O_DIRECT|O_NONBLOCK) == -1)
1240 ERR("Could not create unidirectional pipe for clipboard: %m");
1244 sel_source->send(sel_source, mime_type, p[1]);
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)
1257 if (clip_source->fd[1] == -1)
1259 ERR("clipboard fd is invalid");
1262 sel_source->send(sel_source, mime_type, clip_source->fd[1]);
1267 _e_comp_wl_clipboard_create(void)
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);
1274 _e_comp_wl_data_device_target_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1276 E_Client *ec = data;
1278 if (e_comp_wl->selection.target == ec)
1279 e_comp_wl->selection.target = NULL;
1283 e_comp_wl_data_device_send_enter(E_Client *ec)
1285 struct wl_resource *data_device_res, *offer_res;
1289 struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1290 if (!surface) return;
1293 e_comp_wl_data_find_for_client(wl_resource_get_client(surface));
1295 if (!data_device_res) return;
1296 offer_res = e_comp_wl_data_device_send_offer(ec);
1297 if (e_comp_wl->drag_source)
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;
1303 if (!offer_res) return;
1306 (old_offer->source == drag_source))
1308 old_offer->dropped = EINA_FALSE;
1309 old_offer->source = NULL;
1311 drag_source->accepted = EINA_FALSE;
1313 new_offer = wl_resource_get_user_data(offer_res);
1314 e_comp_wl->drag_offer = new_offer;
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);
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);
1326 if (e_client_transform_core_enable_get(ec))
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;
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;
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);
1347 e_comp_wl_data_device_send_leave(E_Client *ec)
1349 struct wl_resource *res;
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;
1357 res = e_comp_wl_data_find_for_client(wl_resource_get_client(surface));
1359 wl_data_device_send_leave(res);
1363 e_comp_wl_data_device_send_offer(E_Client *ec)
1365 struct wl_resource *data_device_res, *offer_res = NULL;
1366 E_Comp_Wl_Data_Source *source;
1368 struct wl_resource *surface = e_comp_wl_client_surface_get(ec);
1369 if (!surface) return NULL;
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;
1376 offer_res = _e_comp_wl_data_device_data_offer_create(source, data_device_res);
1381 e_comp_wl_data_device_keyboard_focus_set(void)
1383 struct wl_resource *data_device_res, *offer_res = NULL, *focus;
1384 E_Comp_Wl_Data_Source *source;
1386 if (!e_comp_input_key->kbd.enabled)
1388 ERR("Keyboard not enabled");
1392 if (!(focus = e_comp_input_key->kbd.focus))
1394 ERR("No focused resource");
1397 source = (E_Comp_Wl_Data_Source*)e_comp_wl->selection.data_source;
1400 e_comp_wl_data_find_for_client(wl_resource_get_client(focus));
1401 if (!data_device_res) return;
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,
1408 if (source && !source->is_manual)
1411 _e_comp_wl_data_device_data_offer_create(source, data_device_res);
1413 wl_data_device_send_selection(data_device_res, offer_res);
1417 e_comp_wl_data_manager_init(void)
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)
1425 ERR("Could not create global for data device manager: %m");
1429 wl_signal_init(&e_comp_wl->selection.signal);
1431 /* create clipboard */
1432 _e_comp_wl_clipboard_create();
1433 e_comp_wl->mgr.data_resources = eina_hash_pointer_new(NULL);
1439 e_comp_wl_data_manager_shutdown(void)
1441 /* destroy the global manager resource */
1442 /* if (e_comp_wl->mgr.global) wl_global_destroy(e_comp_wl->mgr.global); */
1444 wl_list_remove(&e_comp_wl->clipboard.listener.link);
1445 E_FREE_FUNC(e_comp_wl->mgr.data_resources, eina_hash_free);
1448 EINTERN struct wl_resource *
1449 e_comp_wl_data_find_for_client(struct wl_client *client)
1451 return eina_hash_find(e_comp_wl->mgr.data_resources, &client);
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)
1457 E_Comp_Wl_Data_Source *source;
1459 DBG("Data Manager Source Create");
1461 source = E_NEW(E_Comp_Wl_Data_Source, 1);
1464 wl_resource_post_no_memory(resource);
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;
1474 wl_resource_create(client, &wl_data_source_interface, 3, id);
1475 if (!source->resource)
1477 ERR("Could not create data source resource: %m");
1479 wl_resource_post_no_memory(resource);
1483 wl_resource_set_implementation(source->resource,
1484 &_e_data_source_interface, source,
1485 _e_comp_wl_data_source_cb_resource_destroy);
1489 EINTERN E_Comp_Wl_Clipboard_Source *
1490 e_comp_wl_clipboard_source_create(const char *mime_type, uint32_t serial, int *fd)
1492 E_Comp_Wl_Clipboard_Source *source;
1494 source = E_NEW(E_Comp_Wl_Clipboard_Source, 1);
1495 if (!source) return NULL;
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;
1503 wl_array_init(&source->contents);
1504 wl_signal_init(&source->data_source.destroy_signal);
1507 source->serial = serial;
1511 if (!source->data_source.mime_types)
1512 source->data_source.mime_types = eina_array_new(1);
1514 if (source->data_source.mime_types == NULL)
1520 eina_array_push(source->data_source.mime_types, eina_stringshare_add(mime_type));
1523 if ((fd[0] >= 0) && (fd[1] >= 0))
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)
1541 source->fd[0] = fd[0];
1542 source->fd[1] = fd[1];
1548 e_comp_wl_clipboard_source_ref(E_Comp_Wl_Clipboard_Source *source)
1555 e_comp_wl_clipboard_source_unref(E_Comp_Wl_Clipboard_Source *source)
1557 EINA_SAFETY_ON_NULL_RETURN_VAL(source, 0);
1559 if (source->ref > 0)
1562 if (source->fd_handler)
1564 ecore_main_fd_handler_del(source->fd_handler);
1565 close(source->fd[0]);
1566 close(source->fd[1]);
1569 _mime_types_free(&source->data_source);
1571 wl_signal_emit(&source->data_source.destroy_signal, &source->data_source);
1572 wl_array_release(&source->contents);
1579 e_comp_wl_data_device_only_set(struct wl_resource *data_device_res, Eina_Bool set)
1581 struct wl_resource *offer_res = NULL, *focus;
1582 E_Comp_Wl_Data_Source *source;
1584 EINA_SAFETY_ON_NULL_RETURN(data_device_res);
1588 if (eina_list_data_find(e_comp_wl->selection.data_only_list, data_device_res))
1591 e_comp_wl->selection.data_only_list =
1592 eina_list_append(e_comp_wl->selection.data_only_list, data_device_res);
1594 source = (E_Comp_Wl_Data_Source *)e_comp_wl->selection.data_source;
1595 if (source && !source->is_manual)
1598 _e_comp_wl_data_device_data_offer_create(source, data_device_res);
1600 wl_data_device_send_selection(data_device_res, offer_res);
1604 e_comp_wl->selection.data_only_list =
1605 eina_list_remove(e_comp_wl->selection.data_only_list, data_device_res);
1607 focus = e_comp_input_key->kbd.focus;
1609 (wl_resource_get_client(focus) != wl_resource_get_client(data_device_res)))
1611 wl_data_device_send_selection(data_device_res, NULL);
1617 _e_comp_wl_data_device_destroy_manual_source(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
1619 struct wl_resource *data_device_res = NULL;
1620 struct wl_client *cbhm_client = NULL;
1622 e_comp_wl->selection.data_source = NULL;
1624 if (e_comp_wl->selection.cbhm)
1625 cbhm_client = wl_resource_get_client(e_comp_wl->selection.cbhm);
1630 e_comp_wl_data_find_for_client(cbhm_client);
1632 if (data_device_res)
1633 wl_data_device_send_selection(data_device_res, NULL);
1638 _e_comp_wl_manual_source_ref(E_Comp_Wl_Manual_Data_Source *source)
1645 _e_comp_wl_manual_source_unref(E_Comp_Wl_Manual_Data_Source *source)
1647 EINA_SAFETY_ON_NULL_RETURN_VAL(source, 0);
1649 if (source->ref > 0)
1652 _mime_types_free(&source->data_source);
1654 wl_signal_emit(&source->data_source.destroy_signal, &source->data_source);
1655 wl_array_release(&source->contents);
1662 _e_comp_wl_manual_offer_load(E_Comp_Wl_Manual_Data_Source *source, int fd)
1669 size = source->contents.size;
1670 p = (char *)source->contents.data;
1671 len = write(fd, p, size);
1672 if (len > 0) offset += len;
1674 ERR("could not write for fd(%d) :%m", fd);
1678 _e_comp_wl_manual_source_unref(source);
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)
1688 _e_comp_wl_manual_source_send_send(E_Comp_Wl_Data_Source *source, const char *mime_type, int fd)
1690 E_Comp_Wl_Manual_Data_Source *man_source;
1692 man_source = container_of(source, E_Comp_Wl_Manual_Data_Source, data_source);
1693 if (!man_source) return;
1695 _e_comp_wl_manual_offer_load(man_source, fd);
1700 _e_comp_wl_manual_source_cancelled_send(E_Comp_Wl_Data_Source *source EINA_UNUSED)
1702 E_Comp_Wl_Manual_Data_Source *man_source;
1704 man_source = container_of(source, E_Comp_Wl_Manual_Data_Source, data_source);
1705 if (!man_source) return;
1707 _e_comp_wl_manual_source_unref(man_source);
1711 _e_comp_wl_data_device_manual_selection_set(E_Comp_Wl_Data_Source *source, uint32_t serial)
1713 E_Comp_Wl_Data_Source *sel_source;
1714 struct wl_resource *offer_res, *data_device_res;
1715 struct wl_client *cbhm_client = NULL;
1717 sel_source = (E_Comp_Wl_Data_Source*)e_comp_wl->selection.data_source;
1719 if (e_comp_wl->selection.cbhm)
1720 cbhm_client = wl_resource_get_client(e_comp_wl->selection.cbhm);
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;
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;
1738 e_comp_wl_data_find_for_client(cbhm_client);
1739 if ((data_device_res) && (source))
1742 _e_comp_wl_data_device_data_offer_create(source,
1744 wl_data_device_send_selection(data_device_res, offer_res);
1748 //do not notify to internal clipboard
1749 //wl_signal_emit(&e_comp_wl->selection.signal, e_comp->wl_comp_data);
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);
1761 e_comp_wl_data_device_manual_selection_set(void *data, size_t size, Eina_List *mime_list)
1763 E_Comp_Wl_Manual_Data_Source *man_source;
1767 if ((size <= 0) || (!data) || (!mime_list)) return EINA_FALSE;
1769 man_source = E_NEW(E_Comp_Wl_Manual_Data_Source, 1);
1770 if (!man_source) return EINA_FALSE;
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;
1778 wl_array_init(&man_source->contents);
1779 wl_signal_init(&man_source->data_source.destroy_signal);
1781 man_source->serial = e_comp_wl->selection.serial;
1783 if (!man_source->data_source.mime_types)
1784 man_source->data_source.mime_types = eina_array_new(64);
1786 if (man_source->data_source.mime_types == NULL)
1788 wl_array_release(&man_source->contents);
1793 EINA_LIST_FOREACH(mime_list, l, t)
1794 eina_array_push(man_source->data_source.mime_types, eina_stringshare_add(t));
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);
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);
1807 e_comp_wl_data_current_device_id_set(int id)
1809 e_comp_wl->drag_device_id = id;
1813 e_comp_wl_data_current_device_id_get(void)
1815 return e_comp_wl->drag_device_id;
1819 e_comp_wl_data_offer_mimetype_action_accept(E_Comp_Wl_Data_Offer *offer)
1821 E_Comp_Wl_Data_Source *source;
1825 source = offer->source;
1826 if (!source) return;
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;
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);
1840 _e_comp_wl_data_secondary_list_check(E_Client *ec)
1845 if (e_comp_wl->selection.secondary_list == NULL)
1848 EINA_LIST_FOREACH(e_comp_wl->selection.secondary_list, l, tmp)
1858 e_comp_wl_data_secondary_add(E_Client *ec)
1860 EINA_SAFETY_ON_NULL_RETURN(ec);
1862 if (_e_comp_wl_data_secondary_list_check(ec) == EINA_TRUE)
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));
1871 e_comp_wl_data_secondary_remove(E_Client *ec)
1873 EINA_SAFETY_ON_NULL_RETURN(ec);
1875 if (_e_comp_wl_data_secondary_list_check(ec) == EINA_FALSE)
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));
1882 if (eina_list_count(e_comp_wl->selection.secondary_list) == 0)
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;