2016-04-20 05:45:09 -07:00
|
|
|
/*
|
|
|
|
* Copyright © 2008 Kristian Høgsberg
|
|
|
|
* Copyright © 2012-2013 Collabora, Ltd.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
* Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2012-02-28 13:55:51 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2012-08-28 23:35:02 -07:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/epoll.h>
|
2012-02-28 13:55:51 -08:00
|
|
|
#include "ecore_wl_private.h"
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* local structures */
|
2016-11-18 02:53:14 -08:00
|
|
|
struct _dnd_source
|
|
|
|
{
|
|
|
|
Ecore_Wl_Dnd_Source *source;
|
|
|
|
int read_fd;
|
|
|
|
};
|
|
|
|
|
2012-08-28 23:35:02 -07:00
|
|
|
struct _dnd_task
|
|
|
|
{
|
|
|
|
void *data;
|
|
|
|
Ecore_Fd_Cb cb;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _dnd_read_ctx
|
|
|
|
{
|
|
|
|
int epoll_fd;
|
|
|
|
struct epoll_event *ep;
|
|
|
|
};
|
|
|
|
|
2012-02-28 13:55:51 -08:00
|
|
|
/* local function prototypes */
|
2013-05-28 03:44:53 -07:00
|
|
|
static void _ecore_wl_dnd_selection_data_receive(Ecore_Wl_Dnd_Source *source, const char *type);
|
|
|
|
static Eina_Bool _ecore_wl_dnd_selection_data_read(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED);
|
|
|
|
static void _ecore_wl_dnd_selection_data_ready_cb_free(void *data EINA_UNUSED, void *event);
|
|
|
|
static Eina_Bool _ecore_wl_dnd_selection_cb_idle(void *data);
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
static void _ecore_wl_dnd_source_cb_target(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type EINA_UNUSED);
|
2014-09-19 06:04:49 -07:00
|
|
|
static void _ecore_wl_dnd_source_cb_target_free(void *data EINA_UNUSED, void *event);
|
2013-05-28 03:44:53 -07:00
|
|
|
static void _ecore_wl_dnd_source_cb_send(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type, int32_t fd);
|
|
|
|
static void _ecore_wl_dnd_source_cb_send_free(void *data EINA_UNUSED, void *event);
|
|
|
|
static void _ecore_wl_dnd_source_cb_cancelled(void *data EINA_UNUSED, struct wl_data_source *source);
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
static void _ecore_wl_dnd_offer_cb_offer(void *data, struct wl_data_offer *data_offer EINA_UNUSED, const char *type);
|
|
|
|
|
|
|
|
/* local wayland interfaces */
|
2015-03-13 18:40:59 -07:00
|
|
|
static const struct wl_data_source_listener
|
|
|
|
_ecore_wl_dnd_source_listener =
|
2012-02-28 13:55:51 -08:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_source_cb_target,
|
|
|
|
_ecore_wl_dnd_source_cb_send,
|
|
|
|
_ecore_wl_dnd_source_cb_cancelled
|
2012-02-28 13:55:51 -08:00
|
|
|
};
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
static const struct wl_data_offer_listener
|
|
|
|
_ecore_wl_dnd_offer_listener =
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_offer_cb_offer
|
2012-08-28 23:35:02 -07:00
|
|
|
};
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/**
|
|
|
|
* @deprecated use ecore_wl_dnd_selection_set
|
2015-03-13 18:40:59 -07:00
|
|
|
* @since 1.7
|
2013-05-28 03:44:53 -07:00
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EINA_DEPRECATED EAPI Eina_Bool
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_wl_dnd_set_selection(Ecore_Wl_Dnd *dnd, const char **types_offered)
|
|
|
|
{
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
return ecore_wl_dnd_selection_set(dnd->input, types_offered);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated use ecore_wl_dnd_selection_get
|
2015-03-13 18:40:59 -07:00
|
|
|
* @since 1.7
|
2013-05-28 03:44:53 -07:00
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EINA_DEPRECATED EAPI Eina_Bool
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_wl_dnd_get_selection(Ecore_Wl_Dnd *dnd, const char *type)
|
|
|
|
{
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
return ecore_wl_dnd_selection_get(dnd->input, type);
|
|
|
|
}
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/**
|
|
|
|
* @deprecated Do Not Use
|
|
|
|
* @since 1.7
|
|
|
|
*/
|
|
|
|
EINA_DEPRECATED EAPI Ecore_Wl_Dnd *
|
|
|
|
ecore_wl_dnd_get(void)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
return NULL;
|
2012-08-28 23:35:02 -07:00
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/**
|
|
|
|
* @deprecated use ecore_wl_dnd_drag_start
|
|
|
|
* @since 1.7
|
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EINA_DEPRECATED EAPI Eina_Bool
|
2012-11-25 01:55:32 -08:00
|
|
|
ecore_wl_dnd_start_drag(Ecore_Wl_Dnd *dnd EINA_UNUSED)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
return EINA_FALSE;
|
2012-08-28 23:35:02 -07:00
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/**
|
|
|
|
* @deprecated use ecore_wl_dnd_selection_owner_has
|
|
|
|
* @since 1.7
|
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EINA_DEPRECATED EAPI Eina_Bool
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_wl_dnd_selection_has_owner(Ecore_Wl_Dnd *dnd)
|
|
|
|
{
|
|
|
|
return ecore_wl_dnd_selection_owner_has(dnd->input);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @ingroup Ecore_Wl_Dnd_Group
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EAPI Eina_Bool
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_wl_dnd_selection_set(Ecore_Wl_Input *input, const char **types_offered)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
struct wl_data_device_manager *man;
|
2012-08-28 23:35:02 -07:00
|
|
|
const char **type;
|
2013-05-28 03:44:53 -07:00
|
|
|
char **t;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!input) return EINA_FALSE;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
man = input->display->wl.data_device_manager;
|
|
|
|
|
|
|
|
/* free any old types offered */
|
|
|
|
if (input->data_types.data)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
wl_array_for_each(t, &input->data_types)
|
|
|
|
free(*t);
|
|
|
|
wl_array_release(&input->data_types);
|
|
|
|
wl_array_init(&input->data_types);
|
2012-08-28 23:35:02 -07:00
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
input->data_source = NULL;
|
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
if (!types_offered[0]) return EINA_FALSE;
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* try to create a new data source */
|
|
|
|
if (!(input->data_source = wl_data_device_manager_create_data_source(man)))
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
/* add these types to the data source */
|
|
|
|
for (type = types_offered; *type; type++)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
t = wl_array_add(&input->data_types, sizeof(*t));
|
2018-04-04 21:18:03 -07:00
|
|
|
if (t)
|
|
|
|
{
|
|
|
|
*t = strdup(*type);
|
|
|
|
wl_data_source_offer(input->data_source, *t);
|
|
|
|
}
|
2012-08-28 23:35:02 -07:00
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* add a listener for data source events */
|
2015-03-13 18:40:59 -07:00
|
|
|
wl_data_source_add_listener(input->data_source,
|
2013-05-28 03:44:53 -07:00
|
|
|
&_ecore_wl_dnd_source_listener, input);
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* set the selection */
|
2015-03-13 18:40:59 -07:00
|
|
|
wl_data_device_set_selection(input->data_device, input->data_source,
|
2013-05-28 03:44:53 -07:00
|
|
|
input->display->serial);
|
2012-08-28 23:35:02 -07:00
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/**
|
|
|
|
* @ingroup Ecore_Wl_Dnd_Group
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EAPI Eina_Bool
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_wl_dnd_selection_get(Ecore_Wl_Input *input, const char *type)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
char **t;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* check for valid input and selection source */
|
|
|
|
if ((!input) || (!input->selection_source)) return EINA_FALSE;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
for (t = input->selection_source->types.data; *t; t++)
|
|
|
|
{
|
|
|
|
if (!strcmp(type, *t)) break;
|
|
|
|
}
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!*t) return EINA_FALSE;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_selection_data_receive(input->selection_source, type);
|
2012-08-28 23:35:02 -07:00
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/**
|
|
|
|
* @ingroup Ecore_Wl_Dnd_Group
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EAPI Eina_Bool
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_wl_dnd_selection_owner_has(Ecore_Wl_Input *input)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!input) return EINA_FALSE;
|
2012-08-28 23:35:02 -07:00
|
|
|
return (input->selection_source != NULL);
|
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/**
|
|
|
|
* @ingroup Ecore_Wl_Dnd_Group
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EAPI Eina_Bool
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_wl_dnd_selection_clear(Ecore_Wl_Input *input)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* check for valid input */
|
|
|
|
if (!input) return EINA_FALSE;
|
|
|
|
|
|
|
|
/* set the selection to NULL */
|
2015-03-13 18:40:59 -07:00
|
|
|
wl_data_device_set_selection(input->data_device, NULL,
|
2013-05-28 03:44:53 -07:00
|
|
|
input->display->serial);
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
2012-08-28 23:35:02 -07:00
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/**
|
|
|
|
* @ingroup Ecore_Wl_Dnd_Group
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EAPI void
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_wl_dnd_drag_start(Ecore_Wl_Input *input, Ecore_Wl_Window *win, Ecore_Wl_Window *dragwin, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
struct wl_surface *drag_surface;
|
2014-12-01 06:58:07 -08:00
|
|
|
struct wl_surface *origin_surface;
|
2013-05-28 03:44:53 -07:00
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* check for valid input. if not, get the default one */
|
|
|
|
if (!input) input = _ecore_wl_disp->input;
|
|
|
|
|
|
|
|
/* check for valid data source */
|
|
|
|
if (!input->data_source) return;
|
|
|
|
|
|
|
|
/* get the surface from this drag window */
|
|
|
|
drag_surface = ecore_wl_window_surface_get(dragwin);
|
|
|
|
|
|
|
|
/* release any existing grabs */
|
|
|
|
ecore_wl_input_ungrab(input);
|
|
|
|
|
|
|
|
/* add a listener for data source events */
|
2015-03-13 18:40:59 -07:00
|
|
|
wl_data_source_add_listener(input->data_source,
|
2013-05-28 03:44:53 -07:00
|
|
|
&_ecore_wl_dnd_source_listener, input);
|
|
|
|
|
|
|
|
/* start the drag */
|
2014-12-01 06:58:07 -08:00
|
|
|
if ((origin_surface = ecore_wl_window_surface_get(win)))
|
|
|
|
{
|
2015-03-13 18:40:59 -07:00
|
|
|
wl_data_device_start_drag(input->data_device, input->data_source,
|
|
|
|
origin_surface, drag_surface,
|
2014-12-01 06:58:07 -08:00
|
|
|
input->display->serial);
|
2013-05-28 03:44:53 -07:00
|
|
|
|
2015-01-13 08:23:27 -08:00
|
|
|
/* set pointer image */
|
|
|
|
ecore_wl_input_cursor_from_name_set(input, "move");
|
|
|
|
}
|
2013-05-28 03:44:53 -07:00
|
|
|
|
|
|
|
/* NB: Below code disabled for now
|
2015-03-13 18:40:59 -07:00
|
|
|
*
|
|
|
|
* This Was for adjusting the "drag icon" to be centered on the mouse
|
2013-05-28 03:44:53 -07:00
|
|
|
* based on the hotspot, but it crashes for some reason :(
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* struct wl_buffer *drag_buffer; */
|
|
|
|
/* struct wl_cursor_image *cursor; */
|
|
|
|
/* int cx = 0, cy = 0; */
|
|
|
|
/* drag_buffer = wl_surface_get_user_data(drag_surface); */
|
|
|
|
/* cursor = input->cursor->images[input->cursor_current_index]; */
|
|
|
|
/* cx = cursor->hotspot_x - x; */
|
|
|
|
/* cy = cursor->hotspot_y - y; */
|
|
|
|
/* wl_surface_attach(drag_surface, drag_buffer, cx, cy); */
|
|
|
|
/* wl_surface_damage(drag_surface, 0, 0, w, h); */
|
|
|
|
/* wl_surface_commit(drag_surface); */
|
|
|
|
}
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/**
|
|
|
|
* @ingroup Ecore_Wl_Dnd_Group
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EAPI void
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_wl_dnd_drag_end(Ecore_Wl_Input *input)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Event_Dnd_End *ev;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* check for valid input. if not, get the default one */
|
|
|
|
if (!input) input = _ecore_wl_disp->input;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (input->data_types.data)
|
|
|
|
{
|
|
|
|
char **t;
|
|
|
|
|
|
|
|
wl_array_for_each(t, &input->data_types)
|
|
|
|
free(*t);
|
|
|
|
wl_array_release(&input->data_types);
|
|
|
|
wl_array_init(&input->data_types);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if (input->drag_source) _ecore_wl_dnd_del(input->drag_source); */
|
|
|
|
/* input->drag_source = NULL; */
|
|
|
|
|
|
|
|
/* destroy any existing data source */
|
|
|
|
if (input->data_source) wl_data_source_destroy(input->data_source);
|
|
|
|
input->data_source = NULL;
|
|
|
|
|
|
|
|
if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_End)))) return;
|
|
|
|
|
|
|
|
if (input->pointer_focus)
|
|
|
|
ev->win = input->pointer_focus->id;
|
|
|
|
|
|
|
|
if (input->keyboard_focus)
|
|
|
|
ev->source = input->keyboard_focus->id;
|
|
|
|
|
|
|
|
ecore_event_add(ECORE_WL_EVENT_DND_END, ev, NULL, NULL);
|
2012-08-28 23:35:02 -07:00
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/**
|
|
|
|
* @ingroup Ecore_Wl_Dnd_Group
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EAPI Eina_Bool
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_wl_dnd_drag_get(Ecore_Wl_Input *input, const char *type)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
char **t;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* check for valid input and drag source */
|
|
|
|
if ((!input) || (!input->drag_source)) return EINA_FALSE;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
wl_array_for_each(t, &input->drag_source->types)
|
|
|
|
if (!strcmp(type, *t)) break;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!*t) return EINA_FALSE;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_selection_data_receive(input->drag_source, type);
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
return EINA_TRUE;
|
2012-08-28 23:35:02 -07:00
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/**
|
|
|
|
* @ingroup Ecore_Wl_Dnd_Group
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
2015-03-13 18:40:59 -07:00
|
|
|
EAPI void
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_wl_dnd_drag_types_set(Ecore_Wl_Input *input, const char **types_offered)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
struct wl_data_device_manager *man;
|
|
|
|
const char **type;
|
|
|
|
char **t;
|
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* check for valid input. if not, get the default one */
|
|
|
|
if (!input) input = _ecore_wl_disp->input;
|
|
|
|
|
|
|
|
man = input->display->wl.data_device_manager;
|
|
|
|
|
|
|
|
/* free any old types offered */
|
|
|
|
if (input->data_types.data)
|
|
|
|
{
|
|
|
|
wl_array_for_each(t, &input->data_types)
|
|
|
|
free(*t);
|
|
|
|
wl_array_release(&input->data_types);
|
|
|
|
wl_array_init(&input->data_types);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* destroy any existing data source */
|
|
|
|
if (input->data_source) wl_data_source_destroy(input->data_source);
|
|
|
|
input->data_source = NULL;
|
|
|
|
|
|
|
|
/* try to create a new data source */
|
|
|
|
if (!(input->data_source = wl_data_device_manager_create_data_source(man)))
|
|
|
|
{
|
|
|
|
printf("Failed to create new data source for drag\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add these types to the data source */
|
|
|
|
for (type = types_offered; *type; type++)
|
|
|
|
{
|
2013-11-17 23:56:13 -08:00
|
|
|
if (!*type) continue;
|
2013-05-28 03:44:53 -07:00
|
|
|
t = wl_array_add(&input->data_types, sizeof(*t));
|
2015-03-13 18:40:59 -07:00
|
|
|
if (t)
|
2013-11-17 23:56:13 -08:00
|
|
|
{
|
|
|
|
*t = strdup(*type);
|
|
|
|
wl_data_source_offer(input->data_source, *t);
|
|
|
|
}
|
2013-05-28 03:44:53 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @ingroup Ecore_Wl_Dnd_Group
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
|
|
|
EAPI struct wl_array *
|
|
|
|
ecore_wl_dnd_drag_types_get(Ecore_Wl_Input *input)
|
|
|
|
{
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* check for valid input. if not, get the default one */
|
|
|
|
if (!input) input = _ecore_wl_disp->input;
|
2015-03-17 16:52:43 -07:00
|
|
|
if (!input) return NULL;
|
2013-05-28 03:44:53 -07:00
|
|
|
|
|
|
|
return &input->data_types;
|
2012-08-28 23:35:02 -07:00
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* private functions */
|
2015-03-13 18:40:59 -07:00
|
|
|
void
|
2012-11-25 01:55:32 -08:00
|
|
|
_ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer)
|
2012-02-28 13:55:51 -08:00
|
|
|
{
|
|
|
|
Ecore_Wl_Dnd_Source *source;
|
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!(source = malloc(sizeof(Ecore_Wl_Dnd_Source))))
|
|
|
|
return;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
|
|
|
wl_array_init(&source->types);
|
|
|
|
source->refcount = 1;
|
|
|
|
source->input = input;
|
2013-05-28 03:44:53 -07:00
|
|
|
source->data_offer = offer;
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
wl_data_offer_add_listener(source->data_offer,
|
2013-05-28 03:44:53 -07:00
|
|
|
&_ecore_wl_dnd_offer_listener, source);
|
2012-02-28 13:55:51 -08:00
|
|
|
}
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
void
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device EINA_UNUSED, unsigned int timestamp, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer)
|
2012-02-28 13:55:51 -08:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
Ecore_Wl_Event_Dnd_Enter *ev;
|
2012-02-28 13:55:51 -08:00
|
|
|
Ecore_Wl_Window *win;
|
2013-05-28 03:44:53 -07:00
|
|
|
Ecore_Wl_Input *input;
|
|
|
|
char **types;
|
|
|
|
int num = 0;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!(input = data)) return;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
win = ecore_wl_window_surface_find(surface);
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
input->pointer_enter_serial = timestamp;
|
|
|
|
input->pointer_focus = win;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (offer)
|
|
|
|
{
|
|
|
|
input->drag_source = wl_data_offer_get_user_data(offer);
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
num = (input->drag_source->types.size / sizeof(char *));
|
|
|
|
types = input->drag_source->types.data;
|
|
|
|
}
|
|
|
|
else
|
2012-08-15 07:01:20 -07:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
input->drag_source = NULL;
|
|
|
|
types = NULL;
|
2012-08-15 07:01:20 -07:00
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Enter)))) return;
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
if (win)
|
2013-05-28 03:44:53 -07:00
|
|
|
ev->win = win->id;
|
|
|
|
|
|
|
|
if (input->keyboard_focus)
|
|
|
|
ev->source = input->keyboard_focus->id;
|
|
|
|
|
|
|
|
ev->offer = offer;
|
|
|
|
ev->serial = timestamp;
|
|
|
|
ev->position.x = wl_fixed_to_int(x);
|
|
|
|
ev->position.y = wl_fixed_to_int(y);
|
|
|
|
ev->num_types = num;
|
|
|
|
ev->types = types;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_event_add(ECORE_WL_EVENT_DND_ENTER, ev, NULL, NULL);
|
2012-02-28 13:55:51 -08:00
|
|
|
}
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
void
|
2012-11-25 01:55:32 -08:00
|
|
|
_ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device EINA_UNUSED)
|
2012-02-28 13:55:51 -08:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
Ecore_Wl_Event_Dnd_Leave *ev;
|
2012-02-28 13:55:51 -08:00
|
|
|
Ecore_Wl_Input *input;
|
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2012-02-28 13:55:51 -08:00
|
|
|
if (!(input = data)) return;
|
2013-05-28 03:44:53 -07:00
|
|
|
|
|
|
|
if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Leave)))) return;
|
|
|
|
|
|
|
|
if (input->pointer_focus)
|
|
|
|
ev->win = input->pointer_focus->id;
|
|
|
|
|
|
|
|
if (input->keyboard_focus)
|
|
|
|
ev->source = input->keyboard_focus->id;
|
|
|
|
|
|
|
|
ecore_event_add(ECORE_WL_EVENT_DND_LEAVE, ev, NULL, NULL);
|
2012-02-28 13:55:51 -08:00
|
|
|
}
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
void
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device EINA_UNUSED, unsigned int timestamp EINA_UNUSED, int x, int y)
|
2012-02-28 13:55:51 -08:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
Ecore_Wl_Event_Dnd_Position *ev;
|
2012-02-28 13:55:51 -08:00
|
|
|
Ecore_Wl_Input *input;
|
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2012-02-28 13:55:51 -08:00
|
|
|
if (!(input = data)) return;
|
|
|
|
|
2012-05-15 04:58:21 -07:00
|
|
|
input->sx = wl_fixed_to_int(x);
|
|
|
|
input->sy = wl_fixed_to_int(y);
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (input->pointer_focus)
|
|
|
|
ev->win = input->pointer_focus->id;
|
2012-08-15 07:01:20 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (input->keyboard_focus)
|
|
|
|
ev->source = input->keyboard_focus->id;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
ev->position.x = input->sx;
|
|
|
|
ev->position.y = input->sy;
|
|
|
|
|
|
|
|
ecore_event_add(ECORE_WL_EVENT_DND_POSITION, ev, NULL, NULL);
|
2012-02-28 13:55:51 -08:00
|
|
|
}
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
void
|
2012-11-25 01:55:32 -08:00
|
|
|
_ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device EINA_UNUSED)
|
2012-02-28 13:55:51 -08:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
Ecore_Wl_Event_Dnd_Drop *ev;
|
2012-02-28 13:55:51 -08:00
|
|
|
Ecore_Wl_Input *input;
|
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2012-02-28 13:55:51 -08:00
|
|
|
if (!(input = data)) return;
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Drop)))) return;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2012-08-15 07:01:20 -07:00
|
|
|
if (input->drag_source)
|
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
if (input->pointer_focus)
|
|
|
|
ev->win = input->pointer_focus->id;
|
|
|
|
if (input->keyboard_focus)
|
|
|
|
ev->source = input->keyboard_focus->id;
|
2012-08-15 07:01:20 -07:00
|
|
|
}
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
ev->position.x = input->sx;
|
|
|
|
ev->position.y = input->sy;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
ecore_event_add(ECORE_WL_EVENT_DND_DROP, ev, NULL, NULL);
|
2012-02-28 13:55:51 -08:00
|
|
|
}
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
void
|
2012-11-25 01:55:32 -08:00
|
|
|
_ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device EINA_UNUSED, struct wl_data_offer *offer)
|
2012-02-28 13:55:51 -08:00
|
|
|
{
|
|
|
|
Ecore_Wl_Input *input;
|
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2012-02-28 13:55:51 -08:00
|
|
|
if (!(input = data)) return;
|
2013-05-28 03:44:53 -07:00
|
|
|
|
2012-02-28 13:55:51 -08:00
|
|
|
if (input->selection_source) _ecore_wl_dnd_del(input->selection_source);
|
2013-11-07 06:30:49 -08:00
|
|
|
input->selection_source = NULL;
|
2013-05-28 03:44:53 -07:00
|
|
|
|
2012-02-28 13:55:51 -08:00
|
|
|
if (offer)
|
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
char **t;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
|
|
|
input->selection_source = wl_data_offer_get_user_data(offer);
|
2013-05-28 03:44:53 -07:00
|
|
|
t = wl_array_add(&input->selection_source->types, sizeof(*t));
|
|
|
|
*t = NULL;
|
2012-02-28 13:55:51 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
void
|
2012-02-28 13:55:51 -08:00
|
|
|
_ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source)
|
|
|
|
{
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2012-02-28 13:55:51 -08:00
|
|
|
if (!source) return;
|
|
|
|
source->refcount--;
|
|
|
|
if (source->refcount == 0)
|
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
wl_data_offer_destroy(source->data_offer);
|
2012-02-28 13:55:51 -08:00
|
|
|
wl_array_release(&source->types);
|
|
|
|
free(source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* local functions */
|
2015-03-13 18:40:59 -07:00
|
|
|
static void
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_selection_data_receive(Ecore_Wl_Dnd_Source *source, const char *type)
|
2012-02-28 13:55:51 -08:00
|
|
|
{
|
2013-05-28 03:44:53 -07:00
|
|
|
int epoll_fd;
|
|
|
|
struct epoll_event *ep = NULL;
|
|
|
|
struct _dnd_task *task = NULL;
|
|
|
|
struct _dnd_read_ctx *read_ctx = NULL;
|
2016-11-18 02:53:14 -08:00
|
|
|
struct _dnd_source *read_source = NULL;
|
2013-05-28 03:44:53 -07:00
|
|
|
int p[2];
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (pipe2(p, O_CLOEXEC) == -1)
|
|
|
|
return;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
wl_data_offer_receive(source->data_offer, type, p[1]);
|
|
|
|
close(p[1]);
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
/* Due to http://trac.enlightenment.org/e/ticket/1208,
|
|
|
|
* use epoll and idle handler instead of ecore_main_fd_handler_add() */
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
ep = calloc(1, sizeof(struct epoll_event));
|
|
|
|
if (!ep) goto err;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
task = calloc(1, sizeof(struct _dnd_task));
|
|
|
|
if (!task) goto err;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
read_ctx = calloc(1, sizeof(struct _dnd_read_ctx));
|
|
|
|
if (!read_ctx) goto err;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
epoll_fd = epoll_create1(0);
|
|
|
|
if (epoll_fd < 0) goto err;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2016-11-18 02:53:14 -08:00
|
|
|
read_source = calloc(1, sizeof(struct _dnd_source));
|
|
|
|
if (!read_source) goto err;
|
|
|
|
|
2018-04-19 23:28:39 -07:00
|
|
|
read_source->source = source;
|
2016-11-18 02:53:14 -08:00
|
|
|
read_source->read_fd = p[0];
|
|
|
|
task->data = read_source;
|
2013-05-28 03:44:53 -07:00
|
|
|
task->cb = _ecore_wl_dnd_selection_data_read;
|
|
|
|
ep->events = EPOLLIN;
|
|
|
|
ep->data.ptr = task;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, p[0], ep) < 0) goto err;
|
|
|
|
|
|
|
|
read_ctx->epoll_fd = epoll_fd;
|
|
|
|
read_ctx->ep = ep;
|
|
|
|
|
|
|
|
if (!ecore_idler_add(_ecore_wl_dnd_selection_cb_idle, read_ctx)) goto err;
|
|
|
|
|
|
|
|
source->refcount++;
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
err:
|
|
|
|
if (ep) free(ep);
|
|
|
|
if (task) free(task);
|
|
|
|
if (read_ctx) free(read_ctx);
|
2016-11-18 02:53:14 -08:00
|
|
|
if (read_source) free(read_source);
|
2013-05-28 03:44:53 -07:00
|
|
|
close(p[0]);
|
|
|
|
return;
|
2012-08-28 23:35:02 -07:00
|
|
|
}
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
static Eina_Bool
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_selection_data_read(void *data, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
|
|
|
int len;
|
2013-05-28 03:44:53 -07:00
|
|
|
char buffer[PATH_MAX];
|
2012-08-28 23:35:02 -07:00
|
|
|
Ecore_Wl_Dnd_Source *source;
|
2016-11-18 02:53:14 -08:00
|
|
|
struct _dnd_source *read_source;
|
2012-08-28 23:35:02 -07:00
|
|
|
Ecore_Wl_Event_Selection_Data_Ready *event;
|
|
|
|
Eina_Bool ret;
|
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2016-11-18 02:53:14 -08:00
|
|
|
read_source = data;
|
|
|
|
source = read_source->source;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2016-11-18 02:53:14 -08:00
|
|
|
len = read(read_source->read_fd, buffer, sizeof buffer);
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Selection_Data_Ready))))
|
2012-08-28 23:35:02 -07:00
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
|
|
|
|
if (len <= 0)
|
|
|
|
{
|
2016-11-18 02:53:14 -08:00
|
|
|
close(read_source->read_fd);
|
2012-08-28 23:35:02 -07:00
|
|
|
_ecore_wl_dnd_del(source);
|
|
|
|
event->done = EINA_TRUE;
|
|
|
|
event->data = NULL;
|
|
|
|
event->len = 0;
|
|
|
|
ret = ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-08-13 12:47:09 -07:00
|
|
|
event->data = malloc(len);
|
2013-05-29 05:24:49 -07:00
|
|
|
if (!event->data)
|
|
|
|
{
|
|
|
|
free(event);
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
2015-08-13 12:47:09 -07:00
|
|
|
memcpy(event->data, buffer, len);
|
2012-08-28 23:35:02 -07:00
|
|
|
event->len = len;
|
|
|
|
event->done = EINA_FALSE;
|
|
|
|
ret = ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
ecore_event_add(ECORE_WL_EVENT_SELECTION_DATA_READY, event,
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_selection_data_ready_cb_free, NULL);
|
|
|
|
|
2012-08-28 23:35:02 -07:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
static void
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_selection_data_ready_cb_free(void *data EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Event_Selection_Data_Ready *ev;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!(ev = event)) return;
|
|
|
|
|
|
|
|
free(ev->data);
|
|
|
|
free(ev);
|
|
|
|
}
|
2012-08-28 23:35:02 -07:00
|
|
|
|
|
|
|
static Eina_Bool
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_selection_cb_idle(void *data)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
|
|
|
struct _dnd_read_ctx *ctx;
|
|
|
|
struct _dnd_task *task;
|
|
|
|
int count, i;
|
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2012-08-28 23:35:02 -07:00
|
|
|
ctx = data;
|
|
|
|
count = epoll_wait(ctx->epoll_fd, ctx->ep, 1, 0);
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
task = ctx->ep->data.ptr;
|
|
|
|
if (task->cb(task->data, NULL) == ECORE_CALLBACK_CANCEL)
|
|
|
|
{
|
|
|
|
free(ctx->ep);
|
2016-11-18 02:53:14 -08:00
|
|
|
free(task->data);
|
2012-08-28 23:35:02 -07:00
|
|
|
free(task);
|
|
|
|
free(ctx);
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
2015-03-13 18:40:59 -07:00
|
|
|
}
|
2012-08-28 23:35:02 -07:00
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
static void
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_source_cb_target(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type EINA_UNUSED)
|
2012-08-28 23:35:02 -07:00
|
|
|
{
|
2014-09-19 06:04:49 -07:00
|
|
|
Ecore_Wl_Event_Data_Source_Target *event;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2014-09-19 06:04:49 -07:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
2017-10-16 13:28:08 -07:00
|
|
|
if (!data) return;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2014-09-19 06:04:49 -07:00
|
|
|
if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Data_Source_Target)))) return;
|
|
|
|
|
2015-03-13 11:52:58 -07:00
|
|
|
if (mime_type)
|
|
|
|
event->type = strdup(mime_type);
|
2014-09-19 06:04:49 -07:00
|
|
|
|
|
|
|
ecore_event_add(ECORE_WL_EVENT_DATA_SOURCE_TARGET, event,
|
|
|
|
_ecore_wl_dnd_source_cb_target_free, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_wl_dnd_source_cb_target_free(void *data EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Event_Data_Source_Target *ev;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!(ev = event)) return;
|
|
|
|
|
|
|
|
free(ev->type);
|
|
|
|
free(ev);
|
2013-05-28 03:44:53 -07:00
|
|
|
}
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
static void
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_source_cb_send(void *data, struct wl_data_source *source EINA_UNUSED, const char *mime_type, int32_t fd)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Event_Data_Source_Send *event;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2017-10-16 13:28:08 -07:00
|
|
|
if (!data) return;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Data_Source_Send)))) return;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
event->type = strdup(mime_type);
|
|
|
|
event->fd = fd;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
ecore_event_add(ECORE_WL_EVENT_DATA_SOURCE_SEND, event,
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_source_cb_send_free, NULL);
|
|
|
|
}
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
static void
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_source_cb_send_free(void *data EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Event_Data_Source_Send *ev;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!(ev = event)) return;
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
free(ev->type);
|
|
|
|
free(ev);
|
|
|
|
}
|
2012-08-28 23:35:02 -07:00
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
static void
|
2014-09-08 03:44:07 -07:00
|
|
|
_ecore_wl_dnd_source_cb_cancelled(void *data, struct wl_data_source *source)
|
2013-05-28 03:44:53 -07:00
|
|
|
{
|
2014-09-08 03:44:07 -07:00
|
|
|
Ecore_Wl_Input *input;
|
2014-09-19 05:42:49 -07:00
|
|
|
Ecore_Wl_Event_Data_Source_Cancelled *ev;
|
2014-09-08 03:44:07 -07:00
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2014-09-08 03:44:07 -07:00
|
|
|
if (!(input = data)) return;
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
wl_data_source_destroy(source);
|
2014-09-08 03:44:07 -07:00
|
|
|
if (input->data_source == source) input->data_source = NULL;
|
2014-09-19 05:42:49 -07:00
|
|
|
|
|
|
|
if (!(ev = calloc(1, sizeof(Ecore_Wl_Event_Data_Source_Cancelled)))) return;
|
|
|
|
|
|
|
|
if (input->pointer_focus)
|
|
|
|
ev->win = input->pointer_focus->id;
|
|
|
|
|
|
|
|
if (input->keyboard_focus)
|
|
|
|
ev->source = input->keyboard_focus->id;
|
|
|
|
|
|
|
|
ecore_event_add(ECORE_WL_EVENT_DATA_SOURCE_CANCELLED, ev, NULL, NULL);
|
2013-05-28 03:44:53 -07:00
|
|
|
}
|
|
|
|
|
2015-03-13 18:40:59 -07:00
|
|
|
static void
|
2013-05-28 03:44:53 -07:00
|
|
|
_ecore_wl_dnd_offer_cb_offer(void *data, struct wl_data_offer *data_offer EINA_UNUSED, const char *type)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Dnd_Source *source;
|
|
|
|
char **t;
|
|
|
|
|
2013-11-07 06:30:49 -08:00
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2013-05-28 03:44:53 -07:00
|
|
|
if (!(source = data)) return;
|
2013-11-17 23:56:13 -08:00
|
|
|
if (!type) return;
|
2013-05-28 03:44:53 -07:00
|
|
|
|
|
|
|
t = wl_array_add(&source->types, sizeof(*t));
|
2013-11-17 23:56:13 -08:00
|
|
|
if (t) *t = strdup(type);
|
2012-08-28 23:35:02 -07:00
|
|
|
}
|