summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Michael <devilhorns@comcast.net>2013-06-18 21:08:07 +0100
committerChris Michael <devilhorns@comcast.net>2013-06-18 21:08:07 +0100
commitd6b51b7b4cd774b66effd4df055aae34a10991be (patch)
tree5c5455f6c94c29b81bdb4e18db9a443bc6158c80
parent46fad2b716e792d9e0f1b90a6153a881947be84c (diff)
downloadenlightenment-d6b51b7b4cd774b66effd4df055aae34a10991be.tar.gz
Big giant push to get elm apps working properly
Signed-off-by: Chris Michael <devilhorns@comcast.net>
-rw-r--r--src/bin/e_wayland/e.h1
-rw-r--r--src/bin/e_wayland/e_comp.c108
-rw-r--r--src/bin/e_wayland/e_comp.h8
-rw-r--r--src/bin/e_wayland/e_input.c373
-rw-r--r--src/bin/e_wayland/e_input.h100
-rw-r--r--src/bin/e_wayland/e_menu.c18
-rw-r--r--src/bin/e_wayland/e_output.c3
-rw-r--r--src/bin/e_wayland/e_shell_surface.h9
-rw-r--r--src/bin/e_wayland/e_surface.c99
-rw-r--r--src/bin/e_wayland/e_surface.h11
10 files changed, 612 insertions, 118 deletions
diff --git a/src/bin/e_wayland/e.h b/src/bin/e_wayland/e.h
index 9287bc0aa1..191f0feca7 100644
--- a/src/bin/e_wayland/e.h
+++ b/src/bin/e_wayland/e.h
@@ -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>
diff --git a/src/bin/e_wayland/e_comp.c b/src/bin/e_wayland/e_comp.c
index c9071794ad..2095a3373b 100644
--- a/src/bin/e_wayland/e_comp.c
+++ b/src/bin/e_wayland/e_comp.c
@@ -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;
+}
diff --git a/src/bin/e_wayland/e_comp.h b/src/bin/e_wayland/e_comp.h
index a76273da00..7ad572de43 100644
--- a/src/bin/e_wayland/e_comp.h
+++ b/src/bin/e_wayland/e_comp.h
@@ -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
diff --git a/src/bin/e_wayland/e_input.c b/src/bin/e_wayland/e_input.c
index f9dfb2c68e..2cfb849652 100644
--- a/src/bin/e_wayland/e_input.c
+++ b/src/bin/e_wayland/e_input.c
@@ -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;
diff --git a/src/bin/e_wayland/e_input.h b/src/bin/e_wayland/e_input.h
index e45ba00a86..8173e48c96 100644
--- a/src/bin/e_wayland/e_input.h
+++ b/src/bin/e_wayland/e_input.h
@@ -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
diff --git a/src/bin/e_wayland/e_menu.c b/src/bin/e_wayland/e_menu.c
index 382de9bb34..4decbd8a02 100644
--- a/src/bin/e_wayland/e_menu.c
+++ b/src/bin/e_wayland/e_menu.c
@@ -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;
}
diff --git a/src/bin/e_wayland/e_output.c b/src/bin/e_wayland/e_output.c
index f3cada4646..f392626b3b 100644
--- a/src/bin/e_wayland/e_output.c
+++ b/src/bin/e_wayland/e_output.c
@@ -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 */
diff --git a/src/bin/e_wayland/e_shell_surface.h b/src/bin/e_wayland/e_shell_surface.h
index a62c00865b..fb6ac2b27f 100644
--- a/src/bin/e_wayland/e_shell_surface.h
+++ b/src/bin/e_wayland/e_shell_surface.h
@@ -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);
diff --git a/src/bin/e_wayland/e_surface.c b/src/bin/e_wayland/e_surface.c
index 2528953ff1..785b3b17ea 100644
--- a/src/bin/e_wayland/e_surface.c
+++ b/src/bin/e_wayland/e_surface.c
@@ -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)
diff --git a/src/bin/e_wayland/e_surface.h b/src/bin/e_wayland/e_surface.h
index befa85fce5..19234976c7 100644
--- a/src/bin/e_wayland/e_surface.h
+++ b/src/bin/e_wayland/e_surface.h
@@ -11,12 +11,18 @@ 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;
Eina_Bool keep : 1;
} buffer;
@@ -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