This allows backends to generate their own keymaps and pass them in for
use rather than always forcing a single global keymap, which is
particularly useful for nested compositors.

Signed-off-by: Daniel Stone <[email protected]>
---
 src/compositor-wayland.c |    2 +-
 src/compositor-x11.c     |    2 +-
 src/compositor.c         |   92 ++++++++++++++++++++++++++--------------------
 src/compositor.h         |    2 +-
 src/evdev.c              |    2 +-
 5 files changed, 56 insertions(+), 44 deletions(-)

diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
index c6d9890..60fb9d9 100644
--- a/src/compositor-wayland.c
+++ b/src/compositor-wayland.c
@@ -650,7 +650,7 @@ input_handle_capabilities(void *data, struct wl_seat *seat,
                wl_keyboard_set_user_data(input->keyboard, input);
                wl_keyboard_add_listener(input->keyboard, &keyboard_listener,
                                         input);
-               weston_seat_init_keyboard((struct weston_seat *) seat);
+               weston_seat_init_keyboard((struct weston_seat *) seat, NULL);
        } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) {
                wl_keyboard_destroy(input->keyboard);
                input->keyboard = NULL;
diff --git a/src/compositor-x11.c b/src/compositor-x11.c
index 0599269..3a801a3 100644
--- a/src/compositor-x11.c
+++ b/src/compositor-x11.c
@@ -99,7 +99,7 @@ x11_input_create(struct x11_compositor *c)
        memset(input, 0, sizeof *input);
        weston_seat_init(&input->base, &c->base);
        weston_seat_init_pointer(&input->base);
-       weston_seat_init_keyboard(&input->base);
+       weston_seat_init_keyboard(&input->base, NULL);
 
        c->base.seat = &input->base;
 
diff --git a/src/compositor.c b/src/compositor.c
index 2b99200..e65ea5a 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2226,13 +2226,15 @@ device_handle_new_drag_icon(struct wl_listener 
*listener, void *data)
        weston_seat_update_drag_surface(&seat->seat, 0, 0);
 }
 
-static int weston_compositor_xkb_init(struct weston_compositor *ec,
-                                     struct xkb_rule_names *names)
+static void weston_compositor_xkb_init(struct weston_compositor *ec,
+                                      struct xkb_rule_names *names)
 {
-       ec->xkb_context = xkb_context_new(0);
        if (ec->xkb_context == NULL) {
-               fprintf(stderr, "failed to create XKB context\n");
-               return -1;
+               ec->xkb_context = xkb_context_new(0);
+               if (ec->xkb_context == NULL) {
+                       fprintf(stderr, "failed to create XKB context\n");
+                       exit(1);
+               }
        }
 
        if (names)
@@ -2243,8 +2245,6 @@ static int weston_compositor_xkb_init(struct 
weston_compositor *ec,
                ec->xkb_names.model = strdup("pc105");
        if (!ec->xkb_names.layout)
                ec->xkb_names.layout = strdup("us");
-
-       return 0;
 }
 
 static void xkb_info_destroy(struct weston_xkb_info *xkb_info)
@@ -2265,50 +2265,65 @@ static void weston_compositor_xkb_destroy(struct 
weston_compositor *ec)
        xkb_context_unref(ec->xkb_context);
 }
 
-static int
-weston_compositor_build_global_keymap(struct weston_compositor *ec)
+static void
+weston_xkb_info_get_mods(struct weston_xkb_info *xkb_info)
 {
-       if (!ec->xkb_context)
-               weston_compositor_xkb_init(ec, NULL);
+       xkb_info->ctrl_mod = xkb_map_mod_get_index(xkb_info->keymap,
+                                                  XKB_MOD_NAME_CTRL);
+       xkb_info->alt_mod = xkb_map_mod_get_index(xkb_info->keymap,
+                                                 XKB_MOD_NAME_ALT);
+       xkb_info->super_mod = xkb_map_mod_get_index(xkb_info->keymap,
+                                                   XKB_MOD_NAME_LOGO);
 
+       xkb_info->num_led = xkb_map_led_get_index(xkb_info->keymap,
+                                                 XKB_LED_NAME_NUM);
+       xkb_info->caps_led = xkb_map_led_get_index(xkb_info->keymap,
+                                                  XKB_LED_NAME_CAPS);
+       xkb_info->scroll_led = xkb_map_led_get_index(xkb_info->keymap,
+                                                    XKB_LED_NAME_SCROLL);
+}
+
+static void
+weston_compositor_build_global_keymap(struct weston_compositor *ec)
+{
        if (ec->xkb_info.keymap != NULL)
-               return 0;
+               return;
+
+       if (ec->xkb_names.rules == NULL)
+               weston_compositor_xkb_init(ec, NULL);
 
        ec->xkb_info.keymap = xkb_map_new_from_names(ec->xkb_context,
-                                                    &ec->xkb_names, 0);
+                                                    &ec->xkb_names,
+                                                    0);
        if (ec->xkb_info.keymap == NULL) {
-               fprintf(stderr, "failed to compile XKB keymap\n");
-               return -1;
+               fprintf(stderr, "failed to compile global XKB keymap\n");
+               fprintf(stderr,
+                       "  tried rules %s, model %s, layout %s, variant %s, "
+                       "options %s",
+                       ec->xkb_names.rules, ec->xkb_names.model,
+                       ec->xkb_names.layout, ec->xkb_names.variant,
+                       ec->xkb_names.options);
+               exit(1);
        }
 
