Port Wayland clients to new xkbcommon API
authorKristian Høgsberg <krh@bitplanet.net>
Tue, 8 May 2012 19:55:39 +0000 (15:55 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 8 May 2012 19:55:39 +0000 (15:55 -0400)
A little different from Daniels initial patch.  We look up the common
modifiers at xkb init time and convert the xkb serialized modifier mask
to our own modifier bitmask.

clients/terminal.c
clients/window.c
clients/window.h

index 4fbc1ff..c8818d0 100644 (file)
@@ -272,9 +272,9 @@ function_key_response(char escape, int num, uint32_t modifiers,
        int mod_num = 0;
        int len;
 
-       if (modifiers & XKB_COMMON_SHIFT_MASK) mod_num   |= 1;
-       if (modifiers & XKB_COMMON_MOD1_MASK) mod_num    |= 2;
-       if (modifiers & XKB_COMMON_CONTROL_MASK) mod_num |= 4;
+       if (modifiers & MOD_SHIFT_MASK) mod_num   |= 1;
+       if (modifiers & MOD_ALT_MASK) mod_num    |= 2;
+       if (modifiers & MOD_CONTROL_MASK) mod_num |= 4;
 
        if (mod_num != 0)
                len = snprintf(response, MAX_RESPONSE, "\e[%d;%d%c",
@@ -2078,8 +2078,8 @@ key_handler(struct window *window, struct input *input, uint32_t time,
        int len = 0;
 
        modifiers = input_get_modifiers(input);
-       if ((modifiers & XKB_COMMON_CONTROL_MASK) &&
-           (modifiers & XKB_COMMON_SHIFT_MASK) &&
+       if ((modifiers & MOD_CONTROL_MASK) &&
+           (modifiers & MOD_SHIFT_MASK) &&
            state && handle_bound_key(terminal, input, sym, time))
                return;
 
@@ -2173,7 +2173,7 @@ key_handler(struct window *window, struct input *input, uint32_t time,
                len = apply_key_map(terminal->key_mode, sym, modifiers, ch);
                if (len != 0) break;
                
-               if (modifiers & XKB_COMMON_CONTROL_MASK) {
+               if (modifiers & MOD_CONTROL_MASK) {
                        if (sym >= '3' && sym <= '7')
                                sym = (sym & 0x1f) + 8;
 
@@ -2184,10 +2184,10 @@ key_handler(struct window *window, struct input *input, uint32_t time,
                        else if (sym == '/') sym = 0x1F;
                        else if (sym == '8' || sym == '?') sym = 0x7F;
                } else if ((terminal->mode & MODE_ALT_SENDS_ESC) && 
-                          (modifiers & XKB_COMMON_MOD1_MASK))
+                          (modifiers & MOD_ALT_MASK))
                {
                        ch[len++] = 0x1b;
-               } else if (modifiers & XKB_COMMON_MOD1_MASK) {
+               } else if (modifiers & MOD_ALT_MASK) {
                        sym = sym | 0x80;
                }
 
index b47e969..12a98cb 100644 (file)
@@ -56,6 +56,7 @@
 #endif
 
 #include <xkbcommon/xkbcommon.h>
+#include <X11/keysym.h>
 #include <X11/X.h>
 #include <X11/Xcursor/Xcursor.h>
 
@@ -94,7 +95,17 @@ struct display {
        struct wl_list output_list;
        cairo_surface_t *active_frame, *inactive_frame, *shadow;
        int frame_radius;
-       struct xkb_desc *xkb;
+
+       struct {
+               struct xkb_rule_names names;
+               struct xkb_keymap *keymap;
+               struct xkb_state *state;
+               struct xkb_context *context;
+               xkb_mod_mask_t control_mask;
+               xkb_mod_mask_t alt_mask;
+               xkb_mod_mask_t shift_mask;
+       } xkb;
+
        struct cursor *cursors;
        struct shm_pool *cursor_shm_pool;
 
@@ -1559,30 +1570,42 @@ input_handle_key(void *data, struct wl_input_device *input_device,
        struct input *input = data;
        struct window *window = input->keyboard_focus;
        struct display *d = input->display;
-       uint32_t code, sym, level;
+       uint32_t code, num_syms;
+       const xkb_keysym_t *syms;
+       xkb_keysym_t sym;
+       xkb_mod_mask_t mask;
 
        input->display->serial = serial;
        code = key + 8;
        if (!window || window->keyboard_device != input)
                return;
 
-       level = 0;
-       if (input->modifiers & XKB_COMMON_SHIFT_MASK &&
-           XkbKeyGroupWidth(d->xkb, code, 0) > 1)
-               level = 1;
-
-       sym = XkbKeySymEntry(d->xkb, code, level, 0);
-
-       if (state)
-               input->modifiers |= d->xkb->map->modmap[code];
-       else
-               input->modifiers &= ~d->xkb->map->modmap[code];
+       num_syms = xkb_key_get_syms(d->xkb.state, code, &syms);
+       xkb_state_update_key(d->xkb.state, code,
+                            state ? XKB_KEY_DOWN : XKB_KEY_UP);
 
-       if (key == KEY_F5 && input->modifiers == Mod4Mask) {
+       mask = xkb_state_serialise_mods(d->xkb.state, 
+                                       XKB_STATE_DEPRESSED | 
+                                       XKB_STATE_LATCHED);
+       input->modifiers = 0;
+       if (mask & input->display->xkb.control_mask)
+               input->modifiers |= MOD_CONTROL_MASK;
+       if (mask & input->display->xkb.alt_mask)
+               input->modifiers |= MOD_ALT_MASK;
+       if (mask & input->display->xkb.shift_mask)
+               input->modifiers |= MOD_SHIFT_MASK;
+
+       if (num_syms == 1 && syms[0] == XK_F5 &&
+           input->modifiers == MOD_ALT_MASK) {
                if (state)
                        window_set_maximized(window,
                                             window->type != TYPE_MAXIMIZED);
        } else if (window->key_handler) {
+               if (num_syms == 1)
+                       sym = syms[0];
+               else
+                       sym = NoSymbol;
+
                (*window->key_handler)(window, input, time, key,
                                       sym, state, window->user_data);
        }
@@ -1669,17 +1692,10 @@ input_handle_keyboard_enter(void *data,
 {
        struct input *input = data;
        struct window *window;
-       struct display *d = input->display;
-       uint32_t *k, *end;
 
        input->display->serial = serial;
        input->keyboard_focus = wl_surface_get_user_data(surface);
 
-       end = keys->data + keys->size;
-       input->modifiers = 0;
-       for (k = keys->data; k < end; k++)
-               input->modifiers |= d->xkb->map->modmap[*k];
-
        window = input->keyboard_focus;
        window->keyboard_device = input;
        if (window->keyboard_focus_handler)
@@ -2842,25 +2858,46 @@ display_render_frame(struct display *d)
 static void
 init_xkb(struct display *d)
 {
-       struct xkb_rule_names names;
+       d->xkb.names.rules = "evdev";
+       d->xkb.names.model = "pc105";
+       d->xkb.names.layout = (char *) option_xkb_layout;
+       d->xkb.names.variant = (char *) option_xkb_variant;
+       d->xkb.names.options = (char *) option_xkb_options;
 
-       names.rules = "evdev";
-       names.model = "pc105";
-       names.layout = option_xkb_layout;
-       names.variant = option_xkb_variant;
-       names.options = option_xkb_options;
+       d->xkb.context = xkb_context_new();
+       if (!d->xkb.context) {
+               fprintf(stderr, "Failed to create XKB context\n");
+               exit(1);
+       }
 
-       d->xkb = xkb_compile_keymap_from_rules(&names);
-       if (!d->xkb) {
+       d->xkb.keymap =
+               xkb_map_new_from_names(d->xkb.context, &d->xkb.names);
+       if (!d->xkb.keymap) {
                fprintf(stderr, "Failed to compile keymap\n");
                exit(1);
        }
+
+       d->xkb.state = xkb_state_new(d->xkb.keymap);
+       if (!d->xkb.state) {
+               fprintf(stderr, "Failed to create XKB state\n");
+               exit(1);
+       }
+
+       d->xkb.control_mask =
+               1 << xkb_map_mod_get_index(d->xkb.keymap, "Control");
+       d->xkb.alt_mask =
+               1 << xkb_map_mod_get_index(d->xkb.keymap, "Mod1");
+       d->xkb.shift_mask =
+               1 << xkb_map_mod_get_index(d->xkb.keymap, "Shift");
+
 }
 
 static void
 fini_xkb(struct display *display)
 {
-       xkb_free_keymap(display->xkb);
+       xkb_state_unref(display->xkb.state);
+       xkb_map_unref(display->xkb.keymap);
+       xkb_context_unref(display->xkb.context);
 }
 
 #ifdef HAVE_CAIRO_EGL
index ac52935..8274e2a 100644 (file)
@@ -360,6 +360,10 @@ input_set_pointer_image(struct input *input, uint32_t time, int pointer);
 void
 input_get_position(struct input *input, int32_t *x, int32_t *y);
 
+#define MOD_SHIFT_MASK         0x01
+#define MOD_ALT_MASK           0x02
+#define MOD_CONTROL_MASK       0x04
+
 uint32_t
 input_get_modifiers(struct input *input);