Big giant push to get elm apps working properly

Signed-off-by: Chris Michael <devilhorns@comcast.net>
This commit is contained in:
Chris Michael 2013-06-18 21:08:07 +01:00
parent 46fad2b716
commit d6b51b7b4c
10 changed files with 611 additions and 117 deletions

View 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>

View 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;
}

View 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

View 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);
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; */
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;

View 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

View 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;
}

View 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 */

View 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);

View 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);
wl_resource_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);
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)

View 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