enlightenment/src/bin/e_comp_wl_input.c

235 lines
6.8 KiB
C

#include "e.h"
#ifdef HAVE_WAYLAND_CLIENTS
# include "e_comp_wl.h"
# include "e_comp_wl_input.h"
#endif
/* local function prototypes */
static void _e_comp_wl_input_bind(struct wl_client *client, void *data, uint32_t version __UNUSED__, uint32_t id);
static void _e_comp_wl_input_unbind(struct wl_resource *resource);
static void _e_comp_wl_input_pointer_get(struct wl_client *client, struct wl_resource *resource, unsigned int id);
static void _e_comp_wl_input_keyboard_get(struct wl_client *client, struct wl_resource *resource, unsigned int id);
static void _e_comp_wl_input_touch_get(struct wl_client *client, struct wl_resource *resource, unsigned int id);
static void _e_comp_wl_input_pointer_cursor_set(struct wl_client *client, struct wl_resource *resource, unsigned int serial, struct wl_resource *surface_resource, int x, int y);
/* wayland interfaces */
static const struct wl_seat_interface _wl_seat_interface =
{
_e_comp_wl_input_pointer_get,
_e_comp_wl_input_keyboard_get,
_e_comp_wl_input_touch_get
};
static const struct wl_pointer_interface _wl_pointer_interface =
{
_e_comp_wl_input_pointer_cursor_set
};
/* private variables */
static Wayland_Input *_wl_input;
Eina_Bool
e_comp_wl_input_init(void)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!(_wl_input = malloc(sizeof(Wayland_Input))))
{
EINA_LOG_ERR("Could not allocate space for input\n");
return EINA_FALSE;
}
memset(_wl_input, 0, sizeof(*_wl_input));
wl_seat_init(&_wl_input->seat);
if (!wl_display_add_global(_wl_disp, &wl_seat_interface, _wl_input,
_e_comp_wl_input_bind))
{
EINA_LOG_ERR("Failed to add input to wayland\n");
free(_wl_input);
return EINA_FALSE;
}
_wl_input->hotspot_x = 16;
_wl_input->hotspot_y = 16;
return EINA_TRUE;
}
void
e_comp_wl_input_shutdown(void)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!_wl_input) return;
wl_seat_release(&_wl_input->seat);
free(_wl_input);
}
Wayland_Input *
e_comp_wl_input_get(void)
{
return _wl_input;
}
/* local functions */
static void
_e_comp_wl_input_bind(struct wl_client *client, void *data, uint32_t version __UNUSED__, uint32_t id)
{
Wayland_Input *input;
struct wl_seat *device;
struct wl_resource *resource;
enum wl_seat_capability caps = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
input = data;
device = &input->seat;
resource =
wl_client_add_object(client, &wl_seat_interface,
&_wl_seat_interface, id, data);
wl_list_insert(&device->base_resource_list, &resource->link);
resource->destroy = _e_comp_wl_input_unbind;
if (device->pointer) caps |= WL_SEAT_CAPABILITY_POINTER;
if (device->keyboard) caps |= WL_SEAT_CAPABILITY_KEYBOARD;
if (device->touch) caps |= WL_SEAT_CAPABILITY_TOUCH;
wl_seat_send_capabilities(resource, caps);
}
static void
_e_comp_wl_input_unbind(struct wl_resource *resource)
{
LOGFN(__FILE__, __LINE__, __FUNCTION__);
wl_list_remove(&resource->link);
free(resource);
}
static void
_e_comp_wl_input_pointer_get(struct wl_client *client, struct wl_resource *resource, unsigned int id)
{
Wayland_Input *wi;
struct wl_resource *res;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!(wi = resource->data)) return;
if (!wi->seat.pointer) return;
res = wl_client_add_object(client, &wl_pointer_interface,
&_wl_pointer_interface, id, wi);
wl_list_insert(&wi->seat.pointer->resource_list, &res->link);
res->destroy = _e_comp_wl_input_unbind;
if ((wi->seat.pointer->focus) &&
(wi->seat.pointer->focus->resource.client == client))
{
/* TODO: surface_from_global_fixed ?? */
wl_pointer_set_focus(wi->seat.pointer, wi->seat.pointer->focus,
wi->seat.pointer->x,
wi->seat.pointer->y);
}
}
static void
_e_comp_wl_input_keyboard_get(struct wl_client *client, struct wl_resource *resource, unsigned int id)
{
Wayland_Input *wi;
struct wl_resource *res;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!(wi = resource->data)) return;
if (!wi->seat.keyboard) return;
res = wl_client_add_object(client, &wl_keyboard_interface, NULL, id, wi);
wl_list_insert(&wi->seat.keyboard->resource_list, &res->link);
res->destroy = _e_comp_wl_input_unbind;
/* TODO: wl_keyboard_send_keymap ?? */
if ((wi->seat.keyboard->focus) &&
(wi->seat.keyboard->focus->resource.client == client))
{
wl_keyboard_set_focus(wi->seat.keyboard, wi->seat.keyboard->focus);
}
}
static void
_e_comp_wl_input_touch_get(struct wl_client *client, struct wl_resource *resource, unsigned int id)
{
Wayland_Input *wi;
struct wl_resource *res;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!(wi = resource->data)) return;
if (!wi->seat.touch) return;
res = wl_client_add_object(client, &wl_touch_interface, NULL, id, wi);
wl_list_insert(&wi->seat.touch->resource_list, &res->link);
res->destroy = _e_comp_wl_input_unbind;
}
static void
_e_comp_wl_input_pointer_cursor_set(struct wl_client *client, struct wl_resource *resource, unsigned int serial, struct wl_resource *surface_resource, int x, int y)
{
/* Wayland_Input *wi; */
/* Wayland_Surface *ws; */
/* if (!(wi = resource->data)) return; */
/* if (!wi->seat.pointer->focus) return; */
/* if (wi->seat.pointer->focus->resource.client != client) return; */
/* if (surface_resource) ws = surface_resource->data; */
/* if ((ws) && (ws != wi->sprite)) */
/* { */
/* if (ws->configure) */
/* { */
/* wl_resource_post_error(&ws->surface.resource, */
/* WL_DISPLAY_ERROR_INVALID_OBJECT, */
/* "Surface configure already set"); */
/* return; */
/* } */
/* } */
/* TODO: Unmap sprite ? */
/* if (!ws) return; */
/* wl_signal_add(&ws->surface.resource.destroy_signal, */
/* &wi->sprite_destroy_listener); */
/* ws->configure = ; */
/* ws->private = seat; */
/* wi->sprite = ws; */
/* wi->hotspot_x = x; */
/* wi->hotspot_y = y; */
/* if (ws->buffer) */
/* { */
/* TODO: cursor surface configure */
/* } */
}
/* static void */
/* _e_comp_wl_input_attach(struct wl_client *client, struct wl_resource *resource, uint32_t serial, struct wl_resource *buffer_resource __UNUSED__, int32_t x, int32_t y) */
/* { */
/* Wayland_Input *wi; */
/* LOGFN(__FILE__, __LINE__, __FUNCTION__); */
/* wi = resource->data; */
/* if (serial < wi->input_device.pointer_focus_serial) return; */
/* if (!wi->input_device.pointer_focus) return; */
/* if (wi->input_device.pointer_focus->resource.client != client) return; */
/* wi->hotspot_x = x; */
/* wi->hotspot_y = y; */
/* } */