forked from enlightenment/enlightenment
E Comp (wayland): Get important input from X11 (focus in/out, mouse
in/out, mouse down/up, key down/up, etc, etc) and pass it on to wayland clients in the form that they expect (wayland events). SVN revision: 67593
This commit is contained in:
parent
2b36a0e7ba
commit
9ba038d504
|
@ -151,6 +151,7 @@ struct _Wayland_Input
|
|||
struct wl_input_device input_device;
|
||||
int32_t hotspot_x, hotspot_y;
|
||||
struct wl_list link;
|
||||
uint32_t modifier_state;
|
||||
};
|
||||
|
||||
struct wl_shell
|
||||
|
|
|
@ -4,15 +4,45 @@
|
|||
# include "e_mod_comp_wl.h"
|
||||
# include "e_mod_comp_wl_comp.h"
|
||||
# include "e_mod_comp_wl_shm.h"
|
||||
# include "e_mod_comp_wl_input.h"
|
||||
# include "e_mod_comp_wl_surface.h"
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
# include <linux/input.h>
|
||||
#else
|
||||
# define BTN_LEFT 0x110
|
||||
# define BTN_RIGHT 0x111
|
||||
# define BTN_MIDDLE 0x112
|
||||
# define BTN_SIDE 0x113
|
||||
# define BTN_EXTRA 0x114
|
||||
# define BTN_FORWARD 0x115
|
||||
# define BTN_BACK 0x116
|
||||
#endif
|
||||
|
||||
#define MODIFIER_CTRL (1 << 8)
|
||||
#define MODIFIER_ALT (1 << 9)
|
||||
#define MODIFIER_SUPER (1 << 10)
|
||||
|
||||
/* local function prototypes */
|
||||
static Eina_Bool _e_mod_comp_wl_comp_egl_init(void);
|
||||
static void _e_mod_comp_wl_comp_egl_shutdown(void);
|
||||
static void _e_mod_comp_wl_comp_destroy(void);
|
||||
static void _e_mod_comp_wl_comp_bind(struct wl_client *client, void *data, uint32_t version __UNUSED__, uint32_t id);
|
||||
static void _e_mod_comp_wl_comp_surface_create(struct wl_client *client, struct wl_resource *resource, uint32_t id);
|
||||
static Eina_Bool _e_mod_comp_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event);
|
||||
static Eina_Bool _e_mod_comp_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event);
|
||||
static Eina_Bool _e_mod_comp_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event);
|
||||
static Eina_Bool _e_mod_comp_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event);
|
||||
static Eina_Bool _e_mod_comp_wl_cb_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event);
|
||||
static Eina_Bool _e_mod_comp_wl_cb_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event);
|
||||
static Eina_Bool _e_mod_comp_wl_cb_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event);
|
||||
static Eina_Bool _e_mod_comp_wl_cb_key_down(void *data __UNUSED__, int type __UNUSED__, void *event);
|
||||
static Eina_Bool _e_mod_comp_wl_cb_key_up(void *data __UNUSED__, int type __UNUSED__, void *event);
|
||||
|
||||
static void _e_mod_comp_wl_comp_repick(struct wl_input_device *device, uint32_t timestamp);
|
||||
static Wayland_Surface *_e_mod_comp_wl_comp_pick_surface(int32_t x __UNUSED__, int32_t y __UNUSED__, int32_t *sx, int32_t *sy);
|
||||
static void _e_mod_comp_wl_comp_update_modifier(Wayland_Input *input, uint32_t key, uint32_t state);
|
||||
|
||||
/* wayland interfaces */
|
||||
static const struct wl_compositor_interface _wl_comp_interface =
|
||||
|
@ -29,6 +59,7 @@ static const struct wl_surface_interface _wl_surface_interface =
|
|||
|
||||
/* private variables */
|
||||
static Wayland_Compositor *_wl_comp;
|
||||
static Eina_List *_wl_event_handlers = NULL;
|
||||
|
||||
Eina_Bool
|
||||
e_mod_comp_wl_comp_init(void)
|
||||
|
@ -93,6 +124,43 @@ e_mod_comp_wl_comp_init(void)
|
|||
|
||||
wl_list_init(&_wl_comp->surfaces);
|
||||
|
||||
_wl_event_handlers =
|
||||
eina_list_append(_wl_event_handlers,
|
||||
ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN,
|
||||
_e_mod_comp_wl_cb_focus_in, NULL));
|
||||
_wl_event_handlers =
|
||||
eina_list_append(_wl_event_handlers,
|
||||
ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT,
|
||||
_e_mod_comp_wl_cb_focus_out, NULL));
|
||||
_wl_event_handlers =
|
||||
eina_list_append(_wl_event_handlers,
|
||||
ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN,
|
||||
_e_mod_comp_wl_cb_mouse_in, NULL));
|
||||
_wl_event_handlers =
|
||||
eina_list_append(_wl_event_handlers,
|
||||
ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT,
|
||||
_e_mod_comp_wl_cb_mouse_out, NULL));
|
||||
_wl_event_handlers =
|
||||
eina_list_append(_wl_event_handlers,
|
||||
ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
|
||||
_e_mod_comp_wl_cb_mouse_move, NULL));
|
||||
_wl_event_handlers =
|
||||
eina_list_append(_wl_event_handlers,
|
||||
ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
|
||||
_e_mod_comp_wl_cb_mouse_down, NULL));
|
||||
_wl_event_handlers =
|
||||
eina_list_append(_wl_event_handlers,
|
||||
ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
|
||||
_e_mod_comp_wl_cb_mouse_up, NULL));
|
||||
_wl_event_handlers =
|
||||
eina_list_append(_wl_event_handlers,
|
||||
ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
|
||||
_e_mod_comp_wl_cb_key_down, NULL));
|
||||
_wl_event_handlers =
|
||||
eina_list_append(_wl_event_handlers,
|
||||
ecore_event_handler_add(ECORE_EVENT_KEY_UP,
|
||||
_e_mod_comp_wl_cb_key_up, NULL));
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -101,6 +169,8 @@ e_mod_comp_wl_comp_shutdown(void)
|
|||
{
|
||||
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
E_FREE_LIST(_wl_event_handlers, ecore_event_handler_del);
|
||||
|
||||
if (_wl_comp) _wl_comp->destroy();
|
||||
}
|
||||
|
||||
|
@ -242,3 +312,332 @@ _e_mod_comp_wl_comp_surface_create(struct wl_client *client, struct wl_resource
|
|||
|
||||
wl_client_add_resource(client, &ws->surface.resource);
|
||||
}
|
||||
|
||||
|
||||
static Eina_Bool
|
||||
_e_mod_comp_wl_cb_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
|
||||
{
|
||||
Wayland_Input *input;
|
||||
Wayland_Surface *ws;
|
||||
Ecore_X_Event_Window_Focus_In *ev;
|
||||
|
||||
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
ev = event;
|
||||
if (wl_list_empty(&_wl_comp->surfaces)) return ECORE_CALLBACK_PASS_ON;
|
||||
|
||||
input = e_mod_comp_wl_input_get();
|
||||
wl_list_for_each(ws, &_wl_comp->surfaces, link)
|
||||
{
|
||||
if (((ws->win) && (ws->win->border))
|
||||
&& (ws->win->border->win == ev->win))
|
||||
{
|
||||
wl_input_device_set_keyboard_focus(&input->input_device,
|
||||
&ws->surface, ev->time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_mod_comp_wl_cb_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
|
||||
{
|
||||
Wayland_Input *input;
|
||||
Ecore_X_Event_Window_Focus_Out *ev;
|
||||
|
||||
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
ev = event;
|
||||
input = e_mod_comp_wl_input_get();
|
||||
wl_input_device_set_keyboard_focus(&input->input_device, NULL, ev->time);
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_mod_comp_wl_cb_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
|
||||
{
|
||||
Wayland_Input *input;
|
||||
Ecore_X_Event_Mouse_In *ev;
|
||||
|
||||
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
ev = event;
|
||||
if (wl_list_empty(&_wl_comp->surfaces)) return ECORE_CALLBACK_PASS_ON;
|
||||
input = e_mod_comp_wl_input_get();
|
||||
input->input_device.x = ev->x;
|
||||
input->input_device.y = ev->y;
|
||||
|
||||
_e_mod_comp_wl_comp_repick(&input->input_device, ev->time);
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_mod_comp_wl_cb_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
|
||||
{
|
||||
Wayland_Input *input;
|
||||
Ecore_X_Event_Mouse_Out *ev;
|
||||
|
||||
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
ev = event;
|
||||
if (wl_list_empty(&_wl_comp->surfaces)) return ECORE_CALLBACK_PASS_ON;
|
||||
input = e_mod_comp_wl_input_get();
|
||||
|
||||
_e_mod_comp_wl_comp_repick(&input->input_device, ev->time);
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_mod_comp_wl_cb_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
|
||||
{
|
||||
Wayland_Input *input;
|
||||
Ecore_Event_Mouse_Move *ev;
|
||||
struct wl_input_device *device;
|
||||
const struct wl_grab_interface *interface;
|
||||
|
||||
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
ev = event;
|
||||
if (wl_list_empty(&_wl_comp->surfaces)) return ECORE_CALLBACK_PASS_ON;
|
||||
|
||||
input = e_mod_comp_wl_input_get();
|
||||
device = &input->input_device;
|
||||
device->x = ev->x;
|
||||
device->y = ev->y;
|
||||
|
||||
_e_mod_comp_wl_comp_repick(device, ev->timestamp);
|
||||
|
||||
interface = device->grab->interface;
|
||||
interface->motion(device->grab, ev->timestamp,
|
||||
device->grab->x, device->grab->y);
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_mod_comp_wl_cb_mouse_down(void *data __UNUSED__, int type __UNUSED__, void *event)
|
||||
{
|
||||
Wayland_Input *input;
|
||||
Ecore_Event_Mouse_Button *ev;
|
||||
struct wl_input_device *device;
|
||||
int btn = 0;
|
||||
|
||||
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
ev = event;
|
||||
if (wl_list_empty(&_wl_comp->surfaces)) return ECORE_CALLBACK_PASS_ON;
|
||||
|
||||
switch (ev->buttons)
|
||||
{
|
||||
case 1:
|
||||
btn = ev->buttons + BTN_LEFT - 1;
|
||||
break;
|
||||
case 2:
|
||||
btn = BTN_MIDDLE;
|
||||
break;
|
||||
case 3:
|
||||
btn = BTN_RIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
input = e_mod_comp_wl_input_get();
|
||||
device = &input->input_device;
|
||||
if (device->button_count == 0)
|
||||
{
|
||||
device->grab_button = btn;
|
||||
device->grab_time = ev->timestamp;
|
||||
device->grab_x = device->x;
|
||||
device->grab_y = device->y;
|
||||
}
|
||||
|
||||
device->button_count++;
|
||||
|
||||
/* TODO: Run binding ?? */
|
||||
device->grab->interface->button(device->grab, ev->timestamp, btn, 1);
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_mod_comp_wl_cb_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event)
|
||||
{
|
||||
Wayland_Input *input;
|
||||
Ecore_Event_Mouse_Button *ev;
|
||||
struct wl_input_device *device;
|
||||
int btn = 0;
|
||||
|
||||
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
ev = event;
|
||||
if (wl_list_empty(&_wl_comp->surfaces)) return ECORE_CALLBACK_PASS_ON;
|
||||
|
||||
switch (ev->buttons)
|
||||
{
|
||||
case 1:
|
||||
btn = ev->buttons + BTN_LEFT - 1;
|
||||
break;
|
||||
case 2:
|
||||
btn = BTN_MIDDLE;
|
||||
break;
|
||||
case 3:
|
||||
btn = BTN_RIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
input = e_mod_comp_wl_input_get();
|
||||
device = &input->input_device;
|
||||
|
||||
device->button_count--;
|
||||
|
||||
/* TODO: Run binding ?? */
|
||||
device->grab->interface->button(device->grab, ev->timestamp, btn, 0);
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_mod_comp_wl_cb_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
|
||||
{
|
||||
Wayland_Input *input;
|
||||
Ecore_Event_Key *ev;
|
||||
struct wl_input_device *device;
|
||||
uint32_t *k, *end, key = 0;
|
||||
|
||||
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
ev = event;
|
||||
if (wl_list_empty(&_wl_comp->surfaces)) return ECORE_CALLBACK_PASS_ON;
|
||||
|
||||
input = e_mod_comp_wl_input_get();
|
||||
device = &input->input_device;
|
||||
|
||||
key = ecore_x_keysym_keycode_get(ev->key);
|
||||
|
||||
_e_mod_comp_wl_comp_update_modifier(input, key, 1);
|
||||
|
||||
end = device->keys.data + device->keys.size;
|
||||
for (k = device->keys.data; k < end; k++)
|
||||
if (*k == key) *k = *--end;
|
||||
device->keys.size = (void *)end - device->keys.data;
|
||||
|
||||
k = wl_array_add(&device->keys, sizeof(*k));
|
||||
*k = key;
|
||||
|
||||
if (device->keyboard_focus_resource)
|
||||
wl_resource_post_event(device->keyboard_focus_resource,
|
||||
WL_INPUT_DEVICE_KEY, ev->timestamp, key, 1);
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_e_mod_comp_wl_cb_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
|
||||
{
|
||||
Wayland_Input *input;
|
||||
Ecore_Event_Key *ev;
|
||||
struct wl_input_device *device;
|
||||
uint32_t *k, *end, key = 0;
|
||||
|
||||
// LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
ev = event;
|
||||
if (wl_list_empty(&_wl_comp->surfaces)) return ECORE_CALLBACK_PASS_ON;
|
||||
|
||||
input = e_mod_comp_wl_input_get();
|
||||
device = &input->input_device;
|
||||
|
||||
key = ecore_x_keysym_keycode_get(ev->key);
|
||||
|
||||
_e_mod_comp_wl_comp_update_modifier(input, key, 0);
|
||||
|
||||
end = device->keys.data + device->keys.size;
|
||||
for (k = device->keys.data; k < end; k++)
|
||||
if (*k == key) *k = *--end;
|
||||
device->keys.size = (void *)end - device->keys.data;
|
||||
|
||||
/* k = wl_array_add(&device->keys, sizeof(*k)); */
|
||||
/* *k = ev->key; */
|
||||
|
||||
if (device->keyboard_focus_resource)
|
||||
wl_resource_post_event(device->keyboard_focus_resource,
|
||||
WL_INPUT_DEVICE_KEY, ev->timestamp, key, 0);
|
||||
|
||||
return ECORE_CALLBACK_PASS_ON;
|
||||
}
|
||||
|
||||
static void
|
||||
_e_mod_comp_wl_comp_repick(struct wl_input_device *device, uint32_t timestamp)
|
||||
{
|
||||
Wayland_Surface *ws, *focus;
|
||||
|
||||
ws =
|
||||
_e_mod_comp_wl_comp_pick_surface(device->x, device->y,
|
||||
&device->current_x, &device->current_y);
|
||||
if (&ws->surface != device->current)
|
||||
{
|
||||
const struct wl_grab_interface *interface;
|
||||
|
||||
interface = device->grab->interface;
|
||||
interface->focus(device->grab, timestamp, &ws->surface,
|
||||
device->current_x, device->current_y);
|
||||
device->current = &ws->surface;
|
||||
}
|
||||
|
||||
if ((focus = (Wayland_Surface *)device->grab->focus))
|
||||
{
|
||||
device->grab->x = device->x - focus->x;
|
||||
device->grab->y = device->y - focus->y;
|
||||
}
|
||||
}
|
||||
|
||||
static Wayland_Surface *
|
||||
_e_mod_comp_wl_comp_pick_surface(int32_t x __UNUSED__, int32_t y __UNUSED__, int32_t *sx, int32_t *sy)
|
||||
{
|
||||
Wayland_Surface *ws;
|
||||
|
||||
if (wl_list_empty(&_wl_comp->surfaces)) return NULL;
|
||||
wl_list_for_each(ws, &_wl_comp->surfaces, link)
|
||||
{
|
||||
if (ws->surface.resource.client == NULL) continue;
|
||||
if ((0 <= *sx) && (*sx < ws->w) &&
|
||||
(0 <= *sy) && (*sy < ws->h))
|
||||
return ws;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_e_mod_comp_wl_comp_update_modifier(Wayland_Input *input, uint32_t key, uint32_t state)
|
||||
{
|
||||
uint32_t mod;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case KEY_LEFTCTRL:
|
||||
case KEY_RIGHTCTRL:
|
||||
mod = MODIFIER_CTRL;
|
||||
break;
|
||||
case KEY_LEFTALT:
|
||||
case KEY_RIGHTALT:
|
||||
mod = MODIFIER_ALT;
|
||||
break;
|
||||
case KEY_LEFTMETA:
|
||||
case KEY_RIGHTMETA:
|
||||
mod = MODIFIER_SUPER;
|
||||
break;
|
||||
default:
|
||||
mod = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (state)
|
||||
input->modifier_state |= mod;
|
||||
else
|
||||
input->modifier_state &= ~mod;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue