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

Reply via email to