/************************************************************
- Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
-
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
-
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
- THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
+ * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of Silicon Graphics not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific prior written permission.
+ * Silicon Graphics makes no representation about the suitability
+ * of this software for any purpose. It is provided "as is"
+ * without any express or implied warranty.
+ *
+ * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+ * THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
********************************************************/
/*
* Author: Daniel Stone <daniel@fooishbar.org>
*/
-#include <config.h>
-
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-#include "xkb-priv.h"
+#include "keymap.h"
#include "text.h"
-#define VMOD_HIDE_VALUE 0
-#define VMOD_SHOW_VALUE 1
-#define VMOD_COMMENT_VALUE 2
+#define VMOD_HIDE_VALUE 0
+#define VMOD_SHOW_VALUE 1
+#define VMOD_COMMENT_VALUE 2
-#define BUF_CHUNK_SIZE 4096
+#define BUF_CHUNK_SIZE 4096
+
+struct buf {
+ char *buf;
+ size_t size;
+ size_t alloc;
+};
static bool
-do_realloc(char **buf, size_t *size, size_t offset, size_t at_least)
+do_realloc(struct buf *buf, size_t at_least)
{
char *new;
- *size += BUF_CHUNK_SIZE;
+ buf->alloc += BUF_CHUNK_SIZE;
if (at_least >= BUF_CHUNK_SIZE)
- *size += at_least;
+ buf->alloc += at_least;
- new = realloc(*buf, *size);
+ new = realloc(buf->buf, buf->alloc);
if (!new)
return false;
- *buf = new;
-
- memset(*buf + offset, 0, *size - offset);
+ buf->buf = new;
return true;
}
-/* This whole thing should be a function, but you can't call vsnprintf
- * multiple times. */
-#define check_write_buf(keymap, buf, size, offset, ...) \
-do { \
- size_t _printed; \
- bool _ret = true; \
- \
- /* Concatenate the strings, and check whether or not the output was \
- * truncated. */ \
- while ((_printed = snprintf(*buf + *offset, *size - *offset, \
- __VA_ARGS__)) >= \
- (*size - *offset)) {\
- /* If it was truncated, embiggen the string and roll from the top. */ \
- if (!do_realloc(buf, size, *offset, _printed)) { \
- fprintf(stderr, \
- "xkbcommon: failed to allocate %zu bytes for keymap\n", \
- *size); \
- free(*buf); \
- *buf = NULL; \
- _ret = false; \
- break; \
- } \
- } \
- if (_ret == true) \
- *offset += _printed; \
-} while (0)
-
-#define write_buf(keymap, buf, size, offset, ...) \
-do { \
- check_write_buf(keymap, buf, size, offset, __VA_ARGS__); \
- if (*buf == NULL) \
- return false; \
-} while (0)
-
-static bool
-write_vmods(struct xkb_keymap *keymap, char **buf, size_t *size, size_t *offset)
+ATTR_PRINTF(2, 3) static bool
+check_write_buf(struct buf *buf, const char *fmt, ...)
{
- int num_vmods = 0;
- int i;
-
- for (i = 0; i < XkbNumVirtualMods; i++) {
- if (!keymap->names->vmods[i])
- continue;
- if (num_vmods == 0)
- write_buf(keymap, buf, size, offset, "\t\tvirtual_modifiers ");
- else
- write_buf(keymap, buf, size, offset, ",");
- write_buf(keymap, buf, size, offset, "%s", keymap->names->vmods[i]);
- num_vmods++;
- }
-
- if (num_vmods > 0)
- write_buf(keymap, buf, size, offset, ";\n\n");
+ va_list args;
+ int printed;
+ size_t available;
- return true;
-}
+ available = buf->alloc - buf->size;
+ va_start(args, fmt);
+ printed = vsnprintf(buf->buf + buf->size, available, fmt, args);
+ va_end(args);
-#define GET_TEXT_BUF_SIZE 512
-
-#define append_get_text(...) do { \
- int _size = snprintf(ret, GET_TEXT_BUF_SIZE, __VA_ARGS__); \
- if (_size >= GET_TEXT_BUF_SIZE) \
- return NULL; \
-} while(0)
-
-/* FIXME: Merge with src/xkbcomp/expr.c::modIndexNames. */
-static const char *core_mod_names[] = {
- "Shift",
- "Lock",
- "Control",
- "Mod1",
- "Mod2",
- "Mod3",
- "Mod4",
- "Mod5",
-};
+ if (printed < 0)
+ goto err;
-static const char *
-get_mod_index_text(uint8_t real_mod)
-{
- return core_mod_names[real_mod];
-}
+ if (printed >= available)
+ if (!do_realloc(buf, printed))
+ goto err;
-static char *
-get_mod_mask_text(struct xkb_keymap *keymap, uint8_t real_mods, uint32_t vmods)
-{
- static char ret[GET_TEXT_BUF_SIZE], ret2[GET_TEXT_BUF_SIZE];
- int i;
-
- memset(ret, 0, GET_TEXT_BUF_SIZE);
+ /* The buffer has enough space now. */
- if (real_mods == 0 && vmods == 0) {
- strcpy(ret, "none");
- return ret;
- }
-
- /* This is so broken. If we have a real modmask of 0xff and a
- * vmodmask, we'll get, e.g., all+RightControl. But, it's what xkbfile
- * does, so ... */
- if (real_mods == 0xff) {
- strcpy(ret, "all");
- }
- else if (real_mods) {
- for (i = 0; i < XkbNumModifiers; i++) {
- if (!(real_mods & (1 << i)))
- continue;
- if (ret[0] != '\0') {
- strcpy(ret2, ret);
- append_get_text("%s+%s", ret2, core_mod_names[i]);
- }
- else {
- append_get_text("%s", core_mod_names[i]);
- }
- }
- }
+ available = buf->alloc - buf->size;
+ va_start(args, fmt);
+ printed = vsnprintf(buf->buf + buf->size, available, fmt, args);
+ va_end(args);
- if (vmods == 0)
- return ret;
+ if (printed >= available || printed < 0)
+ goto err;
- for (i = 0; i < XkbNumVirtualMods; i++) {
- if (!(vmods & (1 << i)))
- continue;
- if (ret[0] != '\0') {
- strcpy(ret2, ret);
- append_get_text("%s+%s", ret2, keymap->names->vmods[i]);
- }
- else {
- append_get_text("%s", keymap->names->vmods[i]);
- }
- }
+ buf->size += printed;
+ return true;
- return ret;
+err:
+ free(buf->buf);
+ buf->buf = NULL;
+ return false;
}
-static char *
-get_indicator_state_text(uint8_t which)
-{
- int i;
- static char ret[GET_TEXT_BUF_SIZE];
- /* FIXME: Merge with ... something ... in xkbcomp? */
- static const char *state_names[] = {
- "base",
- "latched",
- "locked",
- "effective",
- "compat"
- };
-
- memset(ret, 0, GET_TEXT_BUF_SIZE);
-
- which &= XkbIM_UseAnyMods;
-
- if (which == 0) {
- strcpy(ret, "0");
- return NULL;
- }
-
- for (i = 0; which != 0; i++) {
- if (!(which & (1 << i)))
- continue;
- which &= ~(1 << i);
-
- if (ret[0] != '\0')
- append_get_text("%s+%s", ret, state_names[i]);
- else
- append_get_text("%s", state_names[i]);
- }
-
- return ret;
-}
+#define write_buf(buf, ...) do { \
+ if (!check_write_buf(buf, __VA_ARGS__)) \
+ return false; \
+} while (0)
-static char *
-get_control_mask_text(uint32_t control_mask)
+static bool
+write_vmods(struct xkb_keymap *keymap, struct buf *buf)
{
- int i;
- static char ret[GET_TEXT_BUF_SIZE];
- /* FIXME: Merge with ... something ... in xkbcomp. */
- static const char *ctrl_names[] = {
- "repeatKeys",
- "slowKeys",
- "bounceKeys",
- "stickyKeys",
- "mouseKeys",
- "mouseKeysAccel",
- "accessXKeys",
- "accessXTimeout",
- "accessXFeedback",
- "audibleBell",
- "overlay1",
- "overlay2",
- "ignoreGroupLock"
- };
-
- memset(ret, 0, GET_TEXT_BUF_SIZE);
-
- control_mask &= XkbAllBooleanCtrlsMask;
-
- if (control_mask == 0) {
- strcpy(ret, "none");
- return ret;
- }
- else if (control_mask == XkbAllBooleanCtrlsMask) {
- strcpy(ret, "all");
- return ret;
- }
+ const struct xkb_mod *mod;
+ xkb_mod_index_t num_vmods = 0;
- for (i = 0; control_mask; i++) {
- if (!(control_mask & (1 << i)))
+ darray_foreach(mod, keymap->mods) {
+ if (mod->type != MOD_VIRT)
continue;
- control_mask &= ~(1 << i);
- if (ret[0] != '\0')
- append_get_text("%s+%s", ret, ctrl_names[i]);
+ if (num_vmods == 0)
+ write_buf(buf, "\t\tvirtual_modifiers ");
else
- append_get_text("%s", ctrl_names[i]);
+ write_buf(buf, ",");
+ write_buf(buf, "%s", xkb_atom_text(keymap->ctx, mod->name));
+ num_vmods++;
}
- return ret;
+ if (num_vmods > 0)
+ write_buf(buf, ";\n\n");
+
+ return true;
}
static bool
-write_keycodes(struct xkb_keymap *keymap, char **buf, size_t *size,
- size_t *offset)
+write_keycodes(struct xkb_keymap *keymap, struct buf *buf)
{
- xkb_keycode_t key;
+ struct xkb_key *key;
struct xkb_key_alias *alias;
- int i;
-
- write_buf(keymap, buf, size, offset, "\txkb_keycodes {\n");
- write_buf(keymap, buf, size, offset, "\t\tminimum = %d;\n",
- keymap->min_key_code);
- write_buf(keymap, buf, size, offset, "\t\tmaximum = %d;\n",
- keymap->max_key_code);
+ xkb_led_index_t i;
+ const struct xkb_indicator_map *im;
- for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
- const char *alternate = "";
+ if (keymap->keycodes_section_name)
+ write_buf(buf, "\txkb_keycodes \"%s\" {\n",
+ keymap->keycodes_section_name);
+ else
+ write_buf(buf, "\txkb_keycodes {\n");
- if (darray_item(keymap->names->keys, key).name[0] == '\0')
+ xkb_foreach_key(key, keymap) {
+ if (key->name == XKB_ATOM_NONE)
continue;
- if (XkbcFindKeycodeByName(keymap,
- darray_item(keymap->names->keys, key).name,
- true) != key)
- alternate = "alternate ";
- write_buf(keymap, buf, size, offset, "\t\t%s%6s = %d;\n", alternate,
- XkbcKeyNameText(darray_item(keymap->names->keys, key).name),
- key);
- }
- for (i = 0; i < XkbNumIndicators; i++) {
- if (!keymap->names->indicators[i])
- continue;
- write_buf(keymap, buf, size, offset, "\t\tindicator %d = \"%s\";\n",
- i + 1, keymap->names->indicators[i]);
+ write_buf(buf, "\t\t%-20s = %d;\n",
+ KeyNameText(keymap->ctx, key->name), key->keycode);
}
+ darray_enumerate(i, im, keymap->indicators)
+ if (im->name != XKB_ATOM_NONE)
+ write_buf(buf, "\t\tindicator %d = \"%s\";\n",
+ i + 1, xkb_atom_text(keymap->ctx, im->name));
+
- darray_foreach(alias, keymap->names->key_aliases)
- write_buf(keymap, buf, size, offset, "\t\talias %6s = %6s;\n",
- XkbcKeyNameText(alias->alias),
- XkbcKeyNameText(alias->real));
+ darray_foreach(alias, keymap->key_aliases)
+ write_buf(buf, "\t\talias %-14s = %s;\n",
+ KeyNameText(keymap->ctx, alias->alias),
+ KeyNameText(keymap->ctx, alias->real));
- write_buf(keymap, buf, size, offset, "\t};\n\n");
+ write_buf(buf, "\t};\n\n");
return true;
}
static bool
-write_types(struct xkb_keymap *keymap, char **buf, size_t *size,
- size_t *offset)
+write_types(struct xkb_keymap *keymap, struct buf *buf)
{
- int n;
+ unsigned int i, j;
+ xkb_level_index_t n;
struct xkb_key_type *type;
+ struct xkb_kt_map_entry *entry;
- write_buf(keymap, buf, size, offset, "\txkb_types {\n\n");
- write_vmods(keymap, buf, size, offset);
+ if (keymap->types_section_name)
+ write_buf(buf, "\txkb_types \"%s\" {\n\n",
+ keymap->types_section_name);
+ else
+ write_buf(buf, "\txkb_types {\n\n");
- darray_foreach(type, keymap->map->types) {
- write_buf(keymap, buf, size, offset, "\t\ttype \"%s\" {\n",
- type->name);
- write_buf(keymap, buf, size, offset, "\t\t\tmodifiers= %s;\n",
- get_mod_mask_text(keymap, type->mods.real_mods,
- type->mods.vmods));
+ write_vmods(keymap, buf);
- for (n = 0; n < darray_size(type->map); n++) {
- struct xkb_kt_map_entry *entry = &darray_item(type->map, n);
- char *str;
+ for (i = 0; i < keymap->num_types; i++) {
+ type = &keymap->types[i];
- str = get_mod_mask_text(keymap, entry->mods.real_mods,
- entry->mods.vmods);
- write_buf(keymap, buf, size, offset, "\t\t\tmap[%s]= Level%d;\n",
+ write_buf(buf, "\t\ttype \"%s\" {\n",
+ xkb_atom_text(keymap->ctx, type->name));
+ write_buf(buf, "\t\t\tmodifiers= %s;\n",
+ ModMaskText(keymap, type->mods.mods));
+
+ for (j = 0; j < type->num_entries; j++) {
+ const char *str;
+ entry = &type->map[j];
+
+ /*
+ * Printing level 1 entries is redundant, it's the default,
+ * unless there's preserve info.
+ */
+ if (entry->level == 0 && entry->preserve.mods == 0)
+ continue;
+
+ str = ModMaskText(keymap, entry->mods.mods);
+ write_buf(buf, "\t\t\tmap[%s]= Level%d;\n",
str, entry->level + 1);
- if (!type->preserve || (!type->preserve[n].real_mods &&
- !type->preserve[n].vmods))
+ if (entry->preserve.mods == 0)
continue;
- write_buf(keymap, buf, size, offset, "\t\t\tpreserve[%s]= ", str);
- write_buf(keymap, buf, size, offset, "%s;\n",
- get_mod_mask_text(keymap, type->preserve[n].real_mods,
- type->preserve[n].vmods));
- }
-
- if (type->level_names) {
- for (n = 0; n < type->num_levels; n++) {
- if (!type->level_names[n])
- continue;
- write_buf(keymap, buf, size, offset,
- "\t\t\tlevel_name[Level%d]= \"%s\";\n", n + 1,
- type->level_names[n]);
- }
- }
- write_buf(keymap, buf, size, offset, "\t\t};\n");
+
+ write_buf(buf, "\t\t\tpreserve[%s]= ", str);
+ write_buf(buf, "%s;\n",
+ ModMaskText(keymap, entry->preserve.mods));
+ }
+
+ if (type->level_names) {
+ for (n = 0; n < type->num_levels; n++) {
+ if (!type->level_names[n])
+ continue;
+ write_buf(buf, "\t\t\tlevel_name[Level%d]= \"%s\";\n", n + 1,
+ xkb_atom_text(keymap->ctx, type->level_names[n]));
+ }
+ }
+ write_buf(buf, "\t\t};\n");
}
- write_buf(keymap, buf, size, offset, "\t};\n\n");
+ write_buf(buf, "\t};\n\n");
return true;
}
static bool
-write_indicator_map(struct xkb_keymap *keymap, char **buf, size_t *size,
- size_t *offset, int num)
+write_indicator_map(struct xkb_keymap *keymap, struct buf *buf,
+ const struct xkb_indicator_map *led)
{
- struct xkb_indicator_map *led = &keymap->indicators->maps[num];
-
- write_buf(keymap, buf, size, offset, "\t\tindicator \"%s\" {\n",
- keymap->names->indicators[num]);
+ write_buf(buf, "\t\tindicator \"%s\" {\n",
+ xkb_atom_text(keymap->ctx, led->name));
if (led->which_groups) {
- if (led->which_groups != XkbIM_UseEffective) {
- write_buf(keymap, buf, size, offset, "\t\t\twhichGroupState= %s;\n",
- get_indicator_state_text(led->which_groups));
- }
- write_buf(keymap, buf, size, offset, "\t\t\tgroups= 0x%02x;\n",
+ if (led->which_groups != XKB_STATE_LAYOUT_EFFECTIVE) {
+ write_buf(buf, "\t\t\twhichGroupState= %s;\n",
+ IndicatorStateText(keymap->ctx, led->which_groups));
+ }
+ write_buf(buf, "\t\t\tgroups= 0x%02x;\n",
led->groups);
}
if (led->which_mods) {
- if (led->which_mods != XkbIM_UseEffective) {
- write_buf(keymap, buf, size, offset, "\t\t\twhichModState= %s;\n",
- get_indicator_state_text(led->which_mods));
- }
- write_buf(keymap, buf, size, offset, "\t\t\tmodifiers= %s;\n",
- get_mod_mask_text(keymap, led->mods.real_mods,
- led->mods.vmods));
+ if (led->which_mods != XKB_STATE_MODS_EFFECTIVE) {
+ write_buf(buf, "\t\t\twhichModState= %s;\n",
+ IndicatorStateText(keymap->ctx, led->which_mods));
+ }
+ write_buf(buf, "\t\t\tmodifiers= %s;\n",
+ ModMaskText(keymap, led->mods.mods));
}
if (led->ctrls) {
- write_buf(keymap, buf, size, offset, "\t\t\tcontrols= %s;\n",
- get_control_mask_text(led->ctrls));
+ write_buf(buf, "\t\t\tcontrols= %s;\n",
+ ControlMaskText(keymap->ctx, led->ctrls));
}
- write_buf(keymap, buf, size, offset, "\t\t};\n");
+ write_buf(buf, "\t\t};\n");
return true;
}
-static char *
-get_interp_match_text(uint8_t type)
-{
- static char ret[16];
-
- switch (type & XkbSI_OpMask) {
- case XkbSI_NoneOf:
- sprintf(ret, "NoneOf");
- break;
- case XkbSI_AnyOfOrNone:
- sprintf(ret, "AnyOfOrNone");
- break;
- case XkbSI_AnyOf:
- sprintf(ret, "AnyOf");
- break;
- case XkbSI_AllOf:
- sprintf(ret, "AllOf");
- break;
- case XkbSI_Exactly:
- sprintf(ret, "Exactly");
- break;
- default:
- sprintf(ret, "0x%x", type & XkbSI_OpMask);
- break;
- }
-
- return ret;
-}
-
static bool
-write_action(struct xkb_keymap *keymap, char **buf, size_t *size,
- size_t *offset, union xkb_action *action, const char *prefix,
- const char *suffix)
+write_action(struct xkb_keymap *keymap, struct buf *buf,
+ const union xkb_action *action,
+ const char *prefix, const char *suffix)
{
- const char *type = NULL;
+ const char *type;
const char *args = NULL;
if (!prefix)
if (!suffix)
suffix = "";
- switch (action->any.type) {
- case XkbSA_SetMods:
- if (!type)
- type = "SetMods";
- case XkbSA_LatchMods:
- if (!type)
- type = "LatchMods";
- case XkbSA_LockMods:
- if (!type)
- type = "LockMods";
- if (action->mods.flags & XkbSA_UseModMapMods)
+ type = ActionTypeText(action->type);
+
+ switch (action->type) {
+ case ACTION_TYPE_MOD_SET:
+ case ACTION_TYPE_MOD_LATCH:
+ case ACTION_TYPE_MOD_LOCK:
+ if (action->mods.flags & ACTION_MODS_LOOKUP_MODMAP)
args = "modMapMods";
else
- args = get_mod_mask_text(keymap, action->mods.real_mods,
- action->mods.vmods);
- write_buf(keymap, buf, size, offset, "%s%s(modifiers=%s%s%s)%s",
- prefix, type, args,
- (action->any.type != XkbSA_LockGroup &&
- action->mods.flags & XkbSA_ClearLocks) ? ",clearLocks" : "",
- (action->any.type != XkbSA_LockGroup &&
- action->mods.flags & XkbSA_LatchToLock) ? ",latchToLock" : "",
+ args = ModMaskText(keymap, action->mods.mods.mods);
+ write_buf(buf, "%s%s(modifiers=%s%s%s)%s", prefix, type, args,
+ (action->type != ACTION_TYPE_MOD_LOCK &&
+ (action->mods.flags & ACTION_LOCK_CLEAR)) ?
+ ",clearLocks" : "",
+ (action->type != ACTION_TYPE_MOD_LOCK &&
+ (action->mods.flags & ACTION_LATCH_TO_LOCK)) ?
+ ",latchToLock" : "",
suffix);
break;
- case XkbSA_SetGroup:
- if (!type)
- type = "SetGroup";
- case XkbSA_LatchGroup:
- if (!type)
- type = "LatchGroup";
- case XkbSA_LockGroup:
- if (!type)
- type = "LockGroup";
- write_buf(keymap, buf, size, offset, "%s%s(group=%s%d%s%s)%s",
- prefix, type,
- (!(action->group.flags & XkbSA_GroupAbsolute) &&
+
+ case ACTION_TYPE_GROUP_SET:
+ case ACTION_TYPE_GROUP_LATCH:
+ case ACTION_TYPE_GROUP_LOCK:
+ write_buf(buf, "%s%s(group=%s%d%s%s)%s", prefix, type,
+ (!(action->group.flags & ACTION_ABSOLUTE_SWITCH) &&
action->group.group > 0) ? "+" : "",
- (action->group.flags & XkbSA_GroupAbsolute) ?
- action->group.group + 1 : action->group.group,
- (action->any.type != XkbSA_LockGroup &&
- action->group.flags & XkbSA_ClearLocks) ? ",clearLocks" : "",
- (action->any.type != XkbSA_LockGroup &&
- action->group.flags & XkbSA_LatchToLock) ? ",latchToLock" : "",
+ (action->group.flags & ACTION_ABSOLUTE_SWITCH) ?
+ action->group.group + 1 : action->group.group,
+ (action->type != ACTION_TYPE_GROUP_LOCK &&
+ (action->group.flags & ACTION_LOCK_CLEAR)) ?
+ ",clearLocks" : "",
+ (action->type != ACTION_TYPE_GROUP_LOCK &&
+ (action->group.flags & ACTION_LATCH_TO_LOCK)) ?
+ ",latchToLock" : "",
suffix);
break;
- case XkbSA_Terminate:
- write_buf(keymap, buf, size, offset, "%sTerminate()%s", prefix, suffix);
+
+ case ACTION_TYPE_TERMINATE:
+ write_buf(buf, "%s%s()%s", prefix, type, suffix);
break;
- case XkbSA_MovePtr:
- write_buf(keymap, buf, size, offset, "%sMovePtr(x=%s%d,y=%s%d%s)%s",
- prefix,
- (!(action->ptr.flags & XkbSA_MoveAbsoluteX) &&
+
+ case ACTION_TYPE_PTR_MOVE:
+ write_buf(buf, "%s%s(x=%s%d,y=%s%d%s)%s", prefix, type,
+ (!(action->ptr.flags & ACTION_ABSOLUTE_X) &&
action->ptr.x >= 0) ? "+" : "",
action->ptr.x,
- (!(action->ptr.flags & XkbSA_MoveAbsoluteY) &&
+ (!(action->ptr.flags & ACTION_ABSOLUTE_Y) &&
action->ptr.y >= 0) ? "+" : "",
action->ptr.y,
- (action->ptr.flags & XkbSA_NoAcceleration) ? ",!accel" : "",
+ (action->ptr.flags & ACTION_NO_ACCEL) ? ",!accel" : "",
suffix);
break;
- case XkbSA_PtrBtn:
- if (!type)
- type = "PtrBtn";
- case XkbSA_LockPtrBtn:
- if (!type) {
- type = "LockPtrBtn";
- switch (action->btn.flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
- case XkbSA_LockNoUnlock:
- args = ",affect=lock";
- break;
- case XkbSA_LockNoLock:
- args = ",affect=unlock";
- break;
- case XkbSA_LockNoLock | XkbSA_LockNoUnlock:
- args = ",affect=neither";
- break;
- default:
- args = ",affect=both";
- break;
- }
- }
- else {
- args = NULL;
+
+ case ACTION_TYPE_PTR_LOCK:
+ switch (action->btn.flags &
+ (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) {
+ case ACTION_LOCK_NO_UNLOCK:
+ args = ",affect=lock";
+ break;
+
+ case ACTION_LOCK_NO_LOCK:
+ args = ",affect=unlock";
+ break;
+
+ case ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK:
+ args = ",affect=neither";
+ break;
+
+ default:
+ args = ",affect=both";
+ break;
}
- write_buf(keymap, buf, size, offset, "%s%s(button=", prefix, type);
+ case ACTION_TYPE_PTR_BUTTON:
+ write_buf(buf, "%s%s(button=", prefix, type);
if (action->btn.button > 0 && action->btn.button <= 5)
- write_buf(keymap, buf, size, offset, "%d", action->btn.button);
+ write_buf(buf, "%d", action->btn.button);
else
- write_buf(keymap, buf, size, offset, "default");
+ write_buf(buf, "default");
if (action->btn.count)
- write_buf(keymap, buf, size, offset, ",count=%d",
- action->btn.count);
+ write_buf(buf, ",count=%d", action->btn.count);
if (args)
- write_buf(keymap, buf, size, offset, "%s", args);
- write_buf(keymap, buf, size, offset, ")%s", suffix);
+ write_buf(buf, "%s", args);
+ write_buf(buf, ")%s", suffix);
break;
- case XkbSA_SetPtrDflt:
- write_buf(keymap, buf, size, offset, "%sSetPtrDflt(", prefix);
- if (action->dflt.affect == XkbSA_AffectDfltBtn)
- write_buf(keymap, buf, size, offset, "affect=button,button=%s%d",
- (!(action->dflt.flags & XkbSA_DfltBtnAbsolute) &&
- action->dflt.value >= 0) ? "+" : "",
- action->dflt.value);
- write_buf(keymap, buf, size, offset, ")%s", suffix);
+
+ case ACTION_TYPE_PTR_DEFAULT:
+ write_buf(buf, "%s%s(", prefix, type);
+ write_buf(buf, "affect=button,button=%s%d",
+ (!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) &&
+ action->dflt.value >= 0) ? "+" : "",
+ action->dflt.value);
+ write_buf(buf, ")%s", suffix);
break;
- case XkbSA_SwitchScreen:
- write_buf(keymap, buf, size, offset,
- "%sSwitchScreen(screen=%s%d,%ssame)%s", prefix,
- (!(action->screen.flags & XkbSA_SwitchAbsolute) &&
+
+ case ACTION_TYPE_SWITCH_VT:
+ write_buf(buf, "%s%s(screen=%s%d,%ssame)%s", prefix, type,
+ (!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) &&
action->screen.screen >= 0) ? "+" : "",
action->screen.screen,
- (action->screen.flags & XkbSA_SwitchApplication) ? "!" : "",
+ (action->screen.flags & ACTION_SAME_SCREEN) ? "!" : "",
suffix);
break;
- /* Deprecated actions below here */
- case XkbSA_SetControls:
- if (!type)
- type = "SetControls";
- case XkbSA_LockControls:
- if (!type)
- type = "LockControls";
- write_buf(keymap, buf, size, offset, "%s%s(controls=%s)%s",
- prefix, type, get_control_mask_text(action->ctrls.ctrls),
- suffix);
+
+ case ACTION_TYPE_CTRL_SET:
+ case ACTION_TYPE_CTRL_LOCK:
+ write_buf(buf, "%s%s(controls=%s)%s", prefix, type,
+ ControlMaskText(keymap->ctx, action->ctrls.ctrls), suffix);
break;
- case XkbSA_ISOLock:
- case XkbSA_ActionMessage:
- case XkbSA_RedirectKey:
- case XkbSA_DeviceBtn:
- case XkbSA_LockDeviceBtn:
- case XkbSA_NoAction:
- /* XXX TODO */
- write_buf(keymap, buf, size, offset, "%sNoAction()%s", prefix, suffix);
+
+ case ACTION_TYPE_NONE:
+ write_buf(buf, "%sNoAction()%s", prefix, suffix);
break;
- case XkbSA_XFree86Private:
+
default:
- write_buf(keymap, buf, size, offset,
- "%sPrivate(type=0x%02x,data[0]=0x%02x,data[1]=0x%02x,data[2]=0x%02x,data[3]=0x%02x,data[4]=0x%02x,data[5]=0x%02x,data[6]=0x%02x)%s",
- prefix, action->any.type, action->any.data[0],
- action->any.data[1], action->any.data[2],
- action->any.data[3], action->any.data[4],
- action->any.data[5], action->any.data[6], suffix);
+ write_buf(buf,
+ "%s%s(type=0x%02x,data[0]=0x%02x,data[1]=0x%02x,data[2]=0x%02x,data[3]=0x%02x,data[4]=0x%02x,data[5]=0x%02x,data[6]=0x%02x)%s",
+ prefix, type, action->type, action->priv.data[0],
+ action->priv.data[1], action->priv.data[2],
+ action->priv.data[3], action->priv.data[4],
+ action->priv.data[5], action->priv.data[6],
+ suffix);
break;
}
}
static bool
-write_compat(struct xkb_keymap *keymap, char **buf, size_t *size,
- size_t *offset)
+write_compat(struct xkb_keymap *keymap, struct buf *buf)
{
- int i;
struct xkb_sym_interpret *interp;
+ const struct xkb_indicator_map *led;
- write_buf(keymap, buf, size, offset, "\txkb_compatibility {\n\n");
+ if (keymap->compat_section_name)
+ write_buf(buf, "\txkb_compatibility \"%s\" {\n\n",
+ keymap->compat_section_name);
+ else
+ write_buf(buf, "\txkb_compatibility {\n\n");
- write_vmods(keymap, buf, size, offset);
+ write_vmods(keymap, buf);
- write_buf(keymap, buf, size, offset, "\t\tinterpret.useModMapMods= AnyLevel;\n");
- write_buf(keymap, buf, size, offset, "\t\tinterpret.repeat= false;\n");
- write_buf(keymap, buf, size, offset, "\t\tinterpret.locking= false;\n");
+ write_buf(buf, "\t\tinterpret.useModMapMods= AnyLevel;\n");
+ write_buf(buf, "\t\tinterpret.repeat= False;\n");
- darray_foreach(interp, keymap->compat->sym_interpret) {
+ darray_foreach(interp, keymap->sym_interprets) {
char keysym_name[64];
if (interp->sym == XKB_KEY_NoSymbol)
else
xkb_keysym_get_name(interp->sym, keysym_name, sizeof(keysym_name));
- write_buf(keymap, buf, size, offset, "\t\tinterpret %s+%s(%s) {\n",
+ write_buf(buf, "\t\tinterpret %s+%s(%s) {\n",
keysym_name,
- get_interp_match_text(interp->match),
- get_mod_mask_text(keymap, interp->mods, 0));
-
- if (interp->virtual_mod != XkbNoModifier) {
- write_buf(keymap, buf, size, offset, "\t\t\tvirtualModifier= %s;\n",
- keymap->names->vmods[interp->virtual_mod]);
- }
-
- if (interp->match & XkbSI_LevelOneOnly)
- write_buf(keymap, buf, size, offset, "\t\t\tuseModMapMods=level1;\n");
- if (interp->flags & XkbSI_LockingKey)
- write_buf(keymap, buf, size, offset, "\t\t\tlocking= true;\n");
- if (interp->flags & XkbSI_AutoRepeat)
- write_buf(keymap, buf, size, offset, "\t\t\trepeat= true;\n");
-
- write_action(keymap, buf, size, offset, &interp->act,
- "\t\t\taction= ", ";\n");
- write_buf(keymap, buf, size, offset, "\t\t};\n");
- }
+ SIMatchText(interp->match),
+ ModMaskText(keymap, interp->mods));
- for (i = 0; i < XkbNumKbdGroups; i++) {
- struct xkb_mods *gc;
+ if (interp->virtual_mod != XKB_MOD_INVALID)
+ write_buf(buf, "\t\t\tvirtualModifier= %s;\n",
+ ModIndexText(keymap, interp->virtual_mod));
- gc = &keymap->compat->groups[i];
- if (gc->real_mods == 0 && gc->vmods ==0)
- continue;
- write_buf(keymap, buf, size, offset,
- "\t\tgroup %d = %s;\n", i + 1,
- get_mod_mask_text(keymap, gc->real_mods, gc->vmods));
- }
+ if (interp->level_one_only)
+ write_buf(buf, "\t\t\tuseModMapMods=level1;\n");
+ if (interp->repeat)
+ write_buf(buf, "\t\t\trepeat= True;\n");
- for (i = 0; i < XkbNumIndicators; i++) {
- struct xkb_indicator_map *map = &keymap->indicators->maps[i];
- if (map->flags == 0 && map->which_groups == 0 &&
- map->groups == 0 && map->which_mods == 0 &&
- map->mods.real_mods == 0 && map->mods.vmods == 0 &&
- map->ctrls == 0)
- continue;
- write_indicator_map(keymap, buf, size, offset, i);
+ write_action(keymap, buf, &interp->action, "\t\t\taction= ", ";\n");
+ write_buf(buf, "\t\t};\n");
}
- write_buf(keymap, buf, size, offset, "\t};\n\n");
+ darray_foreach(led, keymap->indicators)
+ if (led->which_groups || led->groups || led->which_mods ||
+ led->mods.mods || led->ctrls)
+ write_indicator_map(keymap, buf, led);
+
+ write_buf(buf, "\t};\n\n");
return true;
}
static bool
-write_keysyms(struct xkb_keymap *keymap, char **buf, size_t *size,
- size_t *offset, xkb_keycode_t key, unsigned int group)
+write_keysyms(struct xkb_keymap *keymap, struct buf *buf,
+ struct xkb_key *key, xkb_layout_index_t group)
{
const xkb_keysym_t *syms;
- int num_syms, level;
+ int num_syms;
+ xkb_level_index_t level;
#define OUT_BUF_LEN 128
char out_buf[OUT_BUF_LEN];
- for (level = 0; level < XkbKeyGroupWidth(keymap, key, group); level++) {
+ for (level = 0; level < XkbKeyGroupWidth(key, group); level++) {
if (level != 0)
- write_buf(keymap, buf, size, offset, ", ");
- num_syms = xkb_key_get_syms_by_level(keymap, key, group, level,
- &syms);
+ write_buf(buf, ", ");
+ num_syms = xkb_keymap_key_get_syms_by_level(keymap, key->keycode,
+ group, level, &syms);
if (num_syms == 0) {
- write_buf(keymap, buf, size, offset, "%15s", "NoSymbol");
+ write_buf(buf, "%15s", "NoSymbol");
}
else if (num_syms == 1) {
xkb_keysym_get_name(syms[0], out_buf, OUT_BUF_LEN);
- write_buf(keymap, buf, size, offset, "%15s", out_buf);
+ write_buf(buf, "%15s", out_buf);
}
else {
int s;
- write_buf(keymap, buf, size, offset, "{ ");
+ write_buf(buf, "{ ");
for (s = 0; s < num_syms; s++) {
if (s != 0)
- write_buf(keymap, buf, size, offset, ", ");
+ write_buf(buf, ", ");
xkb_keysym_get_name(syms[s], out_buf, OUT_BUF_LEN);
- write_buf(keymap, buf, size, offset, "%15s", out_buf);
+ write_buf(buf, "%s", out_buf);
}
- write_buf(keymap, buf, size, offset, " }");
+ write_buf(buf, " }");
}
}
#undef OUT_BUF_LEN
}
static bool
-write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
- size_t *offset)
+write_symbols(struct xkb_keymap *keymap, struct buf *buf)
{
- struct xkb_client_map *map = keymap->map;
- struct xkb_server_map *srv = keymap->server;
- xkb_keycode_t key;
- int group, tmp;
+ struct xkb_key *key;
+ xkb_layout_index_t group, tmp;
+ xkb_atom_t *group_name;
bool showActions;
- write_buf(keymap, buf, size, offset, "\txkb_symbols {\n\n");
+ if (keymap->symbols_section_name)
+ write_buf(buf, "\txkb_symbols \"%s\" {\n\n",
+ keymap->symbols_section_name);
+ else
+ write_buf(buf, "\txkb_symbols {\n\n");
- for (tmp = group = 0; group < XkbNumKbdGroups; group++) {
- if (!keymap->names->groups[group])
+ tmp = 0;
+ darray_enumerate(group, group_name, keymap->group_names) {
+ if (!*group_name)
continue;
- write_buf(keymap, buf, size, offset,
+ write_buf(buf,
"\t\tname[group%d]=\"%s\";\n", group + 1,
- keymap->names->groups[group]);
- tmp++;
+ xkb_atom_text(keymap->ctx, *group_name));
+ tmp++;
}
if (tmp > 0)
- write_buf(keymap, buf, size, offset, "\n");
-
- for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
- bool simple = true;
-
- if (xkb_key_num_groups(keymap, key) == 0)
- continue;
- if (XkbcFindKeycodeByName(keymap,
- darray_item(keymap->names->keys, key).name,
- true) != key)
- continue;
-
- write_buf(keymap, buf, size, offset, "\t\tkey %6s {",
- XkbcKeyNameText(darray_item(keymap->names->keys, key).name));
- if (srv->explicit) {
- if ((srv->explicit[key] & XkbExplicitKeyTypesMask)) {
- bool multi_type = false;
- int type = XkbKeyTypeIndex(keymap, key, 0);
-
- simple = false;
-
- for (group = 0; group < xkb_key_num_groups(keymap, key); group++) {
- if (XkbKeyTypeIndex(keymap, key, group) != type) {
- multi_type = true;
- break;
- }
- }
- if (multi_type) {
- for (group = 0;
- group < xkb_key_num_groups(keymap, key);
- group++) {
- if (!(srv->explicit[key] & (1 << group)))
- continue;
- type = XkbKeyTypeIndex(keymap, key, group);
- write_buf(keymap, buf, size, offset,
- "\n\t\t\ttype[Group%d]= \"%s\",",
- group + 1,
- darray_item(map->types, type).name);
- }
- }
- else {
- write_buf(keymap, buf, size, offset,
- "\n\t\t\ttype= \"%s\",",
- darray_item(map->types, type).name);
+ write_buf(buf, "\n");
+
+ xkb_foreach_key(key, keymap) {
+ bool simple = true;
+ bool explicit_types = false;
+ bool multi_type = false;
+
+ if (key->num_groups == 0)
+ continue;
+
+ write_buf(buf, "\t\tkey %-20s {", KeyNameText(keymap->ctx, key->name));
+
+ for (group = 0; group < key->num_groups; group++) {
+ if (key->groups[group].explicit_type)
+ explicit_types = true;
+
+ if (group != 0 && key->groups[group].type != key->groups[0].type)
+ multi_type = true;
+ }
+
+ if (explicit_types) {
+ const struct xkb_key_type *type;
+ simple = false;
+
+ if (multi_type) {
+ for (group = 0; group < key->num_groups; group++) {
+ if (!key->groups[group].explicit_type)
+ continue;
+
+ type = key->groups[group].type;
+ write_buf(buf, "\n\t\t\ttype[group%u]= \"%s\",",
+ group + 1,
+ xkb_atom_text(keymap->ctx, type->name));
}
}
- if (keymap->ctrls && (srv->explicit[key] & XkbExplicitAutoRepeatMask)) {
- if (keymap->ctrls->per_key_repeat[key / 8] & (1 << (key % 8)))
- write_buf(keymap, buf, size, offset,
- "\n\t\t\trepeat= Yes,");
- else
- write_buf(keymap, buf, size, offset,
- "\n\t\t\trepeat= No,");
- simple = false;
- }
- if (keymap->server->vmodmap[key] &&
- (srv->explicit[key] & XkbExplicitVModMapMask)) {
- write_buf(keymap, buf, size, offset, "\n\t\t\tvirtualMods= %s,",
- get_mod_mask_text(keymap, 0, keymap->server->vmodmap[key]));
- }
- }
-
- switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(keymap, key))) {
- case XkbClampIntoRange:
- write_buf(keymap, buf, size, offset, "\n\t\t\tgroupsClamp,");
- break;
- case XkbRedirectIntoRange:
- write_buf(keymap, buf, size, offset,
- "\n\t\t\tgroupsRedirect= Group%d,",
- XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(keymap, key)) + 1);
- break;
- }
-
- if (srv->explicit == NULL ||
- (srv->explicit[key] & XkbExplicitInterpretMask))
- showActions = XkbKeyHasActions(keymap, key);
- else
- showActions = false;
-
- if (xkb_key_num_groups(keymap, key) > 1 || showActions)
- simple = false;
-
- if (simple) {
- write_buf(keymap, buf, size, offset, "\t[ ");
- if (!write_keysyms(keymap, buf, size, offset, key, 0))
+ else {
+ type = key->groups[0].type;
+ write_buf(buf, "\n\t\t\ttype= \"%s\",",
+ xkb_atom_text(keymap->ctx, type->name));
+ }
+ }
+
+ if (key->explicit & EXPLICIT_REPEAT) {
+ if (key->repeats)
+ write_buf(buf, "\n\t\t\trepeat= Yes,");
+ else
+ write_buf(buf, "\n\t\t\trepeat= No,");
+ simple = false;
+ }
+
+ if (key->vmodmap && (key->explicit & EXPLICIT_VMODMAP))
+ write_buf(buf, "\n\t\t\tvirtualMods= %s,",
+ ModMaskText(keymap, key->vmodmap));
+
+ switch (key->out_of_range_group_action) {
+ case RANGE_SATURATE:
+ write_buf(buf, "\n\t\t\tgroupsClamp,");
+ break;
+
+ case RANGE_REDIRECT:
+ write_buf(buf, "\n\t\t\tgroupsRedirect= Group%u,",
+ key->out_of_range_group_number + 1);
+ break;
+
+ default:
+ break;
+ }
+
+ showActions = !!(key->explicit & EXPLICIT_INTERP);
+
+ if (key->num_groups > 1 || showActions)
+ simple = false;
+
+ if (simple) {
+ write_buf(buf, "\t[ ");
+ if (!write_keysyms(keymap, buf, key, 0))
return false;
- write_buf(keymap, buf, size, offset, " ] };\n");
- }
- else {
- union xkb_action *acts;
- int level;
-
- acts = XkbKeyActionsPtr(keymap, key);
- for (group = 0; group < xkb_key_num_groups(keymap, key); group++) {
- if (group != 0)
- write_buf(keymap, buf, size, offset, ",");
- write_buf(keymap, buf, size, offset,
- "\n\t\t\tsymbols[Group%d]= [ ", group + 1);
- if (!write_keysyms(keymap, buf, size, offset, key, group))
+ write_buf(buf, " ] };\n");
+ }
+ else {
+ xkb_level_index_t level;
+
+ for (group = 0; group < key->num_groups; group++) {
+ if (group != 0)
+ write_buf(buf, ",");
+ write_buf(buf, "\n\t\t\tsymbols[Group%u]= [ ", group + 1);
+ if (!write_keysyms(keymap, buf, key, group))
return false;
- write_buf(keymap, buf, size, offset, " ]");
- if (showActions) {
- write_buf(keymap, buf, size, offset,
- ",\n\t\t\tactions[Group%d]= [ ", group + 1);
- for (level = 0;
- level < XkbKeyGroupWidth(keymap, key, group);
- level++) {
- if (level != 0)
- write_buf(keymap, buf, size, offset, ", ");
- write_action(keymap, buf, size, offset, &acts[level],
+ write_buf(buf, " ]");
+ if (showActions) {
+ write_buf(buf, ",\n\t\t\tactions[Group%u]= [ ",
+ group + 1);
+ for (level = 0;
+ level < XkbKeyGroupWidth(key, group); level++) {
+ if (level != 0)
+ write_buf(buf, ", ");
+ write_action(keymap, buf,
+ &key->groups[group].levels[level].action,
NULL, NULL);
- }
- write_buf(keymap, buf, size, offset, " ]");
- acts += XkbKeyGroupsWidth(keymap, key);
- }
- }
- write_buf(keymap, buf, size, offset, "\n\t\t};\n");
- }
+ }
+ write_buf(buf, " ]");
+ }
+ }
+ write_buf(buf, "\n\t\t};\n");
+ }
}
- if (map && map->modmap) {
- for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
- int mod;
- char name[5];
- if (map->modmap[key] == 0)
- continue;
+ xkb_foreach_key(key, keymap) {
+ xkb_mod_index_t i;
+ const struct xkb_mod *mod;
- for (mod = 0; mod < XkbNumModifiers; mod++) {
- if (!(map->modmap[key] & (1 << mod)))
- continue;
+ if (key->modmap == 0)
+ continue;
- memcpy(name, darray_item(keymap->names->keys, key).name, 4);
- name[4]= '\0';
+ darray_enumerate(i, mod, keymap->mods) {
+ if (!(key->modmap & (1 << i)))
+ continue;
- write_buf(keymap, buf, size, offset,
- "\t\tmodifier_map %s { <%s> };\n",
- get_mod_index_text(mod), name);
- }
- }
+ write_buf(buf, "\t\tmodifier_map %s { %s };\n",
+ xkb_atom_text(keymap->ctx, mod->name),
+ KeyNameText(keymap->ctx, key->name));
+ }
}
- write_buf(keymap, buf, size, offset, "\t};\n\n");
+ write_buf(buf, "\t};\n\n");
return true;
}
-_X_EXPORT char *
-xkb_map_get_as_string(struct xkb_keymap *keymap)
+XKB_EXPORT char *
+xkb_keymap_get_as_string(struct xkb_keymap *keymap,
+ enum xkb_keymap_format format)
{
- char *ret = NULL;
- size_t size = 0;
- size_t offset = 0;
+ bool ok;
+ struct buf buf = { NULL, 0, 0 };
- check_write_buf(keymap, &ret, &size, &offset, "xkb_keymap {\n");
- if (ret == NULL)
- return NULL;
- if (!write_keycodes(keymap, &ret, &size, &offset))
- return NULL;
- if (!write_types(keymap, &ret, &size, &offset))
- return NULL;
- if (!write_compat(keymap, &ret, &size, &offset))
- return NULL;
- if (!write_symbols(keymap, &ret, &size, &offset))
- return NULL;
- check_write_buf(keymap, &ret, &size, &offset, "};\n");
- if (ret == NULL)
+ if (format == XKB_KEYMAP_USE_ORIGINAL_FORMAT)
+ format = keymap->format;
+
+ if (format != XKB_KEYMAP_FORMAT_TEXT_V1) {
+ log_err(keymap->ctx,
+ "Trying to get a keymap as a string in an unsupported format (%d)\n",
+ format);
return NULL;
+ }
+
+ ok = (check_write_buf(&buf, "xkb_keymap {\n") &&
+ write_keycodes(keymap, &buf) &&
+ write_types(keymap, &buf) &&
+ write_compat(keymap, &buf) &&
+ write_symbols(keymap, &buf) &&
+ check_write_buf(&buf, "};\n"));
- return ret;
+ return (ok ? buf.buf : NULL);
}