summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2020-02-10 09:20:18 +0100
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2020-03-08 10:59:37 +0100
commit5ac02ec9acdd2b9b5bf7b0e6bb4dcd99cb6f63d7 (patch)
tree33b7a645623977a67871ede9a7b15cca37cc61b0 /src/modules
parente0c40abb40f05efe32e263e8a59e923281b559dc (diff)
ecore_evas: introduce wayland support for cnp & dnd
This adds cnp support, actions are right now only mapped to "ask", further support can be added there, and synchronization can be added to register more available actions. However, i did not find *any* wayland implementation in gtk qt nor chromiumos that even use the action to indicate anything. This here also has a slightly different behaviour to X11 in terms of coordinates for motion,leave,enter. They can contain negative coordinates (which is due to the fact that wl is CSD and X11 is SSD. However, I did not want to fix this in any regard, as you might want to use that, and it would be a none trivial amount of code to fix that. Reviewed-by: Chris Michael <cp.michael@samsung.com> Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Differential Revision: https://phab.enlightenment.org/D11329
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c471
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h16
2 files changed, 482 insertions, 5 deletions
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
index e0e2094e2f..d5cb3d8b49 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
@@ -4,6 +4,7 @@
4 4
5#include "ecore_evas_wayland_private.h" 5#include "ecore_evas_wayland_private.h"
6#include <Evas_Engine_Wayland.h> 6#include <Evas_Engine_Wayland.h>
7#include "ecore_wl2_internal.h"
7 8
8extern EAPI Eina_List *_evas_canvas_image_data_unset(Evas *eo_e); 9extern EAPI Eina_List *_evas_canvas_image_data_unset(Evas *eo_e);
9extern EAPI void _evas_canvas_image_data_regenerate(Eina_List *list); 10extern EAPI void _evas_canvas_image_data_regenerate(Eina_List *list);
@@ -32,6 +33,7 @@ static Eina_Array *_ecore_evas_wl_event_hdls;
32 33
33static void _ecore_evas_wayland_resize(Ecore_Evas *ee, int location); 34static void _ecore_evas_wayland_resize(Ecore_Evas *ee, int location);
34static void _ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize); 35static void _ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize);
36static void _ecore_evas_wl_selection_init(Ecore_Evas *ee);
35 37
36/* local functions */ 38/* local functions */
37static void 39static void
@@ -1440,6 +1442,15 @@ _ecore_evas_wl_common_free(Ecore_Evas *ee)
1440 if (wdata->frame) ecore_wl2_window_frame_callback_del(wdata->frame); 1442 if (wdata->frame) ecore_wl2_window_frame_callback_del(wdata->frame);
1441 wdata->frame = NULL; 1443 wdata->frame = NULL;
1442 ecore_event_handler_del(wdata->sync_handler); 1444 ecore_event_handler_del(wdata->sync_handler);
1445 ecore_event_handler_del(wdata->changed_handler);
1446 ecore_event_handler_del(wdata->send_handler);
1447 ecore_event_handler_del(wdata->offer_handler);
1448 ecore_event_handler_del(wdata->dnd_leave_handler);
1449 ecore_event_handler_del(wdata->dnd_enter_handler);
1450 ecore_event_handler_del(wdata->dnd_motion_handler);
1451 ecore_event_handler_del(wdata->dnd_drop_handler);
1452 ecore_event_handler_del(wdata->dnd_end_handler);
1453
1443 if (wdata->win) 1454 if (wdata->win)
1444 { 1455 {
1445 ecore_wl2_window_close_callback_set(wdata->win, NULL, NULL); 1456 ecore_wl2_window_close_callback_set(wdata->win, NULL, NULL);
@@ -2389,6 +2400,457 @@ _ecore_wl2_devices_setup(Ecore_Evas *ee, Ecore_Wl2_Display *display)
2389 return r; 2400 return r;
2390} 2401}
2391 2402
2403static void
2404_reeval_seat(unsigned int *seat, Ecore_Evas *ee)
2405{
2406 if (*seat == 0)
2407 *seat = evas_device_seat_id_get(evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_TYPE_SEAT));
2408}
2409
2410static inline void
2411_clear_selection(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection)
2412{
2413 Ecore_Evas_Engine_Wl_Data *edata = ee->engine.data;
2414 Ecore_Evas_Selection_Callbacks *cbs = &edata->selection_data[selection].callbacks;
2415
2416 EINA_SAFETY_ON_FALSE_RETURN(cbs->cancel);
2417
2418 cbs->cancel(ee, seat, selection);
2419 eina_array_free(cbs->available_types);
2420 memset(cbs, 0, sizeof(Ecore_Evas_Selection_Callbacks));
2421}
2422
2423static void
2424_store_selection_cbs(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Internal_Delivery delivery, Ecore_Evas_Internal_Cancel cancel)
2425{
2426 Ecore_Evas_Wl_Selection_Data *sdata;
2427 Ecore_Evas_Engine_Wl_Data *edata;
2428 Ecore_Evas_Selection_Callbacks *cbs;
2429
2430 edata = ee->engine.data;
2431 sdata = &edata->selection_data[selection];
2432 cbs = &sdata->callbacks;
2433
2434 if (cbs->cancel)
2435 {
2436 _clear_selection(ee, seat, selection);
2437 }
2438
2439 cbs->delivery = delivery;
2440 cbs->cancel = cancel;
2441 cbs->available_types = available_types;
2442}
2443
2444static inline Ecore_Wl2_Input*
2445_fetch_input(Ecore_Evas *ee, unsigned int seat)
2446{
2447 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2448 return ecore_wl2_display_input_find(ecore_wl2_window_display_get(wdata->win), seat);
2449}
2450
2451static Eina_Bool
2452_ecore_evas_wl_selection_claim(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Internal_Delivery delivery, Ecore_Evas_Internal_Cancel cancel)
2453{
2454 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2455 Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
2456 char *tmp_array[eina_array_count(available_types) + 1];
2457
2458 if (selection == ECORE_EVAS_SELECTION_BUFFER_SELECTION_BUFFER)
2459 {
2460 _store_selection_cbs(ee, seat, selection, available_types, delivery, cancel);
2461 return EINA_TRUE;
2462 }
2463
2464 _reeval_seat(&seat, ee);
2465 _store_selection_cbs(ee, seat, selection, available_types, delivery, cancel);
2466
2467 for (unsigned int i = 0; i < eina_array_count(available_types); ++i)
2468 {
2469 tmp_array[i] = eina_array_data_get(available_types, i);
2470 }
2471 tmp_array[eina_array_count(available_types)] = NULL;
2472
2473 data->sent_serial = ecore_wl2_dnd_selection_set(_fetch_input(ee, seat), (const char**)tmp_array);
2474 return EINA_TRUE;
2475}
2476
2477
2478static Eina_Future*
2479_ecore_evas_wl_selection_request(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *acceptable_types)
2480{
2481 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2482 Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
2483 Ecore_Wl2_Input *input;
2484 Ecore_Wl2_Offer *offer = NULL;
2485 Eina_Future *future;
2486
2487 _reeval_seat(&seat, ee);
2488 input = _fetch_input(ee, seat);
2489
2490 if (data->delivery)
2491 {
2492 eina_promise_reject(data->delivery, ecore_evas_request_replaced);
2493 data->delivery = NULL;
2494 }
2495 data->delivery = efl_loop_promise_new(efl_main_loop_get());
2496 future = eina_future_new(data->delivery);
2497
2498 if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
2499 {
2500 offer = data->offer = wdata->external_offer;
2501 }
2502 else if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
2503 {
2504 offer = data->offer = ecore_wl2_dnd_selection_get(input);
2505 }
2506
2507 if (!offer)
2508 {
2509 eina_promise_reject(data->delivery, ecore_evas_no_selection);
2510 data->delivery = NULL;
2511 }
2512 else
2513 {
2514 Eina_Array *available_types = ecore_wl2_offer_mimes_get(offer);
2515 char *selected_type = NULL;
2516
2517 for (unsigned int i = 0; i < eina_array_count(available_types) && !selected_type; ++i)
2518 {
2519 char *available_type = eina_array_data_get(available_types, i);
2520 for (unsigned int j = 0; j < eina_array_count(acceptable_types) && !selected_type; ++j)
2521 {
2522 char *acceptable_type = eina_array_data_get(acceptable_types, j);
2523 if (eina_streq(acceptable_type, available_type))
2524 {
2525 selected_type = available_type;
2526 data->later_convert = NULL;
2527 break;
2528 }
2529
2530 const char *convert_available_type;
2531 Eina_Iterator *convertions = eina_content_converter_possible_conversions(available_type);
2532 EINA_ITERATOR_FOREACH(convertions, convert_available_type)
2533 {
2534 if (eina_streq(convert_available_type, acceptable_type))
2535 {
2536 selected_type = available_type;
2537 data->later_convert = acceptable_type;
2538 }
2539 }
2540 eina_iterator_free(convertions);
2541 }
2542
2543 }
2544 if (selected_type)
2545 {
2546 ecore_wl2_offer_receive(offer, selected_type);
2547 ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
2548 }
2549 else
2550 {
2551 eina_promise_reject(data->delivery, ecore_evas_no_matching_type);
2552 data->delivery = NULL;
2553 }
2554 }
2555
2556 return future;
2557}
2558
2559static Eina_Bool
2560_ecore_evas_wl_selection_has_owner(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection EINA_UNUSED)
2561{
2562 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2563 Ecore_Wl2_Input *input;
2564
2565 _reeval_seat(&seat, ee);
2566 input = _fetch_input(ee, seat);
2567
2568 if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER )
2569 return !!ecore_wl2_dnd_selection_get(input);
2570 else if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
2571 {
2572 Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
2573 return !!data->offer;
2574 }
2575
2576 return EINA_FALSE; //the selection buffer is not supportet in wayland
2577}
2578
2579static Eina_Bool
2580_wl_selection_changed(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
2581{
2582 Ecore_Wl2_Event_Seat_Selection *sel = event;
2583 Ecore_Evas *ee = data;
2584 Ecore_Wl2_Input *input;
2585 unsigned int seat = sel->seat;
2586
2587 _reeval_seat(&seat, ee);
2588 input = _fetch_input(ee, seat);
2589 if (!ecore_wl2_dnd_selection_get(input))
2590 return ECORE_CALLBACK_PASS_ON;
2591
2592 if (ee->func.fn_selection_changed)
2593 ee->func.fn_selection_changed(ee, 0, ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER);
2594
2595 return ECORE_CALLBACK_PASS_ON;
2596}
2597
2598typedef struct {
2599 Eina_Rw_Slice slice;
2600 unsigned int written_bytes;
2601} Delayed_Writing;
2602
2603static Eina_Bool
2604_write_to_fd(void *data, Ecore_Fd_Handler *fd_handler)
2605{
2606 int fd = ecore_main_fd_handler_fd_get(fd_handler);
2607 Delayed_Writing *slice = data;
2608
2609 size_t len = write(fd, slice->slice.mem + slice->written_bytes, slice->slice.len - slice->written_bytes);
2610
2611 slice->written_bytes += len;
2612 if (slice->written_bytes != slice->slice.len)
2613 {
2614 return EINA_TRUE;
2615 }
2616 else
2617 {
2618 ecore_main_fd_handler_del(fd_handler);
2619 free(slice->slice.mem);
2620 free(slice);
2621 close(fd);
2622 return EINA_FALSE;
2623 }
2624
2625}
2626
2627static Eina_Bool
2628_wl_interaction_send(void *data, int type EINA_UNUSED, void *event)
2629{
2630 Ecore_Wl2_Event_Data_Source_Send *ev = event;
2631 Ecore_Evas *ee = data;
2632 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2633 Ecore_Evas_Wl_Selection_Data *selection = NULL;
2634 Delayed_Writing *forign_slice = calloc(1, sizeof(Delayed_Writing));
2635 Ecore_Evas_Selection_Buffer buffer = ECORE_EVAS_SELECTION_BUFFER_LAST;
2636
2637 if (ev->serial == wdata->selection_data[ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER].sent_serial)
2638 buffer = ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER;
2639 else if (ev->serial == wdata->selection_data[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER].sent_serial)
2640 {
2641 buffer = ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER;
2642 ee->drag.accepted = EINA_TRUE;
2643 }
2644
2645 if (buffer == ECORE_EVAS_SELECTION_BUFFER_LAST)
2646 {
2647 //silent return, this send request was *not* for this window
2648 return ECORE_CALLBACK_PASS_ON;
2649 }
2650
2651 selection = &wdata->selection_data[buffer];
2652 EINA_SAFETY_ON_NULL_GOTO(selection, end);
2653 EINA_SAFETY_ON_NULL_GOTO(selection->callbacks.delivery, end);
2654 EINA_SAFETY_ON_FALSE_GOTO(selection->callbacks.delivery(ee, ev->seat, buffer, ev->type, &forign_slice->slice), end);
2655 ecore_main_fd_handler_add(ev->fd, ECORE_FD_WRITE, _write_to_fd, forign_slice, NULL, NULL);
2656end:
2657 return ECORE_CALLBACK_PASS_ON;
2658}
2659
2660static Eina_Bool
2661_wl_selection_receive(void *data, int type EINA_UNUSED, void *event)
2662{
2663 Ecore_Evas *ee = data;
2664 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2665 Ecore_Wl2_Event_Offer_Data_Ready *ready = event;
2666 Ecore_Evas_Selection_Buffer selection = ECORE_EVAS_SELECTION_BUFFER_LAST;
2667
2668 for (int i = 0; i < ECORE_EVAS_SELECTION_BUFFER_LAST; ++i)
2669 {
2670 if (wdata->selection_data[i].offer == ready->offer)
2671 {
2672 selection = i;
2673 break;
2674 }
2675 }
2676
2677 if (selection == ECORE_EVAS_SELECTION_BUFFER_LAST)
2678 return ECORE_CALLBACK_PASS_ON;
2679
2680 //Now deliver the content
2681 Eina_Slice slice;
2682
2683 if (!strncmp(ready->mimetype, "text", strlen("text")))
2684 {
2685 //ensure that we always have a \0 at the end, there is no assertion that \0 is included here.
2686 slice.len = ready->len + 1;
2687 slice.mem = eina_memdup((unsigned char*)ready->data, ready->len, EINA_TRUE);
2688 }
2689 else
2690 {
2691 slice.len = ready->len;
2692 slice.mem = ready->data;
2693 }
2694
2695 Eina_Content *content = eina_content_new(slice, ready->mimetype);
2696
2697 if (wdata->selection_data[selection].later_convert)
2698 {
2699 Eina_Content *tmp = eina_content_convert(content, wdata->selection_data[selection].later_convert);
2700 wdata->selection_data[selection].later_convert = NULL;
2701 eina_content_free(content);
2702 content = tmp;
2703 }
2704
2705 eina_promise_resolve(wdata->selection_data[selection].delivery, eina_value_content_init(content));
2706 wdata->selection_data[selection].delivery = NULL;
2707 eina_content_free(content);
2708
2709 return ECORE_CALLBACK_PASS_ON;
2710}
2711
2712static Eina_Bool
2713_wl_selection_dnd_leave(void *data, int type EINA_UNUSED, void *event)
2714{
2715 Ecore_Evas *ee = data;
2716 Eina_Position2D cpos;
2717 Eina_Position2D fpos = EINA_POSITION2D(0, 0);
2718 Ecore_Wl2_Event_Dnd_Leave *ev = event;
2719 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2720
2721 if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
2722
2723 //evas_output_framespace_get(ee->evas, &fpos.x, &fpos.y, NULL, NULL);
2724 ecore_wl2_input_pointer_xy_get(ecore_wl2_display_input_find(ev->display, ev->seat), &cpos.x, &cpos.y);
2725 ecore_evas_dnd_leave(data, ev->seat, EINA_POSITION2D(cpos.x - fpos.x, cpos.y - fpos.y));
2726 wdata->external_offer = NULL;
2727
2728 return ECORE_CALLBACK_PASS_ON;
2729}
2730
2731static Eina_Bool
2732_wl_selection_dnd_motion(void *data, int type EINA_UNUSED, void *event)
2733{
2734 Ecore_Evas *ee = data;
2735 Ecore_Wl2_Event_Dnd_Motion *ev = event;
2736 Eina_Position2D fpos = EINA_POSITION2D(0, 0);
2737
2738 if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
2739
2740 evas_output_framespace_get(ee->evas, &fpos.x, &fpos.y, NULL, NULL);
2741 ecore_evas_dnd_position_set(data, ev->seat, EINA_POSITION2D(ev->x - fpos.x, ev->y - fpos.y));
2742 return ECORE_CALLBACK_PASS_ON;
2743}
2744static Eina_Bool
2745_wl_selection_dnd_enter(void *data, int type EINA_UNUSED, void *event)
2746{
2747 Ecore_Evas *ee = data;
2748 Ecore_Wl2_Event_Dnd_Enter *ev = event;
2749 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2750 Eina_Position2D fpos = EINA_POSITION2D(0, 0);
2751
2752 if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
2753
2754 evas_output_framespace_get(ee->evas, &fpos.x, &fpos.y, NULL, NULL);
2755 ecore_evas_dnd_enter(data, ev->seat, eina_array_iterator_new(ecore_wl2_offer_mimes_get(ev->offer)), EINA_POSITION2D(ev->x - fpos.x, ev->y - fpos.y));
2756 ecore_wl2_offer_mimes_set(ev->offer, ecore_wl2_offer_mimes_get(ev->offer));
2757 wdata->external_offer = ev->offer;
2758 return ECORE_CALLBACK_PASS_ON;
2759}
2760
2761static Eina_Bool
2762_wl_selection_dnd_drop(void *data, int type EINA_UNUSED, void *event)
2763{
2764 Ecore_Evas *ee = data;
2765 Ecore_Wl2_Event_Dnd_Drop *ev = event;
2766 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2767 if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
2768 wdata = ee->engine.data;
2769
2770 if (ee->func.fn_dnd_drop)
2771 ee->func.fn_dnd_drop(ee, ev->seat, ecore_evas_dnd_pos_get(ee, ev->seat), "ask");
2772
2773 ecore_wl2_dnd_drag_end(_fetch_input(ee, ev->seat));
2774 wdata->external_offer = NULL;
2775
2776 return ECORE_CALLBACK_PASS_ON;
2777}
2778static Eina_Bool
2779_wl_selection_dnd_end(void *data, int type EINA_UNUSED, void *event)
2780{
2781 Ecore_Evas *ee = data;
2782 Ecore_Wl2_Event_Dnd_End *ev = event;
2783
2784 if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
2785
2786
2787 if (ee->drag.free)
2788 ee->drag.free(ee, ev->seat, ee->drag.data, ee->drag.accepted);
2789 ee->drag.free = NULL;
2790 //we got dropped, we should call
2791
2792 return ECORE_CALLBACK_PASS_ON;
2793}
2794
2795static void
2796_ecore_evas_wl_selection_init(Ecore_Evas *ee)
2797{
2798 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2799
2800 wdata->changed_handler = ecore_event_handler_add(ECORE_WL2_EVENT_SEAT_SELECTION,
2801 _wl_selection_changed, ee);
2802 wdata->send_handler = ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_SEND,
2803 _wl_interaction_send, ee);
2804 wdata->offer_handler = ecore_event_handler_add(ECORE_WL2_EVENT_OFFER_DATA_READY,
2805 _wl_selection_receive, ee);
2806 wdata->dnd_leave_handler = ecore_event_handler_add(ECORE_WL2_EVENT_DND_LEAVE,
2807 _wl_selection_dnd_leave, ee);
2808 wdata->dnd_motion_handler = ecore_event_handler_add(ECORE_WL2_EVENT_DND_MOTION,
2809 _wl_selection_dnd_motion, ee);
2810 wdata->dnd_enter_handler = ecore_event_handler_add(ECORE_WL2_EVENT_DND_ENTER,
2811 _wl_selection_dnd_enter, ee);
2812 wdata->dnd_drop_handler = ecore_event_handler_add(ECORE_WL2_EVENT_DND_DROP,
2813 _wl_selection_dnd_drop, ee);
2814 wdata->dnd_end_handler = ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_DROP,
2815 _wl_selection_dnd_end, ee);
2816 for (int i = 0; i < ECORE_EVAS_SELECTION_BUFFER_LAST; ++i)
2817 {
2818 wdata->selection_data[i].callbacks.available_types = NULL;
2819 wdata->selection_data[i].callbacks.delivery = NULL;
2820 wdata->selection_data[i].callbacks.cancel = NULL;
2821 }
2822}
2823
2824static Eina_Bool
2825_ecore_evas_wl_dnd_start(Ecore_Evas *ee, unsigned int seat, Eina_Array *available_types, Ecore_Evas *drag_rep, Ecore_Evas_Internal_Delivery delivery, Ecore_Evas_Internal_Cancel cancel, const char *action EINA_UNUSED)
2826{
2827 Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
2828 const char *tmp_array[eina_array_count(available_types) + 1];
2829
2830 _reeval_seat(&seat, ee);
2831 _store_selection_cbs(ee, seat, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER, available_types, delivery, cancel);
2832
2833 for (unsigned int i = 0; i < eina_array_count(available_types); ++i)
2834 {
2835 tmp_array[i] = eina_array_data_get(available_types, i);
2836 }
2837 tmp_array[eina_array_count(available_types)] = NULL;
2838
2839 ecore_wl2_dnd_drag_types_set(_fetch_input(ee, seat), (const char**)tmp_array);
2840 wdata->selection_data[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER].sent_serial =
2841 ecore_wl2_dnd_drag_start(_fetch_input(ee, seat), _ecore_evas_wayland_window_get(ee), _ecore_evas_wayland_window_get(drag_rep));
2842 return EINA_TRUE;
2843}
2844
2845static Eina_Bool
2846_ecore_evas_wl_dnd_stop(Ecore_Evas *ee, unsigned int seat)
2847{
2848 _clear_selection(ee, seat, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER);
2849 _reeval_seat(&seat, ee);
2850 ecore_wl2_dnd_drag_end(_fetch_input(ee, seat));
2851 return EINA_TRUE;
2852}
2853
2392static Ecore_Evas_Engine_Func _ecore_wl_engine_func = 2854static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
2393{ 2855{
2394 _ecore_evas_wl_common_free, 2856 _ecore_evas_wl_common_free,
@@ -2474,9 +2936,11 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
2474 _ecore_evas_wl_common_pointer_device_xy_get, 2936 _ecore_evas_wl_common_pointer_device_xy_get,
2475 _ecore_evas_wl_common_prepare, 2937 _ecore_evas_wl_common_prepare,
2476 NULL, //fn_last_tick_get 2938 NULL, //fn_last_tick_get
2477 NULL, //fn_selection_claim 2939 _ecore_evas_wl_selection_claim, //fn_selection_claim
2478 NULL, //fn_selection_has_owner 2940 _ecore_evas_wl_selection_has_owner, //fn_selection_has_owner
2479 NULL, //fn_selection_request 2941 _ecore_evas_wl_selection_request, //fn_selection_request
2942 _ecore_evas_wl_dnd_start, //fn_dnd_start
2943 _ecore_evas_wl_dnd_stop, //fn_dnd_stop
2480}; 2944};
2481 2945
2482static void 2946static void
@@ -2653,6 +3117,7 @@ _ecore_evas_wl_common_new_internal(const char *disp_name, Ecore_Window parent, i
2653 } 3117 }
2654 3118
2655 _ecore_evas_wl_common_wm_rotation_protocol_set(ee); 3119 _ecore_evas_wl_common_wm_rotation_protocol_set(ee);
3120 _ecore_evas_wl_selection_init(ee);
2656 3121
2657 ecore_evas_done(ee, EINA_FALSE); 3122 ecore_evas_done(ee, EINA_FALSE);
2658 3123
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h
index e69970f262..d042719d93 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h
@@ -34,12 +34,23 @@
34 34
35typedef struct _Ecore_Evas_Engine_Wl_Data Ecore_Evas_Engine_Wl_Data; 35typedef struct _Ecore_Evas_Engine_Wl_Data Ecore_Evas_Engine_Wl_Data;
36 36
37typedef struct _Ecore_Evas_Wl_Selection_Data Ecore_Evas_Wl_Selection_Data;
38
39struct _Ecore_Evas_Wl_Selection_Data
40{
41 Ecore_Evas_Selection_Callbacks callbacks;
42 Eina_Promise *delivery;
43 Ecore_Wl2_Offer *offer;
44 const char *later_convert;
45 uint32_t sent_serial; //The serial of the last sent selection op
46};
47
37struct _Ecore_Evas_Engine_Wl_Data 48struct _Ecore_Evas_Engine_Wl_Data
38{ 49{
39 Ecore_Wl2_Display *display; 50 Ecore_Wl2_Display *display;
40 Eina_List *regen_objs; 51 Eina_List *regen_objs;
41 Ecore_Wl2_Window *parent, *win; 52 Ecore_Wl2_Window *parent, *win;
42 Ecore_Event_Handler *sync_handler; 53 Ecore_Event_Handler *sync_handler, *changed_handler, *end_handler, *send_handler, *offer_handler, *dnd_leave_handler, *dnd_motion_handler, *dnd_enter_handler, *dnd_drop_handler, *dnd_end_handler;
43 int fx, fy, fw, fh; 54 int fx, fy, fw, fh;
44 Ecore_Wl2_Frame_Cb_Handle *frame; 55 Ecore_Wl2_Frame_Cb_Handle *frame;
45 int x_rel; 56 int x_rel;
@@ -47,7 +58,8 @@ struct _Ecore_Evas_Engine_Wl_Data
47 uint32_t timestamp; 58 uint32_t timestamp;
48 Eina_List *devices_list; 59 Eina_List *devices_list;
49 int cw, ch; 60 int cw, ch;
50 61 Ecore_Evas_Wl_Selection_Data selection_data[ECORE_EVAS_SELECTION_BUFFER_LAST];
62 Ecore_Wl2_Offer *external_offer;
51 struct 63 struct
52 { 64 {
53 Eina_Bool supported : 1; 65 Eina_Bool supported : 1;