INF("Delivery request on seat %d in buffer %d", seat, buffer);
- buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_FALSE);
- EINA_SAFETY_ON_NULL_GOTO(buffers, free_everything);
- content = buffers->selection_buffer[buffer];
+ if (buffer == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
+ {
+ buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_GOTO(buffers, free_everything);
+ content = buffers->selection_buffer[buffer];
+ }
+ else
+ {
+ if (eina_streq(type, "application/x-elementary-markup"))
+ type = "text/plain;charset=utf-8";
+ content = eina_hash_find(ee->cnp_selection_buffers, type);
+ }
+
EINA_SAFETY_ON_NULL_GOTO(content, free_everything);
+
if (!eina_streq(type, eina_content_type_get(content)))
converted = eina_content_convert(content, type);
else
if (converted && content && !eina_streq(type, eina_content_type_get(content)))
eina_content_free(converted);
+ INF("Delivery request, type:%s, result:%d", type, result);
return result;
}
static void
-_cancel_cb(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer buffer)
+_cancel_cb(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer buffer, const char *type)
{
- Ecore_Evas_Selection_Seat_Buffers *buffers;
-
INF("Cancel request on seat %d in buffer %d", seat, buffer);
- buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_FALSE);
- EINA_SAFETY_ON_FALSE_RETURN(buffers);
- EINA_SAFETY_ON_FALSE_RETURN(buffers->selection_buffer[buffer]);
- eina_content_free(buffers->selection_buffer[buffer]);
- buffers->selection_buffer[buffer] = NULL;
-
if (buffer == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
{
+ Ecore_Evas_Selection_Seat_Buffers *buffers;
+ buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN(buffers);
+ EINA_SAFETY_ON_FALSE_RETURN(buffers->selection_buffer[buffer]);
+ eina_content_free(buffers->selection_buffer[buffer]);
+ buffers->selection_buffer[buffer] = NULL;
+
ee->drag.rep = NULL;
if (ee->drag.free)
ee->drag.free(ee, seat, ee->drag.data, EINA_FALSE);
ee->drag.free = NULL;
}
+ else
+ {
+ if (ee->cnp_selection_buffers && type)
+ {
+ Eina_Content *content = eina_hash_find(ee->cnp_selection_buffers, type);
+ if (content)
+ {
+ eina_content_free(content);
+ eina_hash_del(ee->cnp_selection_buffers, type, NULL);
+ INF("Cancel request, type:%s", type);
+ }
+ }
+ }
}
#define CALL(call) (ee->engine.func->fn_ ##call ? : fallback_ ##call)
buffers = _fetch_selection_buffers_of_seat(ee, seat, EINA_TRUE);
+ const char *type = NULL;
if (content)
- available_type = eina_content_possible_conversions(content);
+ {
+ available_type = eina_content_possible_conversions(content);
+ type = eina_content_type_get(content);
+ if (eina_streq(type, "application/x-elementary-markup"))
+ type = "text/plain;charset=utf-8";
+ }
- success = CALL(selection_claim)(ee, seat, buffer, _iterator_to_array(available_type, content ? eina_content_type_get(content) : NULL), content ? _deliver_cb : NULL, content ? _cancel_cb : NULL);
+ INF("Selection set type:%s", type);
+ success = CALL(selection_claim)(ee, seat, buffer, _iterator_to_array(available_type, content ? type : NULL), content ? _deliver_cb : NULL, content ? _cancel_cb : NULL);
if (success)
{
- EINA_SAFETY_ON_FALSE_RETURN_VAL(buffers->selection_buffer[buffer] == NULL, EINA_FALSE);
- //keep this after the claim, the claim might call cancel, which would overwrite this.
+ if (ee->cnp_selection_buffers)
+ {
+ Eina_Content *old_content = eina_hash_find(ee->cnp_selection_buffers, type);
+ if (old_content)
+ {
+ eina_content_free(old_content);
+ eina_hash_del(ee->cnp_selection_buffers, type, NULL);
+ INF("Selection claim, old content free, type:%s\n", type);
+ }
+ }
+
+ if (!ee->cnp_selection_buffers)
+ ee->cnp_selection_buffers = eina_hash_string_superfast_new(NULL);
+
+ eina_hash_add(ee->cnp_selection_buffers, type, content);
+
+ // just keep last content.
buffers->selection_buffer[buffer] = content;
}
else if (content)
EINA_LIST_FREE(wdata->devices_list, device)
free(device);
+ const char *type;
+ EINA_LIST_FREE(wdata->set_types, type)
+ eina_stringshare_del(type);
+
free(wdata);
ecore_event_window_unregister(ee->prop.window);
return r;
}
+static char*
+_cnp_type_to_mime_type(Ecore_Evas_Selection_Cnp_Type cnp_type)
+{
+ switch (cnp_type)
+ {
+ case ECORE_EVAS_SELECTION_CNP_TYPE_TEXT:
+ return "text/plain;charset=utf-8";
+
+ case ECORE_EVAS_SELECTION_CNP_TYPE_HTML:
+ return "application/xhtml+xml";
+
+ case ECORE_EVAS_SELECTION_CNP_TYPE_URI:
+ return "text/uri-list";
+
+ case ECORE_EVAS_SELECTION_CNP_TYPE_VCARD:
+ return "text/vcard";
+
+ case ECORE_EVAS_SELECTION_CNP_TYPE_IMAGE:
+ return ""; // use wdata->reserved_image_type
+
+ default:
+ return "text/plain;charset=utf-8";
+ }
+}
+
+static Ecore_Evas_Selection_Cnp_Type
+_mime_type_to_cnp_type(const char *mime_type)
+{
+ Ecore_Evas_Selection_Cnp_Type cnp_type = ECORE_EVAS_SELECTION_CNP_TYPE_TEXT;
+
+ if (eina_streq(mime_type, "text/plain;charset=utf-8") ||
+ eina_streq(mime_type, "application/x-elementary-markup"))
+ cnp_type = ECORE_EVAS_SELECTION_CNP_TYPE_TEXT;
+ else if (eina_streq(mime_type, "application/xhtml+xml"))
+ cnp_type = ECORE_EVAS_SELECTION_CNP_TYPE_HTML;
+ else if (eina_streq(mime_type, "text/uri-list"))
+ cnp_type = ECORE_EVAS_SELECTION_CNP_TYPE_URI;
+ else if (eina_streq(mime_type, "text/vcard"))
+ cnp_type = ECORE_EVAS_SELECTION_CNP_TYPE_VCARD;
+ else if (strcasestr(mime_type, "image/"))
+ cnp_type = ECORE_EVAS_SELECTION_CNP_TYPE_IMAGE;
+
+ return cnp_type;
+}
+
+static void
+_clear_reserved_offer_receive_types(Ecore_Evas *ee)
+{
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+
+ for (int i = 0 ; i < ECORE_EVAS_SELECTION_CNP_TYPE_LAST ; i ++)
+ wdata->reserved_types[i] = EINA_FALSE;
+}
+
+static void
+_reserve_offer_receive(Ecore_Evas *ee, Ecore_Evas_Selection_Cnp_Type cnp_type)
+{
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+
+ if (cnp_type < ECORE_EVAS_SELECTION_CNP_TYPE_LAST)
+ wdata->reserved_types[cnp_type] = EINA_TRUE;
+}
+
+static Ecore_Evas_Selection_Cnp_Type
+_get_reserved_offer_receive_type(Ecore_Evas *ee)
+{
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ Ecore_Evas_Selection_Cnp_Type reserved_cnp_type = ECORE_EVAS_SELECTION_CNP_TYPE_LAST;
+
+ for (int i = 0 ; i < ECORE_EVAS_SELECTION_CNP_TYPE_LAST ; i ++)
+ {
+ if (wdata->reserved_types[i])
+ {
+ reserved_cnp_type = i;
+ wdata->reserved_types[i] = EINA_FALSE;
+ break;
+ }
+ }
+ return reserved_cnp_type;
+}
+
static void
_reeval_seat(unsigned int *seat, Ecore_Evas *ee)
{
}
static inline void
-_clear_selection(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection)
+_clear_selection(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, const char *type)
{
Ecore_Evas_Engine_Wl_Data *edata = ee->engine.data;
- Ecore_Evas_Selection_Callbacks *cbs = &edata->selection_data[selection].callbacks;
+ Ecore_Evas_Selection_Callbacks *cbs;
- EINA_SAFETY_ON_FALSE_RETURN(cbs->cancel);
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
+ {
+ cbs = &edata->selection_data[selection].callbacks;
+ }
+ else
+ {
+ if (type)
+ {
+ Ecore_Evas_Selection_Cnp_Type cnp_type = _mime_type_to_cnp_type(type);
+ cbs = &edata->selection_datas[cnp_type].callbacks;
+ }
+ else
+ {
+ cbs = &edata->selection_data[selection].callbacks;
+ }
+ }
- cbs->cancel(ee, seat, selection);
+ EINA_SAFETY_ON_FALSE_RETURN(cbs->cancel);
+ cbs->cancel(ee, seat, selection, type);
eina_array_free(cbs->available_types);
memset(cbs, 0, sizeof(Ecore_Evas_Selection_Callbacks));
}
Ecore_Evas_Selection_Callbacks *cbs;
edata = ee->engine.data;
- sdata = &edata->selection_data[selection];
- cbs = &sdata->callbacks;
+ char *type = NULL;
+
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
+ {
+ sdata = &edata->selection_data[selection];
+ }
+ else
+ {
+ type = eina_array_data_get(available_types, 0u);
+ Ecore_Evas_Selection_Cnp_Type cnp_type = _mime_type_to_cnp_type(type);
+ sdata = &edata->selection_datas[cnp_type];
+ }
+ cbs = &sdata->callbacks;
if (cbs->cancel)
{
- _clear_selection(ee, seat, selection);
+ _clear_selection(ee, seat, selection, type);
}
cbs->delivery = delivery;
static Eina_Bool
_ecore_evas_wl_selection_claim(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Selection_Internal_Delivery delivery, Ecore_Evas_Selection_Internal_Cancel cancel)
{
- Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
- Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
- char *tmp_array[eina_array_count(available_types) + 1];
-
if (selection == ECORE_EVAS_SELECTION_BUFFER_SELECTION_BUFFER)
{
_store_selection_cbs(ee, seat, selection, available_types, delivery, cancel);
return EINA_TRUE;
}
- _reeval_seat(&seat, ee);
- _store_selection_cbs(ee, seat, selection, available_types, delivery, cancel);
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ unsigned int type_count = eina_array_count(available_types);
+ if (type_count == 0u)
+ {
+ ERR("available_types is empty");
+ return EINA_FALSE;
+ }
- for (unsigned int i = 0; i < eina_array_count(available_types); ++i)
+ char *tmp_array[type_count + 1];
+
+ for (unsigned int i = 0; i < type_count; ++i)
{
tmp_array[i] = eina_array_data_get(available_types, i);
}
- tmp_array[eina_array_count(available_types)] = NULL;
+ tmp_array[type_count] = NULL;
- data->sent_serial = ecore_wl2_dnd_selection_set(_fetch_input(ee, seat), (const char**)tmp_array);
- return EINA_TRUE;
-}
+ char *mime_type = NULL;
+ for (unsigned int i = 0; i < type_count; ++i)
+ {
+ char *temp = eina_array_data_get(available_types, i);
+ if (eina_streq(temp, "application/x-elementary-markup"))
+ continue;
+ mime_type = temp;
+ break;
+ }
-static Eina_Future*
-_ecore_evas_wl_selection_request(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *acceptable_types)
-{
- Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
- Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
- Ecore_Wl2_Input *input;
- Ecore_Wl2_Offer *offer = NULL;
- Eina_Future *future;
+ Ecore_Evas_Selection_Cnp_Type cnp_type = _mime_type_to_cnp_type(mime_type);
+ Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_datas[cnp_type];
_reeval_seat(&seat, ee);
- input = _fetch_input(ee, seat);
+ _store_selection_cbs(ee, seat, selection, available_types, delivery, cancel);
- if (data->delivery)
- {
- eina_promise_reject(data->delivery, ecore_evas_request_replaced);
- data->delivery = NULL;
- }
- data->delivery = efl_loop_promise_new(efl_main_loop_get());
- future = eina_future_new(data->delivery);
+ data->sent_serial = ecore_wl2_dnd_selection_set(_fetch_input(ee, seat), (const char**)tmp_array);
+ ERR("Selection set serial:%u, type:%s", data->sent_serial, mime_type);
- if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
+ if (wdata->serial == data->sent_serial && !eina_streq(wdata->last_type, mime_type))
{
- offer = data->offer = wdata->external_offer;
+ bool type_exists = false;
+
+ Eina_List *l;
+ const char *type;
+ EINA_LIST_FOREACH(wdata->set_types, l, type)
+ {
+ if (eina_streq(type, mime_type))
+ {
+ type_exists = true;
+ break;
+ }
+ }
+
+ if (!type_exists)
+ {
+ wdata->set_types = eina_list_append(wdata->set_types, eina_stringshare_add(mime_type));
+ int type_count = eina_list_count(wdata->set_types);
+
+ const char* types[type_count + 1];
+ int index = 0;
+
+ Eina_List *list;
+ const char *type;
+ EINA_LIST_FOREACH(wdata->set_types, list, type)
+ {
+ types[index] = type;
+ ERR("Selection set multi types, serial:%u, type:%s", data->sent_serial, types[index]);
+ index++;
+ }
+ types[type_count] = NULL;
+
+ data->sent_serial = ecore_wl2_dnd_selection_set(_fetch_input(ee, seat), types);
+ }
+ else
+ {
+ const char *type;
+ EINA_LIST_FREE(wdata->set_types, type)
+ eina_stringshare_del(type);
+ wdata->set_types = NULL;
+ wdata->set_types = eina_list_append(wdata->set_types, eina_stringshare_add(mime_type));
+ }
}
- else if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ else
{
- offer = data->offer = ecore_wl2_dnd_selection_get(input);
+ const char *type;
+ EINA_LIST_FREE(wdata->set_types, type)
+ eina_stringshare_del(type);
+ wdata->set_types = NULL;
+ wdata->set_types = eina_list_append(wdata->set_types, eina_stringshare_add(mime_type));
}
- if (!offer)
- {
- eina_promise_reject(data->delivery, ecore_evas_no_selection);
- data->delivery = NULL;
- }
- else
+ wdata->serial = data->sent_serial;
+ wdata->last_type = mime_type;
+
+ return EINA_TRUE;
+}
+
+
+static Eina_Future*
+_ecore_evas_wl_selection_request(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *acceptable_types)
+{
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
{
- Eina_Array *available_types = ecore_wl2_offer_mimes_get(offer);
- char *selected_type = NULL;
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
+ Ecore_Wl2_Input *input;
+ Ecore_Wl2_Offer *offer = NULL;
+ Eina_Future *future;
+
+ _reeval_seat(&seat, ee);
+ input = _fetch_input(ee, seat);
- for (unsigned int i = 0; i < eina_array_count(available_types) && !selected_type; ++i)
+ if (data->delivery)
{
- char *available_type = eina_array_data_get(available_types, i);
- for (unsigned int j = 0; j < eina_array_count(acceptable_types) && !selected_type; ++j)
- {
- char *acceptable_type = eina_array_data_get(acceptable_types, j);
- if (eina_streq(acceptable_type, available_type))
- {
- selected_type = available_type;
- data->later_convert = NULL;
- break;
- }
+ eina_promise_reject(data->delivery, ecore_evas_request_replaced);
+ data->delivery = NULL;
+ }
+ data->delivery = efl_loop_promise_new(efl_main_loop_get());
+ future = eina_future_new(data->delivery);
+ offer = data->offer = wdata->external_offer;
+
+ if (!offer)
+ {
+ eina_promise_reject(data->delivery, ecore_evas_no_selection);
+ data->delivery = NULL;
+ }
+ else
+ {
+ Eina_Array *available_types = ecore_wl2_offer_mimes_get(offer);
+ char *selected_type = NULL;
- const char *convert_available_type;
- Eina_Iterator *convertions = eina_content_converter_possible_conversions(available_type);
- EINA_ITERATOR_FOREACH(convertions, convert_available_type)
+ for (unsigned int i = 0; i < eina_array_count(available_types) && !selected_type; ++i)
+ {
+ char *available_type = eina_array_data_get(available_types, i);
+ for (unsigned int j = 0; j < eina_array_count(acceptable_types) && !selected_type; ++j)
{
- if (eina_streq(convert_available_type, acceptable_type))
+ char *acceptable_type = eina_array_data_get(acceptable_types, j);
+ if (eina_streq(acceptable_type, available_type))
{
selected_type = available_type;
- data->later_convert = acceptable_type;
+ data->later_convert = NULL;
+ break;
+ }
+
+ const char *convert_available_type;
+ Eina_Iterator *convertions = eina_content_converter_possible_conversions(available_type);
+ EINA_ITERATOR_FOREACH(convertions, convert_available_type)
+ {
+ if (eina_streq(convert_available_type, acceptable_type))
+ {
+ selected_type = available_type;
+ data->later_convert = acceptable_type;
+ }
}
+ eina_iterator_free(convertions);
}
- eina_iterator_free(convertions);
}
-
+ if (selected_type)
+ {
+ ecore_wl2_offer_receive(offer, selected_type);
+ ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+ }
+ else
+ {
+ eina_promise_reject(data->delivery, ecore_evas_no_matching_type);
+ data->delivery = NULL;
+ }
}
- if (selected_type)
+
+ return future;
+ }
+ else
+ {
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ Ecore_Evas_Wl_Selection_Data *data;
+
+ Ecore_Wl2_Input *input;
+ Ecore_Wl2_Offer *offer = NULL;
+ Eina_Future *future;
+
+ _reeval_seat(&seat, ee);
+ input = _fetch_input(ee, seat);
+
+ offer = ecore_wl2_dnd_selection_get(input);
+ if (!offer)
{
- ecore_wl2_offer_receive(offer, selected_type);
- ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+ wdata->last_offer = NULL;
+ _clear_reserved_offer_receive_types(ee);
+ future = eina_future_new(NULL);
+ ERR("offer is null.");
}
else
{
- eina_promise_reject(data->delivery, ecore_evas_no_matching_type);
- data->delivery = NULL;
+ Eina_Array *available_types = ecore_wl2_offer_mimes_get(offer);
+ char *selected_type = NULL;
+ char *later_convert = NULL;
+
+ for (unsigned int i = 0; i < eina_array_count(available_types) && !selected_type; ++i)
+ {
+ char *available_type = eina_array_data_get(available_types, i);
+ for (unsigned int j = 0; j < eina_array_count(acceptable_types) && !selected_type; ++j)
+ {
+ char *acceptable_type = eina_array_data_get(acceptable_types, j);
+ if (eina_streq(acceptable_type, available_type))
+ {
+ selected_type = available_type;
+ later_convert = NULL;
+ }
+
+ const char *convert_available_type;
+ Eina_Iterator *convertions = eina_content_converter_possible_conversions(available_type);
+ EINA_ITERATOR_FOREACH(convertions, convert_available_type)
+ {
+ if (eina_streq(convert_available_type, acceptable_type))
+ {
+ selected_type = available_type;
+ later_convert = acceptable_type;
+ }
+ }
+ eina_iterator_free(convertions);
+ }
+ }
+
+ if (selected_type)
+ {
+ Ecore_Evas_Selection_Cnp_Type cnp_type = _mime_type_to_cnp_type(selected_type);
+ data = &wdata->selection_datas[cnp_type];
+ if (data->delivery)
+ {
+ eina_promise_reject(data->delivery, ecore_evas_request_replaced);
+ data->delivery = NULL;
+ }
+
+ ERR("Selection request, type:%s, index:%d", selected_type, cnp_type);
+
+ data->delivery = efl_loop_promise_new(efl_main_loop_get());
+ future = eina_future_new(data->delivery);
+
+ data->offer = offer;
+ data->later_convert = later_convert;
+
+ if (wdata->last_offer == offer && wdata->last_delivery)
+ {
+ _reserve_offer_receive(ee, cnp_type);
+ if (cnp_type == ECORE_EVAS_SELECTION_CNP_TYPE_IMAGE)
+ wdata->reserved_image_type = selected_type;
+ }
+ else
+ {
+ ERR("Selection request offer receive, type:%s", selected_type);
+ _clear_reserved_offer_receive_types(ee);
+ ecore_wl2_offer_receive(offer, selected_type);
+ ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+ }
+
+ wdata->last_delivery = data->delivery;
+ }
+ else
+ {
+ ERR("no matching type.");
+ wdata->last_delivery = NULL;
+ future = eina_future_new(NULL);
+ }
+
+ wdata->last_offer = offer;
}
- }
- return future;
+ return future;
+ }
}
static Eina_Bool
Ecore_Evas_Wl_Selection_Data *selection = NULL;
Delayed_Writing *forign_slice = calloc(1, sizeof(Delayed_Writing));
Ecore_Evas_Selection_Buffer buffer = ECORE_EVAS_SELECTION_BUFFER_LAST;
+ Ecore_Evas_Selection_Cnp_Type cnp_type = _mime_type_to_cnp_type(ev->type);
- if (ev->serial == wdata->selection_data[ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER].sent_serial)
+ if (ev->serial == wdata->selection_datas[cnp_type].sent_serial)
buffer = ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER;
else if (ev->serial == wdata->selection_data[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER].sent_serial)
{
goto end;
}
- selection = &wdata->selection_data[buffer];
+ if (buffer == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ {
+ selection = &wdata->selection_datas[cnp_type];
+ }
+ else if (buffer == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
+ {
+ selection = &wdata->selection_data[buffer];
+ }
+
EINA_SAFETY_ON_NULL_GOTO(selection, end);
EINA_SAFETY_ON_NULL_GOTO(selection->callbacks.delivery, end);
EINA_SAFETY_ON_FALSE_GOTO(selection->callbacks.delivery(ee, ev->seat, buffer, ev->type, &forign_slice->slice), end);
+
+ ERR("Send data, type:%s", ev->type);
ecore_main_fd_handler_add(ev->fd, ECORE_FD_WRITE, _write_to_fd, forign_slice, NULL, NULL);
return ECORE_CALLBACK_PASS_ON;
Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
Ecore_Wl2_Event_Offer_Data_Ready *ready = event;
Ecore_Evas_Selection_Buffer selection = ECORE_EVAS_SELECTION_BUFFER_LAST;
+ Ecore_Evas_Selection_Cnp_Type cnp_type = ECORE_EVAS_SELECTION_CNP_TYPE_LAST;
if ((!ready->data) || (ready->len < 1))
{
ERR("no selection data");
return ECORE_CALLBACK_PASS_ON;
}
+
+ bool need_break = false;
for (int i = 0; i < ECORE_EVAS_SELECTION_BUFFER_LAST; ++i)
{
- if (wdata->selection_data[i].offer == ready->offer)
+ if (i == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
{
- selection = i;
- break;
+ if (wdata->selection_data[i].offer == ready->offer)
+ {
+ selection = i;
+ break;
+ }
}
+ else
+ {
+ for (int j = 0 ; j < ECORE_EVAS_SELECTION_CNP_TYPE_LAST; ++j)
+ {
+ if (wdata->selection_datas[j].offer == ready->offer && j == (int)_mime_type_to_cnp_type(ready->mimetype))
+ {
+ selection = ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER;
+ cnp_type = j;
+ need_break = true;
+ break;
+ }
+ }
+ }
+
+ if (need_break)
+ break;
}
if (selection == ECORE_EVAS_SELECTION_BUFFER_LAST)
return ECORE_CALLBACK_PASS_ON;
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER && cnp_type == ECORE_EVAS_SELECTION_CNP_TYPE_LAST)
+ return ECORE_CALLBACK_PASS_ON;
+
+ ERR("Receive data, type:%s, data:%s", ready->mimetype, (char*)ready->data);
+
//Now deliver the content
Eina_Slice slice;
- if (eina_str_has_prefix(ready->mimetype,"text"))
+ if (eina_str_has_prefix(ready->mimetype, "text"))
{
//ensure that we always have a \0 at the end, there is no assertion that \0 is included here.
slice.len = ready->len + 1;
Eina_Content *content = eina_content_new(slice, ready->mimetype);
- if (wdata->selection_data[selection].later_convert)
+ Ecore_Evas_Wl_Selection_Data *selection_data;
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
{
- Eina_Content *tmp = eina_content_convert(content, wdata->selection_data[selection].later_convert);
- wdata->selection_data[selection].later_convert = NULL;
+ selection_data = &wdata->selection_data[selection];
+ }
+ else if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ {
+ selection_data = &wdata->selection_datas[cnp_type];
+ }
+
+ if (selection_data->later_convert)
+ {
+ Eina_Content *tmp = eina_content_convert(content, selection_data->later_convert);
+ selection_data->later_convert = NULL;
eina_content_free(content);
content = tmp;
}
- eina_promise_resolve(wdata->selection_data[selection].delivery, eina_value_content_init(content));
- wdata->selection_data[selection].delivery = NULL;
+ INF("Receive data resolve, type:%s", eina_content_type_get(content));
+ eina_promise_resolve(selection_data->delivery, eina_value_content_init(content));
+ selection_data->delivery = NULL;
+
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ wdata->last_delivery = NULL;
+
eina_content_free(content);
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ {
+ Ecore_Evas_Selection_Cnp_Type reserved_cnp_type = _get_reserved_offer_receive_type(ee);
+
+ if (reserved_cnp_type < ECORE_EVAS_SELECTION_CNP_TYPE_LAST)
+ {
+ char* reserved_type = _cnp_type_to_mime_type(reserved_cnp_type);
+ if (reserved_cnp_type == ECORE_EVAS_SELECTION_CNP_TYPE_IMAGE)
+ reserved_type = wdata->reserved_image_type;
+
+ if (reserved_type)
+ {
+ Ecore_Wl2_Display* display = ecore_wl2_connected_display_get(NULL);
+ Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(display);
+
+ ERR("Selection request offer receive, type:%s", reserved_type);
+ ecore_wl2_offer_receive(ready->offer, reserved_type);
+ ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+ }
+ }
+ }
+
return ECORE_CALLBACK_PASS_ON;
}
wdata->selection_data[i].callbacks.delivery = NULL;
wdata->selection_data[i].callbacks.cancel = NULL;
}
+
+ for (int i = 0; i < ECORE_EVAS_SELECTION_CNP_TYPE_LAST; ++i)
+ {
+ wdata->selection_datas[i].callbacks.available_types = NULL;
+ wdata->selection_datas[i].callbacks.delivery = NULL;
+ wdata->selection_datas[i].callbacks.cancel = NULL;
+ wdata->reserved_types[i] = EINA_FALSE;
+ }
+
+ wdata->serial = UINT32_MAX;
+ wdata->last_type = NULL;
+ wdata->set_types = NULL;
+ wdata->last_offer = NULL;
+ wdata->last_delivery = NULL;
+ wdata->reserved_image_type = NULL;
}
static Eina_Bool
static Eina_Bool
_ecore_evas_wl_dnd_stop(Ecore_Evas *ee, unsigned int seat)
{
- _clear_selection(ee, seat, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER);
+ _clear_selection(ee, seat, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER, NULL);
_reeval_seat(&seat, ee);
ecore_wl2_dnd_drag_end(_fetch_input(ee, seat));
return EINA_TRUE;