2012-02-28 13:55:51 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "ecore_wl_private.h"
|
|
|
|
|
|
|
|
/* local function prototypes */
|
|
|
|
static void _ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer __UNUSED__, const char *type);
|
|
|
|
static void _ecore_wl_dnd_cb_enter_free(void *data __UNUSED__, void *event);
|
|
|
|
|
|
|
|
/* wayland listeners */
|
|
|
|
static const struct wl_data_offer_listener _ecore_wl_data_offer_listener =
|
|
|
|
{
|
|
|
|
_ecore_wl_dnd_offer,
|
|
|
|
};
|
|
|
|
|
|
|
|
void
|
2012-07-04 00:16:29 -07:00
|
|
|
_ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device __UNUSED__, struct wl_data_offer *offer)
|
2012-02-28 13:55:51 -08:00
|
|
|
{
|
|
|
|
Ecore_Wl_Dnd_Source *source;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!(source = malloc(sizeof(Ecore_Wl_Dnd_Source)))) return;
|
|
|
|
wl_array_init(&source->types);
|
|
|
|
source->refcount = 1;
|
|
|
|
source->input = input;
|
2012-07-04 00:16:29 -07:00
|
|
|
source->offer = offer;
|
2012-02-28 13:55:51 -08:00
|
|
|
wl_data_offer_add_listener(source->offer,
|
|
|
|
&_ecore_wl_data_offer_listener, source);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-05-15 04:58:21 -07:00
|
|
|
_ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device __UNUSED__, unsigned int timestamp __UNUSED__, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *offer)
|
2012-02-28 13:55:51 -08:00
|
|
|
{
|
|
|
|
Ecore_Wl_Event_Dnd_Enter *event;
|
|
|
|
Ecore_Wl_Input *input;
|
|
|
|
Ecore_Wl_Window *win;
|
|
|
|
char **p;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
2012-08-15 07:01:20 -07:00
|
|
|
if ((!(input = data)) || (!offer)) return;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
2012-08-15 07:01:20 -07:00
|
|
|
if (!(input->drag_source = wl_data_offer_get_user_data(offer)))
|
|
|
|
return;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
|
|
|
win = wl_surface_get_user_data(surface);
|
|
|
|
// input->pointer_focus = win;
|
|
|
|
|
|
|
|
p = wl_array_add(&input->drag_source->types, sizeof(*p));
|
|
|
|
*p = NULL;
|
|
|
|
|
|
|
|
if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Enter)))) return;
|
|
|
|
|
|
|
|
event->win = win->id;
|
2012-08-15 07:01:20 -07:00
|
|
|
if (input->drag_source->input)
|
|
|
|
{
|
|
|
|
if (input->drag_source->input->keyboard_focus)
|
|
|
|
event->source = input->drag_source->input->keyboard_focus->id;
|
|
|
|
}
|
|
|
|
|
2012-05-15 04:58:21 -07:00
|
|
|
event->position.x = wl_fixed_to_int(x);
|
|
|
|
event->position.y = wl_fixed_to_int(y);
|
2012-02-28 13:55:51 -08:00
|
|
|
event->num_types = input->drag_source->types.size;
|
|
|
|
event->types = input->drag_source->types.data;
|
|
|
|
|
|
|
|
ecore_event_add(ECORE_WL_EVENT_DND_ENTER, event,
|
|
|
|
_ecore_wl_dnd_cb_enter_free, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_ecore_wl_dnd_leave(void *data, struct wl_data_device *data_device __UNUSED__)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Input *input;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!(input = data)) return;
|
2012-04-24 09:59:35 -07:00
|
|
|
/* FIXME: NB: This MAY need to raise a wl_event_dnd_leave for the
|
|
|
|
* source window */
|
2012-02-28 13:55:51 -08:00
|
|
|
_ecore_wl_dnd_del(input->drag_source);
|
|
|
|
input->drag_source = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-05-15 04:58:21 -07:00
|
|
|
_ecore_wl_dnd_motion(void *data, struct wl_data_device *data_device __UNUSED__, unsigned int timestamp __UNUSED__, wl_fixed_t x, wl_fixed_t y)
|
2012-02-28 13:55:51 -08:00
|
|
|
{
|
|
|
|
Ecore_Wl_Event_Dnd_Position *event;
|
|
|
|
Ecore_Wl_Input *input;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return;
|
|
|
|
|
2012-08-15 07:01:20 -07:00
|
|
|
if (input->drag_source)
|
|
|
|
{
|
|
|
|
if (input->drag_source->input)
|
|
|
|
{
|
|
|
|
if (input->drag_source->input->pointer_focus)
|
|
|
|
event->win = input->drag_source->input->pointer_focus->id;
|
|
|
|
if (input->drag_source->input->keyboard_focus)
|
|
|
|
event->source = input->drag_source->input->keyboard_focus->id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-15 04:58:21 -07:00
|
|
|
event->position.x = input->sx;
|
|
|
|
event->position.y = input->sy;
|
2012-02-28 13:55:51 -08:00
|
|
|
|
|
|
|
ecore_event_add(ECORE_WL_EVENT_DND_POSITION, event, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_ecore_wl_dnd_drop(void *data, struct wl_data_device *data_device __UNUSED__)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Event_Dnd_Drop *event;
|
|
|
|
Ecore_Wl_Input *input;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!(input = data)) return;
|
|
|
|
|
|
|
|
if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Drop)))) return;
|
|
|
|
|
2012-08-15 07:01:20 -07:00
|
|
|
if (input->drag_source)
|
|
|
|
{
|
|
|
|
if (input->drag_source->input)
|
|
|
|
{
|
|
|
|
if (input->drag_source->input->pointer_focus)
|
|
|
|
event->win = input->drag_source->input->pointer_focus->id;
|
|
|
|
if (input->drag_source->input->keyboard_focus)
|
|
|
|
event->source = input->drag_source->input->keyboard_focus->id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-28 13:55:51 -08:00
|
|
|
event->position.x = input->sx;
|
|
|
|
event->position.y = input->sy;
|
|
|
|
|
|
|
|
ecore_event_add(ECORE_WL_EVENT_DND_DROP, event, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_ecore_wl_dnd_selection(void *data, struct wl_data_device *data_device __UNUSED__, struct wl_data_offer *offer)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Input *input;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!(input = data)) return;
|
|
|
|
if (input->selection_source) _ecore_wl_dnd_del(input->selection_source);
|
|
|
|
input->selection_source = NULL;
|
|
|
|
if (offer)
|
|
|
|
{
|
|
|
|
char **p;
|
|
|
|
|
|
|
|
input->selection_source = wl_data_offer_get_user_data(offer);
|
|
|
|
p = wl_array_add(&input->selection_source->types, sizeof(*p));
|
|
|
|
*p = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_ecore_wl_dnd_del(Ecore_Wl_Dnd_Source *source)
|
|
|
|
{
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!source) return;
|
|
|
|
source->refcount--;
|
|
|
|
if (source->refcount == 0)
|
|
|
|
{
|
|
|
|
char **p;
|
|
|
|
|
|
|
|
wl_data_offer_destroy(source->offer);
|
|
|
|
for (p = source->types.data; *p; p++)
|
|
|
|
free(*p);
|
|
|
|
wl_array_release(&source->types);
|
|
|
|
free(source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* local functions */
|
|
|
|
static void
|
|
|
|
_ecore_wl_dnd_offer(void *data, struct wl_data_offer *wl_data_offer __UNUSED__, const char *type)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Dnd_Source *source;
|
|
|
|
char **p;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!(source = data)) return;
|
|
|
|
p = wl_array_add(&source->types, sizeof(*p));
|
|
|
|
*p = strdup(type);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_ecore_wl_dnd_cb_enter_free(void *data __UNUSED__, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Event_Dnd_Enter *ev;
|
|
|
|
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
if (!(ev = event)) return;
|
|
|
|
free(ev);
|
|
|
|
}
|