diff options
author | Chris Michael <devilhorns@comcast.net> | 2013-06-18 21:08:07 +0100 |
---|---|---|
committer | Chris Michael <devilhorns@comcast.net> | 2013-06-18 21:08:07 +0100 |
commit | d6b51b7b4cd774b66effd4df055aae34a10991be (patch) | |
tree | 5c5455f6c94c29b81bdb4e18db9a443bc6158c80 | |
parent | 46fad2b716e792d9e0f1b90a6153a881947be84c (diff) | |
download | enlightenment-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.h | 1 | ||||
-rw-r--r-- | src/bin/e_wayland/e_comp.c | 108 | ||||
-rw-r--r-- | src/bin/e_wayland/e_comp.h | 8 | ||||
-rw-r--r-- | src/bin/e_wayland/e_input.c | 373 | ||||
-rw-r--r-- | src/bin/e_wayland/e_input.h | 100 | ||||
-rw-r--r-- | src/bin/e_wayland/e_menu.c | 18 | ||||
-rw-r--r-- | src/bin/e_wayland/e_output.c | 3 | ||||
-rw-r--r-- | src/bin/e_wayland/e_shell_surface.h | 9 | ||||
-rw-r--r-- | src/bin/e_wayland/e_surface.c | 99 | ||||
-rw-r--r-- | src/bin/e_wayland/e_surface.h | 11 |
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 |