Big giant push to get elm apps working properly
authorChris Michael <devilhorns@comcast.net>
Tue, 18 Jun 2013 20:08:07 +0000 (21:08 +0100)
committerChris Michael <devilhorns@comcast.net>
Tue, 18 Jun 2013 20:08:07 +0000 (21:08 +0100)
Signed-off-by: Chris Michael <devilhorns@comcast.net>
src/bin/e_wayland/e.h
src/bin/e_wayland/e_comp.c
src/bin/e_wayland/e_comp.h
src/bin/e_wayland/e_input.c
src/bin/e_wayland/e_input.h
src/bin/e_wayland/e_menu.c
src/bin/e_wayland/e_output.c
src/bin/e_wayland/e_shell_surface.h
src/bin/e_wayland/e_surface.c
src/bin/e_wayland/e_surface.h

index 9287bc0aa13114ed57abeed60c9341490c8cfa7d..191f0feca75e8c9af137f53123afc4656aa07e7d 100644 (file)
@@ -121,6 +121,7 @@ void *alloca (size_t);
 
 # include <pixman.h>
 # include <wayland-server.h>
+# include <xkbcommon/xkbcommon.h>
 
 # ifdef HAVE_WAYLAND_EGL
 #  include <GLES2/gl2.h>
index c9071794ad9a850d93120bf1b486e7aa728a4586..2095a3373bdd26be445939ba51b9939c3faea810 100644 (file)
@@ -10,9 +10,11 @@ static void _e_comp_cb_region_destroy(struct wl_resource *resource);
 static Eina_Bool _e_comp_cb_read(void *data, Ecore_Fd_Handler *hdl EINA_UNUSED);
 static Eina_Bool _e_comp_cb_idle(void *data);
 
-static void _e_comp_data_device_cb_get(struct wl_client *client, struct wl_resource *resource, unsigned int id, struct wl_resource *seat_resource);
+static void _e_comp_data_device_cb_get(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, unsigned int id, struct wl_resource *seat_resource);
 static void _e_comp_data_device_cb_unbind(struct wl_resource *resource);
 
+static Eina_Bool _e_comp_xkb_init(E_Compositor *comp);
+
 /* local interfaces */
 static const struct wl_compositor_interface _e_compositor_interface = 
 {
@@ -121,7 +123,12 @@ e_compositor_init(E_Compositor *comp, void *display)
    e_plane_init(&comp->plane, 0, 0);
    e_compositor_plane_stack(comp, &comp->plane, NULL);
 
-   /* TODO: init xkb */
+   /* init xkb */
+   if (!_e_comp_xkb_init(comp))
+     {
+        ERR("Could not initialize xkb: %m");
+        goto global_err;
+     }
 
    /* initialize the data device manager */
    if (!wl_display_add_global(comp->wl.display, 
@@ -141,7 +148,10 @@ e_compositor_init(E_Compositor *comp, void *display)
     * 
     * NB: This is interesting....if we try to eglGetDisplay and pass in the 
     * wayland display, then EGL fails due to XCB not owning the event queue.
-    * If we pass it a NULL, it inits just fine */
+    * If we pass it a NULL, it inits just fine
+    * 
+    * NB: This is apparently a Mesa bug because it works now :/ Leaving this 
+    * note here in case it fails again in the future */
    comp->egl.display = eglGetDisplay((EGLNativeDisplayType)display);
    if (comp->egl.display == EGL_NO_DISPLAY)
      ERR("Could not get EGL display: %m");
@@ -348,7 +358,9 @@ e_compositor_surface_find(E_Compositor *comp, Evas_Coord x, Evas_Coord y)
    E_Surface *es;
    Eina_List *l;
 
-   EINA_LIST_FOREACH(comp->surfaces, l, es)
+   /* loop the surfaces and try to find one which has these
+    * coordinates contained in it's input region */
+   EINA_LIST_REVERSE_FOREACH(comp->surfaces, l, es)
      {
         if (pixman_region32_contains_point(&es->input, x, y, NULL))
           return es;
@@ -357,6 +369,17 @@ e_compositor_surface_find(E_Compositor *comp, Evas_Coord x, Evas_Coord y)
    return NULL;
 }
 
+EAPI void 
+e_compositor_repick(E_Compositor *comp)
+{
+   E_Input *seat;
+   Eina_List *l;
+
+   if (!comp->focus) return;
+   EINA_LIST_FOREACH(comp->inputs, l, seat)
+     e_input_repick(seat);
+}
+
 /* local functions */
 static void 
 _e_comp_cb_bind(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id)
@@ -384,18 +407,19 @@ _e_comp_cb_surface_create(struct wl_client *client, struct wl_resource *resource
    E_Compositor *comp;
    E_Surface *es;
 
-   printf("E_Comp Surface Create: %d\n", id);
-
    /* try to cast to our compositor */
    if (!(comp = resource->data)) return;
 
    /* try to create a new surface */
-   if (!(es = e_surface_new(id)))
+   if (!(es = e_surface_new(client, id)))
      {
         wl_resource_post_no_memory(resource);
         return;
      }
 
+   /* set destroy callback */
+   wl_resource_set_destructor(es->wl.resource, _e_comp_cb_surface_destroy);
+
    /* ask the renderer to create any internal representation of this surface 
     * that it may need */
    if (!comp->renderer->surface_create(es))
@@ -407,69 +431,25 @@ _e_comp_cb_surface_create(struct wl_client *client, struct wl_resource *resource
    /* set surface plane to compositor primary plane */
    es->plane = &comp->plane;
 
-   /* set destroy callback */
-   es->wl.resource.destroy = _e_comp_cb_surface_destroy;
-
-   /* add this surface to the client */
-   wl_client_add_resource(client, &es->wl.resource);
-
    /* add this surface to the compositors list */
    comp->surfaces = eina_list_append(comp->surfaces, es);
-
-   printf("\tCreated: %p\n", es);
 }
 
 static void 
 _e_comp_cb_surface_destroy(struct wl_resource *resource)
 {
    E_Surface *es;
-   E_Surface_Frame *cb, *cbnext;
-
-   printf("E_Comp Surface Destroy\n");
 
-   /* try to get the surface from this resource */
-   if (!(es = container_of(resource, E_Surface, wl.resource)))
+   if (!(es = wl_resource_get_user_data(resource)))
      return;
 
-   printf("\tDestroyed: %p\n", es);
+   printf("Surface Destroy: %p\n", es);
 
    /* remove this surface from the compositor */
    _e_comp->surfaces = eina_list_remove(_e_comp->surfaces, es);
 
-   /* if this surface is mapped, unmap it */
-   if (es->mapped) e_surface_unmap(es);
-
-   /* remove any pending frame callbacks */
-   wl_list_for_each_safe(cb, cbnext, &es->pending.frames, link)
-     wl_resource_destroy(&cb->resource);
-
-   pixman_region32_fini(&es->pending.damage);
-   pixman_region32_fini(&es->pending.opaque);
-   pixman_region32_fini(&es->pending.input);
-
-   /* destroy pending buffer */
-   if (es->pending.buffer)
-     wl_list_remove(&es->pending.buffer_destroy.link);
-
-   /* remove any buffer references */
-   e_buffer_reference(&es->buffer.reference, NULL);
-
-   if (_e_comp->renderer->surface_destroy)
-     _e_comp->renderer->surface_destroy(es);
-
-   /* free regions */
-   pixman_region32_fini(&es->bounding);
-   pixman_region32_fini(&es->damage);
-   pixman_region32_fini(&es->opaque);
-   pixman_region32_fini(&es->input);
-   pixman_region32_fini(&es->clip);
-
-   /* remove any active frame callbacks */
-   wl_list_for_each_safe(cb, cbnext, &es->frames, link)
-     wl_resource_destroy(&cb->resource);
-
-   /* free the surface structure */
-   E_FREE(es);
+   es->wl.resource = NULL;
+   e_surface_destroy(es);
 }
 
 static void 
@@ -538,7 +518,7 @@ _e_comp_cb_idle(void *data)
 }
 
 static void 
-_e_comp_data_device_cb_get(struct wl_client *client, struct wl_resource *resource, unsigned int id, struct wl_resource *seat_resource)
+_e_comp_data_device_cb_get(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, unsigned int id, struct wl_resource *seat_resource)
 {
    E_Input *seat;
    struct wl_resource *res;
@@ -559,3 +539,19 @@ _e_comp_data_device_cb_unbind(struct wl_resource *resource)
    wl_list_remove(&resource->link);
    free(resource);
 }
+
+static Eina_Bool 
+_e_comp_xkb_init(E_Compositor *comp)
+{
+   if (!(comp->xkb_context = xkb_context_new(0)))
+     return EINA_FALSE;
+
+   if (!comp->xkb_names.rules)
+     comp->xkb_names.rules = strdup("evdev");
+   if (!comp->xkb_names.model)
+     comp->xkb_names.model = strdup("pc105");
+   if (!comp->xkb_names.layout)
+     comp->xkb_names.layout = strdup("us");
+
+   return EINA_TRUE;
+}
index a76273da001502b651c29035366ab3b15475ff63..7ad572de435ebf46455754cf312973abc9a42a99 100644 (file)
@@ -47,6 +47,8 @@ struct _E_Compositor
    Ecore_Fd_Handler *fd_hdlr;
    Ecore_Idler *idler;
 
+   Eina_Bool focus : 1;
+
    unsigned int output_pool;
 
    Eina_List *planes;
@@ -54,7 +56,10 @@ struct _E_Compositor
    Eina_List *inputs;
    Eina_List *surfaces;
 
-   void (*cb_ping) (void *surface, unsigned int serial);
+   void (*cb_ping) (E_Surface *surface, unsigned int serial);
+
+   struct xkb_rule_names xkb_names;
+   struct xkb_context *xkb_context;
 };
 
 EINTERN int e_comp_init(void);
@@ -68,6 +73,7 @@ EAPI int e_compositor_input_read(int fd EINA_UNUSED, unsigned int mask EINA_UNUS
 EAPI void e_compositor_damage_calculate(E_Compositor *comp);
 EAPI unsigned int e_compositor_get_time(void);
 EAPI E_Surface *e_compositor_surface_find(E_Compositor *comp, Evas_Coord x, Evas_Coord y);
+EAPI void e_compositor_repick(E_Compositor *comp);
 
 # endif
 #endif
index f9dfb2c68e96b04b196df7f24e4d129a2c5ae209..2cfb8496524dd7ac69a93cdb890b45014af34dd7 100644 (file)
@@ -1,4 +1,6 @@
 #include "e.h"
+#include <sys/mman.h>
+#include <fcntl.h>
 
 /* local function prototypes */
 static void _e_input_capabilities_update(E_Input *seat);
@@ -9,9 +11,14 @@ static void _e_input_cb_pointer_get(struct wl_client *client, struct wl_resource
 static void _e_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, unsigned int id);
 static void _e_input_cb_touch_get(struct wl_client *client, struct wl_resource *resource, unsigned int id);
 static void _e_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource, unsigned int serial, struct wl_resource *surface_resource, int x, int y);
+static void _e_input_pointer_cb_focus(struct wl_listener *listener, void *data EINA_UNUSED);
 static void _e_input_pointer_grab_cb_focus(E_Input_Pointer_Grab *grab);
 static void _e_input_pointer_grab_cb_motion(E_Input_Pointer_Grab *grab, unsigned int timestamp);
 static void _e_input_pointer_grab_cb_button(E_Input_Pointer_Grab *grab, unsigned int timestamp, unsigned int button, unsigned int state);
+static int _e_input_keyboard_keymap_fd_get(off_t size);
+static void _e_input_keyboard_cb_focus(struct wl_listener *listener, void *data EINA_UNUSED);
+static void _e_input_keyboard_grab_cb_key(E_Input_Keyboard_Grab *grab, unsigned int timestamp, unsigned int key, unsigned int state);
+static void _e_input_keyboard_grab_cb_modifiers(E_Input_Keyboard_Grab *grab, unsigned int serial, unsigned int pressed, unsigned int latched, unsigned int locked, unsigned int group);
 
 static struct wl_resource *_e_input_surface_resource_get(struct wl_list *list, E_Surface *surface);
 
@@ -35,6 +42,12 @@ static E_Input_Pointer_Grab_Interface _e_pointer_grab_interface =
    _e_input_pointer_grab_cb_button
 };
 
+static E_Input_Keyboard_Grab_Interface _e_keyboard_grab_interface = 
+{
+   _e_input_keyboard_grab_cb_key,
+   _e_input_keyboard_grab_cb_modifiers,
+};
+
 /* external functions */
 EAPI Eina_Bool 
 e_input_init(E_Compositor *comp, E_Input *seat, const char *name)
@@ -84,14 +97,12 @@ e_input_pointer_init(E_Input *seat)
    /* try to allocate space for new pointer structure */
    if (!(ptr = E_NEW(E_Input_Pointer, 1))) return EINA_FALSE;
 
-   /* FIXME: Finish setting up pointer */
-
    wl_list_init(&ptr->resources);
-   wl_signal_init(&ptr->signals.focus);
-
+   ptr->focus_listener.notify = _e_input_pointer_cb_focus;
    ptr->default_grab.interface = &_e_pointer_grab_interface;
    ptr->default_grab.pointer = ptr;
    ptr->grab = &ptr->default_grab;
+   wl_signal_init(&ptr->signals.focus);
 
    wl_list_init(&ptr->grab->surfaces);
 
@@ -104,8 +115,38 @@ e_input_pointer_init(E_Input *seat)
 }
 
 EAPI Eina_Bool 
-e_input_keyboard_init(E_Input *seat)
+e_input_keyboard_init(E_Input *seat, struct xkb_keymap *keymap)
 {
+   if (seat->keyboard) return EINA_TRUE;
+
+   if (keymap)
+     {
+        seat->kbd_info.keymap = xkb_map_ref(keymap);
+        if (!e_input_keyboard_info_keymap_add(&seat->kbd_info))
+          {
+             xkb_map_unref(seat->kbd_info.keymap);
+             return EINA_FALSE;
+          }
+     }
+   else
+     {
+        /* TODO: build a global keymap */
+     }
+
+   if (!(seat->kbd.state = xkb_state_new(seat->kbd_info.keymap)))
+     {
+        /* TODO: cleanup keymap */
+        return EINA_FALSE;
+     }
+
+   if (!(seat->keyboard = e_input_keyboard_add(seat)))
+     {
+        /* TODO: cleanup */
+        return EINA_FALSE;
+     }
+
+   _e_input_capabilities_update(seat);
+
    return EINA_TRUE;
 }
 
@@ -118,36 +159,51 @@ e_input_touch_init(E_Input *seat)
 EAPI void 
 e_input_pointer_focus_set(E_Input_Pointer *pointer, E_Surface *surface, Evas_Coord x, Evas_Coord y)
 {
+   E_Input_Keyboard *kbd;
    struct wl_resource *resource;
    struct wl_display *disp;
    unsigned int serial = 0;
 
+   kbd = pointer->seat->keyboard;
+
    resource = pointer->focus_resource;
    if ((resource) && (pointer->focus != surface))
      {
         disp = wl_client_get_display(resource->client);
-        serial = e_compositor_get_time();
-//        serial = wl_display_next_serial(disp);
-        wl_pointer_send_leave(resource, serial, &pointer->focus->wl.resource);
-        /* wl_list_remove(&pointer->focus_listener.link); */
+        serial = wl_display_next_serial(disp);
+        wl_pointer_send_leave(resource, serial, pointer->focus->wl.resource);
+//        wl_list_remove(&pointer->focus_listener.link);
      }
 
-   resource = _e_input_surface_resource_get(&pointer->resources, surface);
+   if (!surface) return;
 
-//   resource = &surface->wl.resource;
+   resource = _e_input_surface_resource_get(&pointer->resources, surface);
    if ((resource) && 
        ((pointer->focus != surface) || 
            (pointer->focus_resource != resource)))
      {
         disp = wl_client_get_display(resource->client);
-        serial = e_compositor_get_time();
-//        serial = wl_display_next_serial(disp);
-
-        wl_pointer_send_enter(resource, serial, &surface->wl.resource, 
-                              wl_fixed_from_int(pointer->x), 
-                              wl_fixed_from_int(pointer->y));
-        /* wl_signal_add(&resource->destroy_signal, &pointer->focus_listener); */
-        /* pointer->focus_serial = serial; */
+        serial = wl_display_next_serial(disp);
+
+        if (kbd)
+          {
+             struct wl_resource *res;
+
+             res = _e_input_surface_resource_get(&kbd->resources, surface);
+             if (res)
+               {
+                  wl_keyboard_send_modifiers(res, serial, 
+                                             kbd->modifiers.pressed,
+                                             kbd->modifiers.latched,
+                                             kbd->modifiers.locked,
+                                             kbd->modifiers.group);
+               }
+          }
+
+        wl_pointer_send_enter(resource, serial, surface->wl.resource, 
+                              wl_fixed_from_int(x), wl_fixed_from_int(y));
+        wl_signal_add(&resource->destroy_signal, &pointer->focus_listener);
+        pointer->focus_serial = serial;
      }
 
    pointer->focus_resource = resource;
@@ -184,6 +240,140 @@ e_input_pointer_grab_end(E_Input_Pointer *pointer)
      }
 }
 
