Add wayland compositor data & input files to build order

Signed-off-by: Chris Michael <cp.michael@samsung.com>
devs/devilhorns/xwayland
Chris Michael 9 years ago
parent 6fded4853d
commit adf559a850
  1. 4
      src/bin/Makefile.mk
  2. 116
      src/bin/e_comp_wl_data.c
  3. 10
      src/bin/e_comp_wl_data.h
  4. 480
      src/bin/e_comp_wl_input.c
  5. 20
      src/bin/e_comp_wl_input.h

@ -205,6 +205,8 @@ src/bin/e_zone.h
if HAVE_WAYLAND_CLIENTS
ENLIGHTENMENTHEADERS += \
src/bin/e_uuid_store.h \
src/bin/e_comp_wl_data.h \
src/bin/e_comp_wl_input.h \
src/bin/e_comp_wl.h
endif
@ -378,6 +380,8 @@ endif
if HAVE_WAYLAND_CLIENTS
enlightenment_src += \
src/bin/e_uuid_store.c \
src/bin/e_comp_wl_data.c \
src/bin/e_comp_wl_input.c \
src/bin/e_comp_wl.c
endif

@ -0,0 +1,116 @@
#include "e.h"
#include "e_comp_wl.h"
#include "e_comp_wl_data.h"
static void
_e_comp_wl_data_device_cb_drag_start(struct wl_client *client, struct wl_resource *resource, struct wl_resource *source_resource, struct wl_resource *origin_resource, struct wl_resource *icon_resource, uint32_t serial)
{
}
static void
_e_comp_wl_data_device_cb_selection_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *source_resource, uint32_t serial)
{
}
static const struct wl_data_device_interface _e_data_device_interface =
{
_e_comp_wl_data_device_cb_drag_start,
_e_comp_wl_data_device_cb_selection_set,
};
static void
_e_comp_wl_data_manager_cb_source_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
{
/* NB: New resource */
}
static void
_e_comp_wl_data_manager_cb_device_get(struct wl_client *client EINA_UNUSED, struct wl_resource *manager_resource, uint32_t id, struct wl_resource *seat_resource)
{
E_Comp_Data *cdata;
struct wl_resource *res;
DBG("Comp_Wl_Data: Get Data Device");
/* try to get the compositor data */
if (!(cdata = wl_resource_get_user_data(seat_resource))) return;
/* try to create the data device resource */
res = wl_resource_create(client, &wl_data_device_interface, 1, id);
if (!res)
{
ERR("Could not create data device resource: %m");
wl_resource_post_no_memory(manager_resource);
return;
}
wl_resource_set_implementation(res, &_e_data_device_interface, cdata, NULL);
}
static const struct wl_data_device_manager_interface _e_manager_interface =
{
_e_comp_wl_data_manager_cb_source_create,
_e_comp_wl_data_manager_cb_device_get
};
/* static void */
/* _e_comp_wl_data_cb_unbind_manager(struct wl_resource *resource) */
/* { */
/* E_Comp_Data *cdata; */
/* DBG("Comp_Wl_Data: Unbind Manager"); */
/* if (!(cdata = wl_resource_get_user_data(resource))) return; */
/* cdata->mgr.resource = NULL; */
/* } */
static void
_e_comp_wl_data_cb_bind_manager(struct wl_client *client, void *data, uint32_t version EINA_UNUSED, uint32_t id)
{
E_Comp_Data *cdata;
struct wl_resource *res;
if (!(cdata = data)) return;
DBG("Comp_Wl_Data: Bind Manager");
/* try to create data manager resource */
res = wl_resource_create(client, &wl_data_device_manager_interface, 1, id);
if (!res)
{
ERR("Could not create data device manager: %m");
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(res, &_e_manager_interface, cdata, NULL);
}
EINTERN Eina_Bool
e_comp_wl_data_manager_init(E_Comp_Data *cdata)
{
/* check for valid compositor data */
if (!cdata) return EINA_FALSE;
/* try to create global data manager */
cdata->mgr.global =
wl_global_create(cdata->wl.disp, &wl_data_device_manager_interface, 1,
cdata, _e_comp_wl_data_cb_bind_manager);
if (!cdata->mgr.global)
{
ERR("Could not create global for data device manager: %m");
return EINA_FALSE;
}
return EINA_TRUE;
}
EINTERN void
e_comp_wl_data_manager_shutdown(E_Comp_Data *cdata)
{
/* destroy the global manager resource */
if (cdata->mgr.global) wl_global_destroy(cdata->mgr.global);
}

@ -0,0 +1,10 @@
#ifdef E_TYPEDEFS
#else
# ifndef E_COMP_WL_DATA_H
# define E_COMP_WL_DATA_H
EINTERN Eina_Bool e_comp_wl_data_manager_init(E_Comp_Data *cdata);
EINTERN void e_comp_wl_data_manager_shutdown(E_Comp_Data *cdata);
# endif
#endif

@ -0,0 +1,480 @@
#include "e.h"
#include "e_comp_wl.h"
#include "e_comp_wl_input.h"
#include <sys/mman.h>
static void
_e_comp_wl_input_update_seat_caps(E_Comp_Data *cdata)
{
Eina_List *l;
struct wl_resource *res;
enum wl_seat_capability caps = 0;
if (!cdata) return;
if (cdata->ptr.enabled)
caps |= WL_SEAT_CAPABILITY_POINTER;
if (cdata->kbd.enabled)
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
if (cdata->touch.enabled)
caps |= WL_SEAT_CAPABILITY_TOUCH;
EINA_LIST_FOREACH(cdata->seat.resources, l, res)
wl_seat_send_capabilities(res, caps);
}
static void
_e_comp_wl_input_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
{
wl_resource_destroy(resource);
}
static void
_e_comp_wl_input_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource, uint32_t serial, struct wl_resource *surface_resource, int32_t x, int32_t y)
{
E_Comp_Data *cdata;
/* get compositor data */
if (!(cdata = wl_resource_get_user_data(resource))) return;
}
static const struct wl_pointer_interface _e_pointer_interface =
{
_e_comp_wl_input_pointer_cb_cursor_set,
_e_comp_wl_input_cb_resource_destroy
};
static const struct wl_keyboard_interface _e_keyboard_interface =
{
_e_comp_wl_input_cb_resource_destroy
};
static void
_e_comp_wl_input_cb_pointer_unbind(struct wl_resource *resource)
{
E_Comp_Data *cdata;
/* get compositor data */
if (!(cdata = wl_resource_get_user_data(resource))) return;
cdata->ptr.resources = eina_list_remove(cdata->ptr.resources, resource);
}
static void
_e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
{
E_Comp_Data *cdata;
struct wl_resource *res;
/* get compositor data */
if (!(cdata = wl_resource_get_user_data(resource))) return;
/* try to create pointer resource */
res = wl_resource_create(client, &wl_pointer_interface,
wl_resource_get_version(resource), id);
if (!res)
{
ERR("Could not create pointer on seat %s: %m", cdata->seat.name);
wl_client_post_no_memory(client);
return;
}
cdata->ptr.resources = eina_list_append(cdata->ptr.resources, res);
wl_resource_set_implementation(res, &_e_pointer_interface, cdata,
_e_comp_wl_input_cb_pointer_unbind);
}
static void
_e_comp_wl_input_cb_keyboard_unbind(struct wl_resource *resource)
{
E_Comp_Data *cdata;
/* get compositor data */
if (!(cdata = wl_resource_get_user_data(resource))) return;
cdata->kbd.resources = eina_list_remove(cdata->kbd.resources, resource);
}
static void
_e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, uint32_t id)
{
E_Comp_Data *cdata;
struct wl_resource *res;
/* uint32_t serial; */
/* get compositor data */
if (!(cdata = wl_resource_get_user_data(resource))) return;
/* try to create keyboard resource */
res = wl_resource_create(client, &wl_keyboard_interface,
wl_resource_get_version(resource), id);
if (!res)
{
ERR("Could not create keyboard on seat %s: %m", cdata->seat.name);
wl_client_post_no_memory(client);
return;
}
cdata->kbd.resources = eina_list_append(cdata->kbd.resources, res);
wl_resource_set_implementation(res, &_e_keyboard_interface, cdata,
_e_comp_wl_input_cb_keyboard_unbind);
/* send current keymap */
wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
cdata->xkb.fd, cdata->xkb.size);
/* FIXME: Should only need todo this if This client is focused */
/* send modifiers */
/* serial = wl_display_get_serial(cdata->wl.disp); */
/* wl_keyboard_send_modifiers(res, serial, cdata->kbd.mods_depressed, */
/* cdata->kbd.mods_latched, cdata->kbd.mods_locked, */
/* cdata->kbd.mod_group); */
}
static void
_e_comp_wl_input_cb_touch_get(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t id EINA_UNUSED)
{
E_Comp_Data *cdata;
/* DBG("Input Touch Get"); */
/* NB: Needs new resource !! */
/* get compositor data */
if (!(cdata = wl_resource_get_user_data(resource))) return;
}
static const struct wl_seat_interface _e_seat_interface =
{
_e_comp_wl_input_cb_pointer_get,
_e_comp_wl_input_cb_keyboard_get,
_e_comp_wl_input_cb_touch_get,
};
static void
_e_comp_wl_input_cb_unbind_seat(struct wl_resource *resource)
{
E_Comp_Data *cdata;
if (!(cdata = wl_resource_get_user_data(resource))) return;
cdata->seat.resources = eina_list_remove(cdata->seat.resources, resource);
}
static void
_e_comp_wl_input_cb_bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
{
E_Comp_Data *cdata;
struct wl_resource *res;
if (!(cdata = data)) return;
/* try to create the seat resource */
res = wl_resource_create(client, &wl_seat_interface, MIN(version, 3), id);
if (!res)
{
ERR("Could not create seat resource: %m");
return;
}
/* store version of seat interface for reuse in updating capabilities */
cdata->seat.version = version;
cdata->seat.resources = eina_list_append(cdata->seat.resources, res);
wl_resource_set_implementation(res, &_e_seat_interface, cdata,
_e_comp_wl_input_cb_unbind_seat);
_e_comp_wl_input_update_seat_caps(cdata);
if (cdata->seat.version >= 2) wl_seat_send_name(res, cdata->seat.name);
}
static int
_e_comp_wl_input_keymap_fd_get(off_t size)
{
int fd = 0, blen = 0, len = 0;
const char *path;
char tmp[PATH_MAX];
long flags;
blen = sizeof(tmp) - 1;
if (!(path = getenv("XDG_RUNTIME_DIR")))
return -1;
len = strlen(path);
if (len < blen)
{
strcpy(tmp, path);
strcat(tmp, "/e-wl-keymap-XXXXXX");
}
else
return -1;
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_comp_wl_input_keymap_update(E_Comp_Data *cdata, struct xkb_keymap *keymap)
{
char *tmp;
xkb_mod_mask_t latched, locked;
struct wl_resource *res;
Eina_List *l;
uint32_t serial;
if (!cdata) return;
/* unreference any existing keymap */
if (cdata->xkb.keymap) xkb_map_unref(cdata->xkb.keymap);
/* unmap any existing keyboard area */
if (cdata->xkb.area) munmap(cdata->xkb.area, cdata->xkb.size);
if (cdata->xkb.fd >= 0) close(cdata->xkb.fd);
/* unreference any existing keyboard state */
if (cdata->xkb.state) xkb_state_unref(cdata->xkb.state);
/* create a new xkb state */
cdata->xkb.state = xkb_state_new(keymap);
latched =
xkb_state_serialize_mods(cdata->xkb.state, XKB_STATE_MODS_LATCHED);
locked =
xkb_state_serialize_mods(cdata->xkb.state, XKB_STATE_MODS_LOCKED);
xkb_state_update_mask(cdata->xkb.state, 0, latched, locked, 0, 0, 0);
/* increment keymap reference */
cdata->xkb.keymap = xkb_map_ref(keymap);
/* fetch updated modifiers */
cdata->kbd.mod_shift = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
cdata->kbd.mod_caps = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
cdata->kbd.mod_ctrl = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
cdata->kbd.mod_alt = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT);
cdata->kbd.mod_super = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
if (!(tmp = xkb_map_get_as_string(keymap)))
{
ERR("Could not get keymap string");
return;
}
cdata->xkb.size = strlen(tmp) + 1;
cdata->xkb.fd = _e_comp_wl_input_keymap_fd_get(cdata->xkb.size);
if (cdata->xkb.fd < 0)
{
ERR("Could not create keymap file");
return;
}
cdata->xkb.area =
mmap(NULL, cdata->xkb.size, (PROT_READ | PROT_WRITE),
MAP_SHARED, cdata->xkb.fd, 0);
if (cdata->xkb.area == MAP_FAILED)
{
ERR("Failed to mmap keymap area: %m");
return;
}
strcpy(cdata->xkb.area, tmp);
free(tmp);
/* send updated keymap */
EINA_LIST_FOREACH(cdata->kbd.resources, l, res)
wl_keyboard_send_keymap(res, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
cdata->xkb.fd, cdata->xkb.size);
/* update modifiers */
e_comp_wl_input_keyboard_modifiers_update(cdata);
if ((!latched) && (!locked)) return;
/* send modifiers */
serial = wl_display_get_serial(cdata->wl.disp);
EINA_LIST_FOREACH(cdata->kbd.resources, l, res)
wl_keyboard_send_modifiers(res, serial, cdata->kbd.mod_depressed,
cdata->kbd.mod_latched, cdata->kbd.mod_locked,
cdata->kbd.mod_group);
}
EINTERN Eina_Bool
e_comp_wl_input_init(E_Comp_Data *cdata)
{
/* check for valid compositor data */
if (!cdata) return EINA_FALSE;
/* set default seat name */
if (!cdata->seat.name) cdata->seat.name = "default";
/* create the global resource for input seat */
cdata->seat.global =
wl_global_create(cdata->wl.disp, &wl_seat_interface, 3,
cdata, _e_comp_wl_input_cb_bind_seat);
if (!cdata->seat.global)
{
ERR("Could not create global for seat: %m");
return EINA_FALSE;
}
wl_array_init(&cdata->kbd.keys);
return EINA_TRUE;
}
EINTERN void
e_comp_wl_input_shutdown(E_Comp_Data *cdata)
{
Eina_List *l;
struct wl_resource *res;
/* check for valid compositor data */
if (!cdata) return;
/* destroy pointer resources */
EINA_LIST_FOREACH(cdata->ptr.resources, l, res)
wl_resource_destroy(res);
/* destroy keyboard resources */
EINA_LIST_FOREACH(cdata->kbd.resources, l, res)
wl_resource_destroy(res);
/* TODO: destroy touch resources */
/* TODO: destroy cdata->kbd.keys array */
/* destroy the global seat resource */
if (cdata->seat.global) wl_global_destroy(cdata->seat.global);
cdata->seat.global = NULL;
}
EINTERN Eina_Bool
e_comp_wl_input_pointer_check(struct wl_resource *res)
{
return wl_resource_instance_of(res, &wl_pointer_interface,
&_e_pointer_interface);
}
EINTERN Eina_Bool
e_comp_wl_input_keyboard_check(struct wl_resource *res)
{
return wl_resource_instance_of(res, &wl_keyboard_interface,
&_e_keyboard_interface);
}
EINTERN void
e_comp_wl_input_keyboard_modifiers_update(E_Comp_Data *cdata)
{
xkb_mod_mask_t depressed, latched, locked;
xkb_layout_index_t group;
depressed =
xkb_state_serialize_mods(cdata->xkb.state, XKB_STATE_DEPRESSED);
latched =
xkb_state_serialize_mods(cdata->xkb.state, XKB_STATE_MODS_LATCHED);
locked =
xkb_state_serialize_mods(cdata->xkb.state, XKB_STATE_MODS_LOCKED);
group =
xkb_state_serialize_group(cdata->xkb.state, XKB_STATE_EFFECTIVE);
if ((cdata->kbd.mod_depressed != depressed) ||
(cdata->kbd.mod_latched != latched) ||
(cdata->kbd.mod_locked != locked) ||
(cdata->kbd.mod_group != group))
{
uint32_t serial;
struct wl_resource *res;
Eina_List *l;
cdata->kbd.mod_depressed = depressed;
cdata->kbd.mod_latched = latched;
cdata->kbd.mod_locked = locked;
cdata->kbd.mod_group = group;
serial = wl_display_get_serial(cdata->wl.disp);
EINA_LIST_FOREACH(cdata->kbd.resources, l, res)
wl_keyboard_send_modifiers(res, serial,
depressed, latched, locked, group);
}
}
EINTERN void
e_comp_wl_input_keyboard_state_update(E_Comp_Data *cdata, uint32_t keycode, Eina_Bool pressed)
{
enum xkb_key_direction dir;
if (!cdata->xkb.state) return;
if (pressed) dir = XKB_KEY_DOWN;
else dir = XKB_KEY_UP;
xkb_state_update_key(cdata->xkb.state, keycode + 8, dir);
e_comp_wl_input_keyboard_modifiers_update(cdata);
}
EAPI void
e_comp_wl_input_pointer_enabled_set(E_Comp_Data *cdata, Eina_Bool enabled)
{
/* check for valid compositor data */
if (!cdata) return;
cdata->ptr.enabled = enabled;
_e_comp_wl_input_update_seat_caps(cdata);
}
EAPI void
e_comp_wl_input_keyboard_enabled_set(E_Comp_Data *cdata, Eina_Bool enabled)
{
/* check for valid compositor data */
if (!cdata) return;
cdata->kbd.enabled = enabled;
_e_comp_wl_input_update_seat_caps(cdata);
}
EAPI void
e_comp_wl_input_keymap_set(E_Comp_Data *cdata, const char *rules, const char *model, const char *layout)
{
struct xkb_keymap *keymap;
struct xkb_rule_names names;
if (!cdata) return;
/* DBG("COMP_WL: Keymap Set: %s %s %s", rules, model, layout); */
/* assemble xkb_rule_names so we can fetch keymap */
memset(&names, 0, sizeof(names));
if (rules) names.rules = strdup(rules);
if (model) names.model = strdup(model);
if (layout) names.layout = strdup(layout);
/* unreference any existing context */
if (cdata->xkb.context) xkb_context_unref(cdata->xkb.context);
/* create a new xkb context */
cdata->xkb.context = xkb_context_new(0);
/* fetch new keymap based on names */
keymap = xkb_map_new_from_names(cdata->xkb.context, &names, 0);
/* update compositor keymap */
_e_comp_wl_input_keymap_update(cdata, keymap);
/* cleanup */
free((char *)names.rules);
free((char *)names.model);
free((char *)names.layout);
}

@ -0,0 +1,20 @@
#ifdef E_TYPEDEFS
#else
# ifndef E_COMP_WL_INPUT_H
# define E_COMP_WL_INPUT_H
EINTERN Eina_Bool e_comp_wl_input_init(E_Comp_Data *cdata);
EINTERN void e_comp_wl_input_shutdown(E_Comp_Data *cdata);
EINTERN Eina_Bool e_comp_wl_input_pointer_check(struct wl_resource *res);
EINTERN Eina_Bool e_comp_wl_input_keyboard_check(struct wl_resource *res);
EINTERN void e_comp_wl_input_keyboard_modifiers_update(E_Comp_Data *cdata);
EINTERN void e_comp_wl_input_keyboard_state_update(E_Comp_Data *cdata, uint32_t keycode, Eina_Bool pressed);
EAPI void e_comp_wl_input_pointer_enabled_set(E_Comp_Data *cdata, Eina_Bool enabled);
EAPI void e_comp_wl_input_keyboard_enabled_set(E_Comp_Data *cdata, Eina_Bool enabled);
EAPI void e_comp_wl_input_keymap_set(E_Comp_Data *cdata, const char *rules, const char *model, const char *layout);
# endif
#endif
Loading…
Cancel
Save