efl/legacy/ecore/src/lib/ecore_wayland/ecore_wl_dnd.c

210 lines
5.6 KiB
C
Raw Normal View History

#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
_ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device __UNUSED__, struct wl_data_offer *offer)
{
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;
source->offer = offer;
wl_data_offer_add_listener(source->offer,
&_ecore_wl_data_offer_listener, source);
}
void
_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)
{
Ecore_Wl_Event_Dnd_Enter *event;
Ecore_Wl_Input *input;
Ecore_Wl_Window *win;
char **p;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if ((!(input = data)) || (!offer)) return;
if (!(input->drag_source = wl_data_offer_get_user_data(offer)))
return;
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;
if (input->drag_source->input)
{
if (input->drag_source->input->keyboard_focus)
event->source = input->drag_source->input->keyboard_focus->id;
}
event->position.x = wl_fixed_to_int(x);
event->position.y = wl_fixed_to_int(y);
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;
/* FIXME: NB: This MAY need to raise a wl_event_dnd_leave for the
* source window */
_ecore_wl_dnd_del(input->drag_source);
input->drag_source = NULL;
}
void
_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)
{
Ecore_Wl_Event_Dnd_Position *event;
Ecore_Wl_Input *input;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!(input = data)) return;
input->sx = wl_fixed_to_int(x);
input->sy = wl_fixed_to_int(y);
if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Dnd_Position)))) return;
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;
}
}
event->position.x = input->sx;
event->position.y = input->sy;
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;
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;
}
}
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);
}