+EAPI Eina_Bool 
+e_input_keyboard_info_keymap_add(E_Input_Keyboard_Info *kbd_info)
+{
+   char *str = NULL;
+
+   kbd_info->mods.shift = 
+     xkb_map_mod_get_index(kbd_info->keymap, XKB_MOD_NAME_SHIFT);
+   kbd_info->mods.caps = 
+     xkb_map_mod_get_index(kbd_info->keymap, XKB_MOD_NAME_CAPS);
+   kbd_info->mods.ctrl = 
+     xkb_map_mod_get_index(kbd_info->keymap, XKB_MOD_NAME_CTRL);
+   kbd_info->mods.alt = 
+     xkb_map_mod_get_index(kbd_info->keymap, XKB_MOD_NAME_ALT);
+   kbd_info->mods.super = 
+     xkb_map_mod_get_index(kbd_info->keymap, XKB_MOD_NAME_LOGO);
+
+   if (!(str = xkb_map_get_as_string(kbd_info->keymap)))
+     return EINA_FALSE;
+
+   kbd_info->size = strlen(str) + 1;
+   kbd_info->fd = _e_input_keyboard_keymap_fd_get(kbd_info->size);
+   if (kbd_info->fd < 0)
+     {
+        free(str);
+        return EINA_FALSE;
+     }
+
+   kbd_info->area = 
+     mmap(NULL, kbd_info->size, (PROT_READ | PROT_WRITE), 
+          MAP_SHARED, kbd_info->fd, 0);
+   if (kbd_info->area == MAP_FAILED)
+     {
+        close(kbd_info->fd);
+        kbd_info->fd = -1;
+        free(str);
+        return EINA_FALSE;
+     }
+
+   if ((kbd_info->area) && (str)) strcpy(kbd_info->area, str);
+   free(str);
+
+   return EINA_TRUE;
+}
+
+EAPI void 
+e_input_keyboard_focus_set(E_Input_Keyboard *keyboard, E_Surface *surface)
+{
+   struct wl_resource *res;
+   struct wl_display *disp;
+   unsigned int serial = 0;
+
+   if ((keyboard->focus_resource) && (keyboard->focus != surface))
+     {
+        res = keyboard->focus_resource;
+        disp = wl_client_get_display(res->client);
+        serial = wl_display_next_serial(disp);
+        printf("Send Keyboard Leave: %p\n", keyboard->focus);
+        if (surface) printf("\tSurface: %p\n", surface);
+        else printf("\tNO SURFACE\n");
+        wl_keyboard_send_leave(res, serial, keyboard->focus->wl.resource);
+        wl_list_remove(&keyboard->focus_listener.link);
+     }
+
+   res = _e_input_surface_resource_get(&keyboard->resources, surface);
+   if ((res) && 
+       ((keyboard->focus != surface) || (keyboard->focus_resource != res)))
+     {
+        disp = wl_client_get_display(res->client);
+        serial = wl_display_next_serial(disp);
+        wl_keyboard_send_modifiers(res, serial, 
+                                   keyboard->modifiers.pressed,
+                                   keyboard->modifiers.latched,
+                                   keyboard->modifiers.locked,
+                                   keyboard->modifiers.group);
+        printf("Send Keyboard Enter: %p\n", surface);
+        wl_keyboard_send_enter(res, serial, 
+                               surface->wl.resource, &keyboard->keys);
+        wl_signal_add(&res->destroy_signal, &keyboard->focus_listener);
+        keyboard->focus_serial = serial;
+     }
+
+   keyboard->focus_resource = res;
+   keyboard->focus = surface;
+   wl_signal_emit(&keyboard->signals.focus, keyboard);
+}
+
+EAPI E_Input_Keyboard *
+e_input_keyboard_add(E_Input *seat)
+{
+   E_Input_Keyboard *kbd;
+
+   if (!(kbd = E_NEW(E_Input_Keyboard, 1))) return NULL;
+
+   wl_list_init(&kbd->resources);
+   wl_array_init(&kbd->keys);
+   kbd->focus_listener.notify = _e_input_keyboard_cb_focus;
+   kbd->default_grab.interface = &_e_keyboard_grab_interface;
+   kbd->default_grab.keyboard = kbd;
+   kbd->grab = &kbd->default_grab;
+   wl_signal_init(&kbd->signals.focus);
+
+   return kbd;
+}
+
+EAPI void 
+e_input_keyboard_del(E_Input_Keyboard *keyboard)
+{
+   if (!keyboard) return;
+   if (keyboard->focus_resource) 
+     wl_list_remove(&keyboard->focus_listener.link);
+   wl_array_release(&keyboard->keys);
+   E_FREE(keyboard);
+}
+
+EAPI void 
+e_input_repick(E_Input *seat)
+{
+   E_Input_Pointer_Grab_Interface *interface;
+
+   if (!seat->pointer) return;
+   interface = seat->pointer->grab->interface;
+   interface->focus(seat->pointer->grab);
+}
+
+EAPI void 
+e_input_keyboard_focus_destroy(struct wl_listener *listener, void *data)
+{
+   E_Input *seat;
+
+   printf("Input Keyboard Focus Destroy\n");
+   if ((seat = container_of(listener, E_Input, kbd.focus_listener)))
+     seat->kbd.saved_focus = NULL;
+}
+
 /* local functions */
 static void 
 _e_input_capabilities_update(E_Input *seat)
