devilhorns pushed a commit to branch devs/devilhorns/wayland.
commit a2b951c1749c2ae30e46eced0c6d175548bbc930
Author: Chris Michael <[email protected]>
Date: Mon Mar 11 10:13:19 2013 +0000
Add code to initialize input for wayland clients.
Change the init job (for loading the wl_shell module) to an idler.
Add wl_seat interface and wl_pointer interface.
Use E_EVENT_BORDER_FOCUS_* so that we can send or remove focus to the
wayland
client(s).
Signed-off-by: Chris Michael <[email protected]>
---
src/bin/e_comp_wl.c | 285 ++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 263 insertions(+), 22 deletions(-)
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index d264276..805cbcf 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -5,6 +5,15 @@
static void _e_comp_wl_cb_bind(struct wl_client *client, void *data
EINA_UNUSED, unsigned int version EINA_UNUSED, unsigned int id);
static Eina_Bool _e_comp_wl_cb_fd_handle(void *data EINA_UNUSED,
Ecore_Fd_Handler *hdl EINA_UNUSED);
+static Eina_Bool _e_comp_wl_input_init(void);
+static void _e_comp_wl_input_shutdown(void);
+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_cb_bind(struct wl_client *client, void *data,
unsigned int version EINA_UNUSED, unsigned int id);
+static void _e_comp_wl_input_cb_unbind(struct wl_resource *resource);
+static void _e_comp_wl_input_focus_cb_destroy(struct wl_listener *listener,
void *data EINA_UNUSED);
+
static void _e_comp_wl_cb_surface_create(struct wl_client *client, struct
wl_resource *resource, unsigned int id);
static void _e_comp_wl_cb_surface_destroy(struct wl_resource *resource);
static void _e_comp_wl_cb_region_create(struct wl_client *client, struct
wl_resource *resource, unsigned int id);
@@ -24,9 +33,11 @@ static void _e_comp_wl_region_cb_destroy(struct wl_client
*client EINA_UNUSED, s
static void _e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED,
struct wl_resource *resource, int x, int y, int w, int h);
static void _e_comp_wl_region_cb_subtract(struct wl_client *client
EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h);
+static void _e_comp_wl_pointer_cursor_set(struct wl_client *client, struct
wl_resource *resource, unsigned int serial, struct wl_resource *surf_resource,
int x, int y);
+
static void _e_comp_wl_frame_cb_destroy(struct wl_resource *resource);
-static void _e_comp_wl_cb_init_job(void *data EINA_UNUSED);
+static Eina_Bool _e_comp_wl_cb_idle(void *data EINA_UNUSED);
static Eina_Bool _e_comp_wl_cb_window_focus_in(void *data, int type
EINA_UNUSED, void *event);
static Eina_Bool _e_comp_wl_cb_window_focus_out(void *data, int type
EINA_UNUSED, void *event);
@@ -64,9 +75,21 @@ static const struct wl_region_interface
_e_wl_region_interface =
_e_comp_wl_region_cb_subtract
};
+static const struct wl_seat_interface _e_wl_input_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 _e_wl_pointer_interface =
+{
+ _e_comp_wl_pointer_cursor_set
+};
+
/* local variables */
-static Ecore_Job *_init_job = NULL;
-static Eina_List *_hdlrs = NULL;
+static Ecore_Idler *_idler = NULL;
+/* static Eina_List *_hdlrs = NULL; */
/* external variables */
E_Wayland_Compositor *_e_wl_comp;
@@ -113,14 +136,13 @@ e_comp_wl_init(void)
wl_signal_init(&_e_wl_comp->wl.signals.destroy);
wl_signal_init(&_e_wl_comp->wl.signals.activate);
wl_signal_init(&_e_wl_comp->wl.signals.kill);
- wl_signal_init(&_e_wl_comp->wl.signals.idle);
- wl_signal_init(&_e_wl_comp->wl.signals.wake);
+ /* wl_signal_init(&_e_wl_comp->wl.signals.idle); */
+ /* wl_signal_init(&_e_wl_comp->wl.signals.wake); */
wl_signal_init(&_e_wl_comp->wl.signals.seat);
/* initialize compositor lists */
wl_list_init(&_e_wl_comp->wl.lists.surface);
-
- /* TODO: ping_handler = NULL */
+ wl_list_init(&_e_wl_comp->wl.lists.seat);
/* initalize the wayland data device manager */
wl_data_device_manager_init(_e_wl_comp->wl.display);
@@ -129,9 +151,16 @@ e_comp_wl_init(void)
if (wl_display_init_shm(_e_wl_comp->wl.display) < 0)
ERR("Could not intiialize SHM !!!");
- /* setup a job handler so we can load the wl_shell module after
+ /* try to initialize input */
+ if (!_e_comp_wl_input_init())
+ {
+ ERR("Could not initialize input: %m");
+ goto err;
+ }
+
+ /* setup an idler so we can load the wl_shell module after
* init has completed */
- _init_job = ecore_job_add(_e_comp_wl_cb_init_job, NULL);
+ _idler = ecore_idler_add(_e_comp_wl_cb_idle, NULL);
/* get the display's event loop */
loop = wl_display_get_event_loop(_e_wl_comp->wl.display);
@@ -181,6 +210,11 @@ e_comp_wl_shutdown(void)
/* E_FREE_LIST(_hdlrs, ecore_event_handler_del); */
+ if (_idler) ecore_idler_del(_idler);
+ _idler = NULL;
+
+ _e_comp_wl_input_shutdown();
+
wl_signal_emit(&_e_wl_comp->wl.signals.destroy, _e_wl_comp);
if (_e_wl_comp->fd_handler)
@@ -223,6 +257,183 @@ _e_comp_wl_cb_fd_handle(void *data EINA_UNUSED,
Ecore_Fd_Handler *hdl EINA_UNUSE
return ECORE_CALLBACK_RENEW;
}
+static Eina_Bool
+_e_comp_wl_input_init(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(_e_wl_comp->input = E_NEW(E_Wayland_Input, 1)))
+ return EINA_FALSE;
+
+ _e_wl_comp->input->pointer = EINA_FALSE;
+ _e_wl_comp->input->keyboard = EINA_FALSE;
+ _e_wl_comp->input->touch = EINA_FALSE;
+
+ wl_seat_init(&_e_wl_comp->input->wl.seat);
+
+ if (!wl_display_add_global(_e_wl_comp->wl.display,
+ &wl_seat_interface, _e_wl_comp->input,
+ _e_comp_wl_input_cb_bind))
+ {
+ ERR("Could not Add Input to Globals: %m");
+ goto err;
+ }
+
+ wl_pointer_init(&_e_wl_comp->input->wl.pointer);
+ wl_seat_set_pointer(&_e_wl_comp->input->wl.seat,
+ &_e_wl_comp->input->wl.pointer);
+ _e_wl_comp->input->pointer = EINA_TRUE;
+
+ wl_keyboard_init(&_e_wl_comp->input->wl.keyboard);
+ wl_seat_set_keyboard(&_e_wl_comp->input->wl.seat,
+ &_e_wl_comp->input->wl.keyboard);
+ _e_wl_comp->input->keyboard = EINA_TRUE;
+
+ /* TODO: handle cases of touch ? */
+
+ wl_list_insert(_e_wl_comp->wl.lists.seat.prev, &_e_wl_comp->input->wl.link);
+ wl_signal_emit(&_e_wl_comp->wl.signals.seat, _e_wl_comp->input);
+
+ return EINA_TRUE;
+
+err:
+ E_FREE(_e_wl_comp->input);
+ return EINA_FALSE;
+}
+
+static void
+_e_comp_wl_input_shutdown(void)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (_e_wl_comp->input)
+ {
+ wl_list_remove(&_e_wl_comp->input->wl.link);
+ wl_seat_release(&_e_wl_comp->input->wl.seat);
+
+ E_FREE(_e_wl_comp->input);
+ }
+}
+
+static void
+_e_comp_wl_input_pointer_get(struct wl_client *client, struct wl_resource
*resource, unsigned int id)
+{
+ E_Wayland_Input *input = NULL;
+ struct wl_resource *ptr = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(input = resource->data)) return;
+ if (!input->pointer) return;
+
+ ptr = wl_client_add_object(client, &wl_pointer_interface,
+ &_e_wl_pointer_interface, id, input);
+ wl_list_insert(&input->wl.seat.pointer->resource_list, &ptr->link);
+ ptr->destroy = _e_comp_wl_input_cb_unbind;
+
+ if ((input->wl.seat.pointer->focus) &&
+ (input->wl.seat.pointer->focus->resource.client == client))
+ {
+ E_Wayland_Surface *ews = NULL;
+
+ if ((ews = (E_Wayland_Surface *)input->wl.seat.pointer->focus))
+ wl_pointer_set_focus(input->wl.seat.pointer,
+ input->wl.seat.pointer->focus,
+ ews->geometry.x, ews->geometry.y);
+ }
+}
+
+static void
+_e_comp_wl_input_keyboard_get(struct wl_client *client, struct wl_resource
*resource, unsigned int id)
+{
+ E_Wayland_Input *input = NULL;
+ struct wl_resource *kbd = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(input = resource->data)) return;
+ if (!input->keyboard) return;
+
+ kbd = wl_client_add_object(client, &wl_keyboard_interface, NULL, id, input);
+ wl_list_insert(&input->wl.seat.keyboard->resource_list, &kbd->link);
+ kbd->destroy = _e_comp_wl_input_cb_unbind;
+
+ /* TODO: send keymap ? */
+
+ if ((input->wl.seat.keyboard->focus) &&
+ (input->wl.seat.keyboard->focus->resource.client == client))
+ {
+ wl_keyboard_set_focus(input->wl.seat.keyboard,
+ input->wl.seat.keyboard->focus);
+ wl_data_device_set_keyboard_focus(&input->wl.seat);
+ }
+
+}
+
+static void
+_e_comp_wl_input_touch_get(struct wl_client *client, struct wl_resource
*resource, unsigned int id)
+{
+ E_Wayland_Input *input = NULL;
+ struct wl_resource *touch = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(input = resource->data)) return;
+ if (!input->touch) return;
+
+ touch = wl_client_add_object(client, &wl_touch_interface, NULL, id, input);
+ wl_list_insert(&input->wl.seat.touch->resource_list, &touch->link);
+ touch->destroy = _e_comp_wl_input_cb_unbind;
+}
+
+static void
+_e_comp_wl_input_cb_bind(struct wl_client *client, void *data, unsigned int
version EINA_UNUSED, unsigned int id)
+{
+ struct wl_seat *seat = NULL;
+ struct wl_resource *resource = NULL;
+ enum wl_seat_capability caps = 0;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (!(seat = data)) return;
+
+ resource = wl_client_add_object(client, &wl_seat_interface,
+ &_e_wl_input_interface, id, data);
+ wl_list_insert(&seat->base_resource_list, &resource->link);
+ resource->destroy = _e_comp_wl_input_cb_unbind;
+
+ if (seat->pointer)
+ caps |= WL_SEAT_CAPABILITY_POINTER;
+ if (seat->keyboard)
+ caps |= WL_SEAT_CAPABILITY_KEYBOARD;
+ if (seat->touch)
+ caps |= WL_SEAT_CAPABILITY_TOUCH;
+
+ wl_seat_send_capabilities(resource, caps);
+}
+
+static void
+_e_comp_wl_input_cb_unbind(struct wl_resource *resource)
+{
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ wl_list_remove(&resource->link);
+ free(resource);
+}
+
+static void
+_e_comp_wl_input_focus_cb_destroy(struct wl_listener *listener, void *data
EINA_UNUSED)
+{
+ E_Wayland_Input *input = NULL;
+
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ input = container_of(listener, E_Wayland_Input, focus_listener);
+ if (!input) return;
+
+ input->focus = NULL;
+}
+
static void
_e_comp_wl_cb_surface_create(struct wl_client *client, struct wl_resource
*resource, unsigned int id)
{
@@ -643,6 +854,12 @@ _e_comp_wl_region_cb_subtract(struct wl_client *client
EINA_UNUSED, struct wl_re
}
static void
+_e_comp_wl_pointer_cursor_set(struct wl_client *client, struct wl_resource
*resource, unsigned int serial, struct wl_resource *surf_resource, int x, int y)
+{
+
+}
+
+static void
_e_comp_wl_frame_cb_destroy(struct wl_resource *resource)
{
E_Wayland_Frame_Cb *cb = NULL;
@@ -654,24 +871,26 @@ _e_comp_wl_frame_cb_destroy(struct wl_resource *resource)
free(cb);
}
-static void
-_e_comp_wl_cb_init_job(void *data EINA_UNUSED)
+static Eina_Bool
+_e_comp_wl_cb_idle(void *data EINA_UNUSED)
{
E_Module *mod = NULL;
- /* if we are still in the process of loading modules, get out */
- if (e_module_loading_get()) return;
+ LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+ if (e_module_loading_get()) return ECORE_CALLBACK_RENEW;
- /* all modules have been loaded now.
- * try to find the wl_shell module, and enable it if not there */
if (!(mod = e_module_find("wl_shell")))
+ mod = e_module_new("wl_shell");
+
+ if (mod)
{
- if ((mod = e_module_new("wl_shell")))
- e_module_enable(mod);
+ e_module_enable(mod);
+ _idler = NULL;
+ return ECORE_CALLBACK_CANCEL;
}
- if (_init_job) ecore_job_del(_init_job);
- _init_job = NULL;
+ return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
@@ -679,6 +898,7 @@ _e_comp_wl_cb_window_focus_in(void *data, int type
EINA_UNUSED, void *event)
{
E_Wayland_Surface *ews = NULL;
E_Event_Border_Focus_In *ev;
+ struct wl_keyboard *kbd;
if (!(ews = data)) return ECORE_CALLBACK_PASS_ON;
if (!(ev = event)) return ECORE_CALLBACK_PASS_ON;
@@ -686,9 +906,16 @@ _e_comp_wl_cb_window_focus_in(void *data, int type
EINA_UNUSED, void *event)
if ((!ews->win) || (!ews->win->border)) return ECORE_CALLBACK_PASS_ON;
if (ev->border != ews->win->border) return ECORE_CALLBACK_PASS_ON;
- /* TODO */
+ kbd = _e_wl_comp->input->wl.seat.keyboard;
+
+ if (_e_wl_comp->input->focus)
+ {
+ wl_list_remove(&_e_wl_comp->input->focus_listener.link);
+ _e_wl_comp->input->focus = NULL;
+ }
printf("Focus This Wayland Surface !!\n");
+ wl_keyboard_set_focus(kbd, &ews->wl.surface);
return ECORE_CALLBACK_PASS_ON;
}
@@ -698,6 +925,7 @@ _e_comp_wl_cb_window_focus_out(void *data, int type
EINA_UNUSED, void *event)
{
E_Wayland_Surface *ews = NULL;
E_Event_Border_Focus_Out *ev;
+ struct wl_keyboard *kbd;
if (!(ews = data)) return ECORE_CALLBACK_PASS_ON;
if (!(ev = event)) return ECORE_CALLBACK_PASS_ON;
@@ -705,10 +933,23 @@ _e_comp_wl_cb_window_focus_out(void *data, int type
EINA_UNUSED, void *event)
if ((!ews->win) || (!ews->win->border)) return ECORE_CALLBACK_PASS_ON;
if (ev->border != ews->win->border) return ECORE_CALLBACK_PASS_ON;
- /* TODO */
-
printf("Unfocus This Wayland Surface !!\n");
+ kbd = _e_wl_comp->input->wl.seat.keyboard;
+
+ if (kbd->focus)
+ {
+ _e_wl_comp->input->focus = kbd->focus;
+ _e_wl_comp->input->focus_listener.notify =
+ _e_comp_wl_input_focus_cb_destroy;
+
+ wl_signal_add(&kbd->focus->resource.destroy_signal,
+ &_e_wl_comp->input->focus_listener);
+ }
+
+ wl_keyboard_set_focus(kbd, NULL);
+ wl_keyboard_end_grab(kbd);
+
return ECORE_CALLBACK_PASS_ON;
}
--
------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev