#include "utils.h"
#include "context.h"
-#define XKB_KEY_NAME_LENGTH 4
+/* This limit is artificially enforced, we do not depend on it any where.
+ * The reason it's still here is that the rules file format does not
+ * support multiple groups very well, and the rules shipped with
+ * xkeyboard-config (see rules/evdev) depend on this limit extensively.
+ * So just lifting this limit would cause problems for people who will use
+ * more than 4 layouts.
+ * TODO: Fix the group index syntax in the rules format, preferably in a
+ * backwards compatible way.
+ * See e.g. https://bugs.freedesktop.org/show_bug.cgi?id=14372
+ * Note: A limit on the number of groups we *do* depend on is imposed by
+ * the size of the xkb_layout_mask_t type (32). This is more than enough
+ * though.
+ */
+#define XKB_NUM_GROUPS 4
/* These should all be dynamic. */
-#define XKB_NUM_GROUPS 4
#define XKB_NUM_INDICATORS 32
#define XKB_NUM_VIRTUAL_MODS 16
#define XKB_NUM_CORE_MODS 8
struct xkb_indicator_map {
xkb_atom_t name;
enum xkb_state_component which_groups;
- uint32_t groups;
+ xkb_layout_mask_t groups;
enum xkb_state_component which_mods;
struct xkb_mods mods;
enum xkb_action_controls ctrls;
};
struct xkb_key_alias {
- char real[XKB_KEY_NAME_LENGTH];
- char alias[XKB_KEY_NAME_LENGTH];
+ xkb_atom_t real;
+ xkb_atom_t alias;
};
struct xkb_controls {
EXPLICIT_REPEAT = (1 << 2),
};
+struct xkb_level {
+ union xkb_action action;
+ unsigned int num_syms;
+ union {
+ xkb_keysym_t sym; /* num_syms == 1 */
+ xkb_keysym_t *syms; /* num_syms > 1 */
+ } u;
+};
+
+struct xkb_group {
+ bool explicit_type;
+ /* Points to a type in keymap->types. */
+ const struct xkb_key_type *type;
+ /* Use XkbKeyGroupWidth for the number of levels. */
+ struct xkb_level *levels;
+};
+
struct xkb_key {
xkb_keycode_t keycode;
- char name[XKB_KEY_NAME_LENGTH];
+ xkb_atom_t name;
enum xkb_explicit_components explicit;
- xkb_layout_mask_t explicit_groups;
unsigned char modmap;
xkb_mod_mask_t vmodmap;
bool repeats;
- union xkb_action *actions;
-
- unsigned kt_index[XKB_NUM_GROUPS];
-
- xkb_layout_index_t num_groups;
- /* How many levels the largest group has. */
- xkb_level_index_t width;
-
enum xkb_range_exceed_type out_of_range_group_action;
xkb_layout_index_t out_of_range_group_number;
- /* per level/group index into 'syms' */
- int *sym_index;
- /* per level/group */
- unsigned int *num_syms;
- xkb_keysym_t *syms;
+ xkb_layout_index_t num_groups;
+ struct xkb_group *groups;
};
+typedef darray(xkb_atom_t) darray_xkb_atom_t;
+
/* Common keyboard description structure */
struct xkb_keymap {
struct xkb_context *ctx;
int refcnt;
enum xkb_keymap_compile_flags flags;
+ enum xkb_keymap_format format;
- unsigned int enabled_ctrls;
+ enum xkb_action_controls enabled_ctrls;
xkb_keycode_t min_key_code;
xkb_keycode_t max_key_code;
/* Number of groups in the key with the most groups. */
xkb_layout_index_t num_groups;
- xkb_atom_t group_names[XKB_NUM_GROUPS];
+ darray_xkb_atom_t group_names;
struct xkb_indicator_map indicators[XKB_NUM_INDICATORS];
return &darray_item(keymap->keys, kc);
}
-static inline xkb_keycode_t
-XkbKeyGetKeycode(struct xkb_keymap *keymap, const struct xkb_key *key)
-{
- /* Hack to avoid having to keep the keycode inside the xkb_key. */
- return (xkb_keycode_t)(key - keymap->keys.item);
-}
-
#define xkb_foreach_key(iter, keymap) \
darray_foreach(iter, keymap->keys)
-static inline struct xkb_key_type *
-XkbKeyType(struct xkb_keymap *keymap, const struct xkb_key *key,
- xkb_layout_index_t layout)
-{
- return &keymap->types[key->kt_index[layout]];
-}
-
static inline xkb_level_index_t
-XkbKeyGroupWidth(struct xkb_keymap *keymap, const struct xkb_key *key,
- xkb_layout_index_t layout)
-{
- return XkbKeyType(keymap, key, layout)->num_levels;
-}
-
-static inline unsigned int
-XkbKeyNumSyms(const struct xkb_key *key, xkb_layout_index_t layout,
- xkb_level_index_t level)
-{
- return key->num_syms[layout * key->width + level];
-}
-
-static inline const xkb_keysym_t *
-XkbKeySymEntry(const struct xkb_key *key, xkb_layout_index_t layout,
- xkb_level_index_t level)
-{
- return &key->syms[key->sym_index[layout * key->width + level]];
-}
-
-static inline const union xkb_action *
-XkbKeyActionEntry(const struct xkb_key *key, xkb_layout_index_t layout,
- xkb_level_index_t level)
+XkbKeyGroupWidth(const struct xkb_key *key, xkb_layout_index_t layout)
{
- return &key->actions[key->width * layout + level];
+ return key->groups[layout].type->num_levels;
}
struct xkb_keymap *
-xkb_keymap_new(struct xkb_context *ctx);
+xkb_keymap_new(struct xkb_context *ctx,
+ enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags);
#endif