@@ -193,9 +383,8 @@ _e_input_capabilities_update(E_Input *seat)
 
    if (seat->pointer)
      caps |= WL_SEAT_CAPABILITY_POINTER;
-
-   /* if (seat->keyboard) */
-   /*   caps |= WL_SEAT_CAPABILITY_KEYBOARD; */
+   if (seat->keyboard)
+     caps |= WL_SEAT_CAPABILITY_KEYBOARD;
    /* if (seat->touch) */
    /*   caps |= WL_SEAT_CAPABILITY_TOUCH; */
 
@@ -221,8 +410,8 @@ _e_input_cb_bind(struct wl_client *client, void *data, unsigned int version, uns
 
    if (seat->pointer)
      caps |= WL_SEAT_CAPABILITY_POINTER;
-   /* if (seat->keyboard) */
-   /*   caps |= WL_SEAT_CAPABILITY_KEYBOARD; */
+   if (seat->keyboard)
+     caps |= WL_SEAT_CAPABILITY_KEYBOARD;
    /* if (seat->touch) */
    /*   caps |= WL_SEAT_CAPABILITY_TOUCH; */
 
@@ -255,20 +444,44 @@ _e_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource,
    res->destroy = _e_input_cb_unbind;
 
    if ((seat->pointer->focus) && 
-       (seat->pointer->focus->wl.resource.client == client))
+       (wl_resource_get_client(seat->pointer->focus->wl.resource) == client))
      {
         E_Surface *es;
 
         es = seat->pointer->focus;
         e_input_pointer_focus_set(seat->pointer, es, 
-                                  seat->pointer->x, seat->pointer->y);
+                                  seat->pointer->x - es->geometry.x, 
+                                  seat->pointer->y - es->geometry.y);
      }
 }
 
 static void 
 _e_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, unsigned int id)
 {
+   E_Input *seat;
+   struct wl_resource *res;
+
+   if (!(seat = resource->data)) return;
+   if (!seat->keyboard) return;
+
+   res = wl_client_add_object(client, &wl_keyboard_interface, NULL, id, seat);
+
+   wl_list_insert(&seat->keyboard->resources, &res->link);
+
+   res->destroy = _e_input_cb_unbind;
 
+   wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, 
+                           seat->kbd_info.fd, seat->kbd_info.size);
+
+   if ((seat->keyboard->focus) && 
+       (seat->kbd.saved_focus != seat->keyboard->focus) && 
+       (wl_resource_get_client(seat->keyboard->focus->wl.resource) == client))
+     {
+        /* printf("Input Keyboard Get. Set Focus %p\n", seat->keyboard->focus); */
+        e_input_keyboard_focus_set(seat->keyboard, seat->keyboard->focus);
+        /* FIXME */
+        /* wl_data_device_set_keyboard_focus(seat); */
+     }
 }
 
 static void 
@@ -280,7 +493,29 @@ _e_input_cb_touch_get(struct wl_client *client, struct wl_resource *resource, un
 static void 
 _e_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource, unsigned int serial, struct wl_resource *surface_resource, int x, int y)
 {
+   E_Input_Pointer *ptr;
+   E_Surface *es;
 
+   if (!(ptr = resource->data)) return;
+   if (surface_resource) es = surface_resource->data;
+   if (!ptr->focus) return;
+   if (wl_resource_get_client(ptr->focus->wl.resource) != client) return;
+   if (ptr->focus_serial - serial > UINT32_MAX / 2) return;
+
+   /* TODO */
+   /* if ((es) && (es != ptr->sprite)) */
+   /*   { */
+
+   /*   } */
+}
+
+static void 
+_e_input_pointer_cb_focus(struct wl_listener *listener, void *data EINA_UNUSED)
+{
+   E_Input_Pointer *ptr;
+
+   ptr = container_of(listener, E_Input_Pointer, focus_listener);
+   ptr->focus_resource = NULL;
 }
 
 static void 
@@ -338,6 +573,90 @@ _e_input_pointer_grab_cb_button(E_Input_Pointer_Grab *grab, unsigned int timesta
      }
 }
 
+static int 
+_e_input_keyboard_keymap_fd_get(off_t size)
+{
+   const char *path;
+   char tmp[PATH_MAX];
+   int fd = 0;
+   long flags;
+
+   if (!(path = getenv("XDG_RUNTIME_DIR"))) return -1;
+
+   strcpy(tmp, path);
+   strcat(tmp, "/e_wayland-keymap-XXXXXX");
+
+   if ((fd = mkstemp(tmp)) < 0) return -1;
+
+   flags = fcntl(fd, F_GETFD);
+   fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+   if (ftruncate(fd, size) < 0)
+     {
+        close(fd);
+        return -1;
+     }
+
+   unlink(tmp);
+   return fd;
+}
+
+static void 
+_e_input_keyboard_cb_focus(struct wl_listener *listener, void *data EINA_UNUSED)
+{
+   E_Input_Keyboard *kbd;
+
+   printf("Input Keyboard Cb Focus\n");
+   kbd = container_of(listener, E_Input_Keyboard, focus_listener);
+   kbd->focus_resource = NULL;
+}
+
+static void 
+_e_input_keyboard_grab_cb_key(E_Input_Keyboard_Grab *grab, unsigned int timestamp, unsigned int key, unsigned int state)
+{
+   E_Input_Keyboard *kbd;
+   struct wl_resource *res;
+
+   if (!(kbd = grab->keyboard)) return;
+   if ((res = kbd->focus_resource))
+     {
+        struct wl_display *disp;
+        unsigned int serial = 0;
+
+        disp = wl_client_get_display(res->client);
+        serial = wl_display_next_serial(disp);
+        wl_keyboard_send_key(res, serial, timestamp, key, state);
+     }
+}
+
+static void 
+_e_input_keyboard_grab_cb_modifiers(E_Input_Keyboard_Grab *grab, unsigned int serial, unsigned int pressed, unsigned int latched, unsigned int locked, unsigned int group)
+{
+   E_Input_Keyboard *kbd;
+   E_Input_Pointer *ptr;
+   struct wl_resource *res;
+
+   if (!(kbd = grab->keyboard)) return;
+   if (!(res = kbd->focus_resource)) return;
+
+   wl_keyboard_send_modifiers(res, serial, pressed, latched, locked, group);
+
+   if (!(ptr = kbd->seat->pointer)) return;
+   if ((ptr->focus) && (ptr->focus != kbd->focus))
+     {
+        struct wl_resource *pres;
+
+        if ((pres = 
+             _e_input_surface_resource_get(&kbd->resources, ptr->focus)))
+          {
+             wl_keyboard_send_modifiers(pres, serial, 
+                                        kbd->modifiers.pressed, 
+                                        kbd->modifiers.latched,
+                                        kbd->modifiers.locked,
+                                        kbd->modifiers.group);
+          }
+     }
+}
+
 static struct wl_resource *
 _e_input_surface_resource_get(struct wl_list *list, E_Surface *surface)
 {
@@ -346,7 +665,7 @@ _e_input_surface_resource_get(struct wl_list *list, E_Surface *surface)
    if (!surface) return NULL;
 
    wl_list_for_each(ret, list, link)
-     if (ret->client == surface->wl.resource.client)
+     if (ret->client == wl_resource_get_client(surface->wl.resource))
        return ret;
 
    return NULL;
index e45ba00a86a53897f7ddbfdeca2b5840c4b0a8b2..8173e48c96ac8dc7dd2f067e83b69e5270adb08f 100644 (file)
@@ -3,13 +3,33 @@
 typedef struct _E_Input E_Input;
 typedef struct _E_Input_Pointer E_Input_Pointer;
 typedef struct _E_Input_Keyboard E_Input_Keyboard;
+typedef struct _E_Input_Keyboard_Info E_Input_Keyboard_Info;
 typedef struct _E_Input_Pointer_Grab E_Input_Pointer_Grab;
 typedef struct _E_Input_Pointer_Grab_Interface E_Input_Pointer_Grab_Interface;
+typedef struct _E_Input_Keyboard_Grab E_Input_Keyboard_Grab;
+typedef struct _E_Input_Keyboard_Grab_Interface E_Input_Keyboard_Grab_Interface;
 
 #else
 # ifndef E_INPUT_H
 #  define E_INPUT_H
 
+struct _E_Input_Keyboard_Info
+{
+   struct xkb_keymap *keymap;
+   int fd;
+   size_t size;
+   char *area;
+   struct 
+     {
+        xkb_mod_index_t shift;
+        xkb_mod_index_t caps;
+        xkb_mod_index_t ctrl;
+        xkb_mod_index_t alt;
+        xkb_mod_index_t super;
+        /* TODO: leds */
+     } mods;
+};
+
 struct _E_Input
 {
    Ecore_Wl_Input base;
@@ -21,6 +41,17 @@ struct _E_Input
    struct wl_list drag_resources;
 
    E_Input_Pointer *pointer;
+   E_Input_Keyboard *keyboard;
+   unsigned int modifier_state;
+
+   E_Input_Keyboard_Info kbd_info;
+
+   struct 
+     {
+        E_Surface *saved_focus;
+        struct wl_listener focus_listener;
+        struct xkb_state *state;
+     } kbd;
 
    struct 
      {
@@ -31,11 +62,6 @@ struct _E_Input
    char *name;
 };
 
-struct _E_Input_Keyboard
-{
-
-};
-
 struct _E_Input_Pointer_Grab_Interface
 {
    void (*focus)(E_Input_Pointer_Grab *grab);
@@ -65,6 +91,8 @@ struct _E_Input_Pointer
 
    E_Surface *focus;
    struct wl_resource *focus_resource;
+   struct wl_listener focus_listener;
+   unsigned int focus_serial;
 
    struct 
      {
@@ -77,15 +105,75 @@ struct _E_Input_Pointer
    E_Input_Pointer_Grab default_grab;
 };
 
+struct _E_Input_Keyboard_Grab_Interface
+{
+   void (*key)(E_Input_Keyboard_Grab *grab, unsigned int timestamp, unsigned int key, unsigned int state);
+   void (*modifiers)(E_Input_Keyboard_Grab *grab, unsigned int serial, unsigned int pressed, unsigned int latched, unsigned int locked, unsigned int group);
+};
+
+struct _E_Input_Keyboard_Grab
+{
+   E_Input_Keyboard *keyboard;
+   E_Input_Keyboard_Grab_Interface *interface;
+};
+
+struct _E_Input_Keyboard
+{
+   E_Input *seat;
+
+   struct wl_list resources;
+
+   E_Surface *focus;
+   struct wl_resource *focus_resource;
+   struct wl_listener focus_listener;
+   unsigned int focus_serial;
+
+   struct 
+     {
+        struct wl_signal focus;
+     } signals;
+
+   E_Input_Keyboard_Grab *grab;
+   E_Input_Keyboard_Grab default_grab;
+
+   unsigned int grab_key;
+   unsigned int grab_serial;
+   unsigned int grab_time;
+
+   struct wl_array keys;
+
+   struct 
+     {
+        unsigned int pressed;
+        unsigned int latched;
+        unsigned int locked;
+        unsigned int group;
+     } modifiers;
+
+   /* TODO: input method */
+};
+
 EAPI Eina_Bool e_input_init(E_Compositor *comp, E_Input *seat, const char *name);
 EAPI Eina_Bool e_input_shutdown(E_Input *seat);
 EAPI Eina_Bool e_input_pointer_init(E_Input *seat);
-EAPI Eina_Bool e_input_keyboard_init(E_Input *seat);
+EAPI Eina_Bool e_input_keyboard_init(E_Input *seat, struct xkb_keymap *keymap);
 EAPI Eina_Bool e_input_touch_init(E_Input *seat);
 
 EAPI void e_input_pointer_focus_set(E_Input_Pointer *pointer, E_Surface *surface, Evas_Coord x, Evas_Coord y);
 EAPI void e_input_pointer_grab_start(E_Input_Pointer *pointer);
 EAPI void e_input_pointer_grab_end(E_Input_Pointer *pointer);
 
+EAPI Eina_Bool e_input_keyboard_info_keymap_add(E_Input_Keyboard_Info *kbd_info);
+
+EAPI void e_input_keyboard_focus_set(E_Input_Keyboard *keyboard, E_Surface *surface);
+EAPI void e_input_keyboard_grab_start(E_Input_Keyboard *keyboard);
+EAPI void e_input_keyboard_grab_end(E_Input_Keyboard *keyboard);
+EAPI E_Input_Keyboard *e_input_keyboard_add(E_Input *seat);
+EAPI void e_input_keyboard_del(E_Input_Keyboard *keyboard);
+
+EAPI void e_input_repick(E_Input *seat);
+
+EAPI void e_input_keyboard_focus_destroy(struct wl_listener *listener, void *data);
+
 # endif
 #endif
index 382de9bb3458bb5bb8ad09aab7864e45981b1625..4decbd8a02b82b3e0ded12b6c99b333991801eed 100644 (file)
@@ -333,14 +333,14 @@ e_menu_idler_before(void)
    Eina_List *l;
    E_Menu *m;
 
-   /* EINA_LIST_FOREACH(_active_menus, l, m) */
-   /*   { */
-   /*      if ((!m->cur.visible) && (m->prev.visible)) */
-   /*        { */
-   /*           m->prev.visible = m->cur.visible; */
-   /*           ecore_evas_hide(m->ee); */
-   /*        } */
-   /*   } */
+   EINA_LIST_FOREACH(_active_menus, l, m)
+     {
+        if ((!m->cur.visible) && (m->prev.visible))
+          {
+             m->prev.visible = m->cur.visible;
+             ecore_evas_hide(m->ee);
+          }
+     }
 
    EINA_LIST_FOREACH(_active_menus, l, m)
      {
@@ -369,6 +369,7 @@ e_menu_idler_before(void)
                   m->prev.h = m->cur.h;
                   ecore_evas_resize(m->ee, m->cur.w, m->cur.h);
                }
+             ecore_evas_show(m->ee);
           }
      }
 
@@ -1092,6 +1093,7 @@ _e_menu_activate_internal(E_Menu *m, E_Zone *zone)
                if (cb->create) cb->create(m, cat->data, cb->data);
           }
      }
+
    m->cur.visible = EINA_TRUE;
 }
 
index f3cada4646c7812c311d0ac831569d985c7f236a..f392626b3ba2ab4ff62e45f2f14bc41cfcaa05e2 100644 (file)
@@ -98,8 +98,7 @@ e_output_repaint(E_Output *output, unsigned int secs)
    pixman_region32_fini(&damage);
    output->repaint.needed = EINA_FALSE;
 
-   /* TODO: comp repick ? */
-
+   e_compositor_repick(comp);
    wl_event_loop_dispatch(comp->wl.input_loop, 0);
 
    /* send surface frame callback done */
index a62c00865bfb32965095f5a20ca03136f99482a7..fb6ac2b27f2cec3ab395b920be62213db2882f2e 100644 (file)
@@ -2,6 +2,7 @@
 
 typedef enum _E_Shell_Surface_Type E_Shell_Surface_Type;
 typedef struct _E_Shell_Surface E_Shell_Surface;
+typedef struct _E_Shell_Surface_Ping_Timer E_Shell_Surface_Ping_Timer;
 
 #else
 # ifndef E_SHELL_SURFACE_H
@@ -56,7 +57,13 @@ struct _E_Shell_Surface
 
    Eina_Bool active : 1;
 
-   void *ping_timer;
+   E_Shell_Surface_Ping_Timer *ping_timer;
+};
+
+struct _E_Shell_Surface_Ping_Timer
+{
+   struct wl_event_source *source;
+   unsigned int serial;
 };
 
 EAPI E_Shell_Surface *e_shell_surface_new(E_Surface *surface, unsigned int id);
index 2528953ff1ad5a0513486c432ffa75f43ad8f3f1..785b3b17ea2a93e3cbca0d3ff82e0c39c9c6c258 100644 (file)
@@ -26,15 +26,17 @@ static const struct wl_surface_interface _e_surface_interface =
 };
 
 EAPI E_Surface *
-e_surface_new(unsigned int id)
+e_surface_new(struct wl_client *client, unsigned int id)
 {
    E_Surface *es;
 
    /* try to allocate space for a new surface */
    if (!(es = E_NEW(E_Surface, 1))) return NULL;
 
+   es->wl.id = id;
+
    /* initialize the destroy signal */
-   wl_signal_init(&es->wl.resource.destroy_signal);
+   wl_signal_init(&es->signals.destroy);
 
    /* initialize the link */
    wl_list_init(&es->wl.link);
@@ -48,8 +50,6 @@ e_surface_new(unsigned int id)
    pixman_region32_init_rect(&es->input, INT32_MIN, INT32_MIN, 
                              UINT32_MAX, UINT32_MAX);
 
-   /* TODO: finish me */
-
    es->pending.buffer_destroy.notify = _e_surface_cb_buffer_destroy;
 
    pixman_region32_init(&es->pending.damage);
@@ -57,14 +57,9 @@ e_surface_new(unsigned int id)
    pixman_region32_init_rect(&es->pending.input, INT32_MIN, INT32_MIN, 
                              UINT32_MAX, UINT32_MAX);
 
-   /* setup the surface object */
-   es->wl.resource.client = NULL;
-
-   es->wl.resource.object.id = id;
-   es->wl.resource.object.interface = &wl_surface_interface;
-   es->wl.resource.object.implementation = 
-     (void (**)(void))&_e_surface_interface;
-   es->wl.resource.data = es;
+   es->wl.resource = 
+     wl_client_add_object(client, &wl_surface_interface, 
+                          &_e_surface_interface, id, es);
 
    return es;
 }
@@ -125,13 +120,65 @@ e_surface_damage_below(E_Surface *es)
 EAPI void 
 e_surface_destroy(E_Surface *es)
 {
+   E_Surface_Frame *cb, *cbnext;
+
    /* check for valid surface */
    if (!es) return;
 
-   /* emit the destroy signal */
-   wl_signal_emit(&es->wl.resource.destroy_signal, &es->wl.resource);
+   wl_signal_emit(&es->signals.destroy, &es->wl.resource);
+
+   /* if this surface is mapped, unmap it */
+   if (es->mapped) e_surface_unmap(es);
+
+   /* remove any pending frame callbacks */
+   wl_list_for_each_safe(cb, cbnext, &es->pending.frames, link)
+     wl_resource_destroy(&cb->resource);
 
-   wl_resource_destroy(&es->wl.resource);
+   pixman_region32_fini(&es->pending.damage);
+   pixman_region32_fini(&es->pending.opaque);
+   pixman_region32_fini(&es->pending.input);
+
+   /* destroy pending buffer */
+   if (es->pending.buffer)
+     wl_list_remove(&es->pending.buffer_destroy.link);
+
+   /* remove any buffer references */
+   e_buffer_reference(&es->buffer.reference, NULL);
+
+   if (_e_comp->renderer->surface_destroy)
+     _e_comp->renderer->surface_destroy(es);
+
+   /* free regions */
+   pixman_region32_fini(&es->bounding);
+   pixman_region32_fini(&es->damage);
+   pixman_region32_fini(&es->opaque);
+   pixman_region32_fini(&es->input);
+   pixman_region32_fini(&es->clip);
+
+   /* remove any active frame callbacks */
+   wl_list_for_each_safe(cb, cbnext, &es->frames, link)
+     wl_resource_destroy(&cb->resource);
+
+   /* EINA_LIST_FOREACH(_e_comp->inputs, l, seat) */
+   /*   { */
+   /*      kbd = seat->keyboard; */
+
+   /*      if (kbd->focus) printf("\tCurrently Focused: %p\n", kbd->focus); */
+
+   /*      if ((kbd->focus) && (kbd->focus == es)) */
+   /*        { */
+   /*           if (seat->kbd.saved_focus) */
+   /*             { */
+   /*                printf("\tSaved Focus: %p\n", seat->kbd.saved_focus); */
+   /*                wl_list_remove(&seat->kbd.focus_listener.link); */
+   /*                e_input_keyboard_focus_set(kbd, seat->kbd.saved_focus); */
+   /*                seat->kbd.saved_focus = NULL; */
+   /*             } */
+   /*        } */
+   /*   } */
+
+   /* free the surface structure */
+   E_FREE(es);
 }
 
 EAPI void 
@@ -220,6 +267,28 @@ e_surface_output_assign(E_Surface *es)
    es->output_mask = mask;
 }
 
+EAPI void 
+e_surface_activate(E_Surface *es, E_Input *seat)
+{
+   E_Compositor *comp;
+
+   if (!(comp = seat->compositor)) return;
+
+   printf("Surface Activate: %p\n", es);
+
+   if ((seat->keyboard) && (comp->focus))
+     e_input_keyboard_focus_set(seat->keyboard, es);
+   else if (seat->keyboard)
+     {
+        seat->kbd.saved_focus = es;
+        seat->kbd.focus_listener.notify = e_input_keyboard_focus_destroy;
+        wl_signal_add(&seat->kbd.saved_focus->signals.destroy, 
+                      &seat->kbd.focus_listener);
+     }
+
+   wl_signal_emit(&comp->signals.activate, es);
+}
+
 /* local functions */
 static void 
 _e_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
index befa85fce5ac7d25785d318bf6cb45ee34bb8d64..19234976c7f4959cf25a407c9ce7c2cc0a95740d 100644 (file)
@@ -11,10 +11,16 @@ struct _E_Surface
 {
    struct 
      {
-        struct wl_resource resource;
+        struct wl_resource *resource;
         struct wl_list link;
+        unsigned int id;
      } wl;
 
+   struct 
+     {
+        struct wl_signal destroy;
+     } signals;
+
    struct 
      {
         E_Buffer_Reference reference;
@@ -69,7 +75,7 @@ struct _E_Surface_Frame
    struct wl_list link;
 };
 
-EAPI E_Surface *e_surface_new(unsigned int id);
+EAPI E_Surface *e_surface_new(struct wl_client *client, unsigned int id);
 EAPI void e_surface_attach(E_Surface *es, struct wl_buffer *buffer);
 EAPI void e_surface_unmap(E_Surface *es);
 EAPI void e_surface_damage(E_Surface *es);
@@ -79,6 +85,7 @@ EAPI void e_surface_damage_calculate(E_Surface *es, pixman_region32_t *opaque);
 EAPI void e_surface_show(E_Surface *es);
 EAPI void e_surface_repaint_schedule(E_Surface *es);
 EAPI void e_surface_output_assign(E_Surface *es);
+EAPI void e_surface_activate(E_Surface *es, E_Input *seat);
 
 # endif
 #endif