-       ec->xkb_info.ctrl_mod = xkb_map_mod_get_index(ec->xkb_info.keymap,
-                                                     XKB_MOD_NAME_CTRL);
-       ec->xkb_info.alt_mod = xkb_map_mod_get_index(ec->xkb_info.keymap,
-                                                    XKB_MOD_NAME_ALT);
-       ec->xkb_info.super_mod = xkb_map_mod_get_index(ec->xkb_info.keymap,
-                                                      XKB_MOD_NAME_LOGO);
-
-       ec->xkb_info.num_led = xkb_map_led_get_index(ec->xkb_info.keymap,
-                                                    XKB_LED_NAME_NUM);
-       ec->xkb_info.caps_led = xkb_map_led_get_index(ec->xkb_info.keymap,
-                                                     XKB_LED_NAME_CAPS);
-       ec->xkb_info.scroll_led = xkb_map_led_get_index(ec->xkb_info.keymap,
-                                                       XKB_LED_NAME_SCROLL);
-
-       return 0;
+       weston_xkb_info_get_mods(&ec->xkb_info);
 }
 
 WL_EXPORT void
-weston_seat_init_keyboard(struct weston_seat *seat)
+weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
 {
        if (seat->has_keyboard)
                return;
 
-       if (weston_compositor_build_global_keymap(seat->compositor) == -1)
-               return;
-
-       seat->xkb_info = seat->compositor->xkb_info;
-       seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
+       if (keymap != NULL) {
+               seat->xkb_info.keymap = xkb_map_ref(keymap);
+               weston_xkb_info_get_mods(&seat->xkb_info);
+       }
+       else {
+               weston_compositor_build_global_keymap(seat->compositor);
+               seat->xkb_info = seat->compositor->xkb_info;
+               seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
+       }
 
        seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
        if (seat->xkb_state.state == NULL) {
@@ -3072,10 +3087,7 @@ int main(int argc, char *argv[])
        if (argv[1])
                exit(EXIT_FAILURE);
 
-       if (weston_compositor_xkb_init(ec, &xkb_names) == -1) {
-               fprintf(stderr, "failed to initialise keyboard support\n");
-               exit(EXIT_FAILURE);
-       }
+       weston_compositor_xkb_init(ec, &xkb_names);
 
        ec->option_idle_time = idle_time;
        ec->idle_time = idle_time;
diff --git a/src/compositor.h b/src/compositor.h
index 4a5c39c..2df753f 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -638,7 +638,7 @@ weston_seat_init(struct weston_seat *seat, struct 
weston_compositor *ec);
 void
 weston_seat_init_pointer(struct weston_seat *seat);
 void
-weston_seat_init_keyboard(struct weston_seat *seat);
+weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap);
 void
 weston_seat_init_touch(struct weston_seat *seat);
 
diff --git a/src/evdev.c b/src/evdev.c
index 23faaa6..8439eda 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -444,7 +444,7 @@ evdev_configure_device(struct evdev_input_device *device)
             (EVDEV_MOTION_ABS | EVDEV_MOTION_REL | EVDEV_BUTTON)))
                weston_seat_init_pointer(&device->master->base);
        if ((device->caps & EVDEV_KEYBOARD))
-               weston_seat_init_keyboard(&device->master->base);
+               weston_seat_init_keyboard(&device->master->base, NULL);
        if ((device->caps & EVDEV_TOUCH))
                weston_seat_init_touch(&device->master->base);
 
-- 
1.7.10

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to