1 /************************************************************
2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
28 * Copyright © 2012 Intel Corporation
30 * Permission is hereby granted, free of charge, to any person obtaining a
31 * copy of this software and associated documentation files (the "Software"),
32 * to deal in the Software without restriction, including without limitation
33 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
34 * and/or sell copies of the Software, and to permit persons to whom the
35 * Software is furnished to do so, subject to the following conditions:
37 * The above copyright notice and this permission notice (including the next
38 * paragraph) shall be included in all copies or substantial portions of the
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
44 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
46 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
47 * DEALINGS IN THE SOFTWARE.
49 * Author: Daniel Stone <daniel@fooishbar.org>
61 #define VMOD_HIDE_VALUE 0
62 #define VMOD_SHOW_VALUE 1
63 #define VMOD_COMMENT_VALUE 2
65 #define BUF_CHUNK_SIZE 4096
68 do_realloc(char **buf, size_t *size, size_t offset, size_t at_least)
72 *size += BUF_CHUNK_SIZE;
73 if (at_least >= BUF_CHUNK_SIZE)
76 new = realloc(*buf, *size);
81 memset(*buf + offset, 0, *size - offset);
86 /* This whole thing should be a function, but you can't call vsnprintf
88 #define check_write_buf(keymap, buf, size, offset, ...) \
93 /* Concatenate the strings, and check whether or not the output was \
95 while ((_printed = snprintf(*buf + *offset, *size - *offset, \
98 /* If it was truncated, embiggen the string and roll from the top. */ \
99 if (!do_realloc(buf, size, *offset, _printed)) { \
101 "xkbcommon: failed to allocate %lu bytes for keymap\n", \
102 (unsigned long) *size); \
110 *offset += _printed; \
113 #define write_buf(keymap, buf, size, offset, ...) \
115 check_write_buf(keymap, buf, size, offset, __VA_ARGS__); \
121 write_vmods(struct xkb_keymap *keymap, char **buf, size_t *size, size_t *offset)
126 for (i = 0; i < XkbNumVirtualMods; i++) {
127 if (!keymap->names->vmods[i])
130 write_buf(keymap, buf, size, offset, "\t\tvirtual_modifiers ");
132 write_buf(keymap, buf, size, offset, ",");
133 write_buf(keymap, buf, size, offset, "%s", keymap->names->vmods[i]);
138 write_buf(keymap, buf, size, offset, ";\n\n");
143 #define GET_TEXT_BUF_SIZE 512
145 #define append_get_text(...) do { \
146 int _size = snprintf(ret, GET_TEXT_BUF_SIZE, __VA_ARGS__); \
147 if (_size >= GET_TEXT_BUF_SIZE) \
151 /* FIXME: Merge with src/xkbcomp/expr.c::modIndexNames. */
152 static const char *core_mod_names[] = {
164 get_mod_index_text(uint8_t real_mod)
166 return core_mod_names[real_mod];
170 get_mod_mask_text(struct xkb_keymap *keymap, uint8_t real_mods, uint32_t vmods)
172 static char ret[GET_TEXT_BUF_SIZE], ret2[GET_TEXT_BUF_SIZE];
175 memset(ret, 0, GET_TEXT_BUF_SIZE);
177 if (real_mods == 0 && vmods == 0) {
182 /* This is so broken. If we have a real modmask of 0xff and a
183 * vmodmask, we'll get, e.g., all+RightControl. But, it's what xkbfile
185 if (real_mods == 0xff) {
188 else if (real_mods) {
189 for (i = 0; i < XkbNumModifiers; i++) {
190 if (!(real_mods & (1 << i)))
192 if (ret[0] != '\0') {
194 append_get_text("%s+%s", ret2, core_mod_names[i]);
197 append_get_text("%s", core_mod_names[i]);
205 for (i = 0; i < XkbNumVirtualMods; i++) {
206 if (!(vmods & (1 << i)))
208 if (ret[0] != '\0') {
210 append_get_text("%s+%s", ret2, keymap->names->vmods[i]);
213 append_get_text("%s", keymap->names->vmods[i]);
221 get_indicator_state_text(uint8_t which)
224 static char ret[GET_TEXT_BUF_SIZE];
225 /* FIXME: Merge with ... something ... in xkbcomp? */
226 static const char *state_names[] = {
234 memset(ret, 0, GET_TEXT_BUF_SIZE);
236 which &= XkbIM_UseAnyMods;
243 for (i = 0; which != 0; i++) {
244 if (!(which & (1 << i)))
249 append_get_text("%s+%s", ret, state_names[i]);
251 append_get_text("%s", state_names[i]);
258 get_control_mask_text(uint32_t control_mask)
261 static char ret[GET_TEXT_BUF_SIZE];
262 /* FIXME: Merge with ... something ... in xkbcomp. */
263 static const char *ctrl_names[] = {
279 memset(ret, 0, GET_TEXT_BUF_SIZE);
281 control_mask &= XkbAllBooleanCtrlsMask;
283 if (control_mask == 0) {
287 else if (control_mask == XkbAllBooleanCtrlsMask) {
292 for (i = 0; control_mask; i++) {
293 if (!(control_mask & (1 << i)))
295 control_mask &= ~(1 << i);
298 append_get_text("%s+%s", ret, ctrl_names[i]);
300 append_get_text("%s", ctrl_names[i]);
307 write_keycodes(struct xkb_keymap *keymap, char **buf, size_t *size,
311 struct xkb_key_alias *alias;
314 write_buf(keymap, buf, size, offset, "\txkb_keycodes {\n");
315 write_buf(keymap, buf, size, offset, "\t\tminimum = %d;\n",
316 keymap->min_key_code);
317 write_buf(keymap, buf, size, offset, "\t\tmaximum = %d;\n",
318 keymap->max_key_code);
320 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
321 const char *alternate = "";
323 if (darray_item(keymap->names->keys, key).name[0] == '\0')
325 if (XkbcFindKeycodeByName(keymap,
326 darray_item(keymap->names->keys, key).name,
328 alternate = "alternate ";
329 write_buf(keymap, buf, size, offset, "\t\t%s%6s = %d;\n", alternate,
330 XkbcKeyNameText(darray_item(keymap->names->keys, key).name),
334 for (i = 0; i < XkbNumIndicators; i++) {
335 if (!keymap->names->indicators[i])
337 write_buf(keymap, buf, size, offset, "\t\tindicator %d = \"%s\";\n",
338 i + 1, keymap->names->indicators[i]);
342 for (i = 0; i < darray_size(keymap->names->key_aliases); i++) {
343 alias = &darray_item(keymap->names->key_aliases, i);
344 write_buf(keymap, buf, size, offset, "\t\talias %6s = %6s;\n",
345 XkbcKeyNameText(alias->alias),
346 XkbcKeyNameText(alias->real));
349 write_buf(keymap, buf, size, offset, "\t};\n\n");
354 write_types(struct xkb_keymap *keymap, char **buf, size_t *size,
358 struct xkb_key_type *type;
360 write_buf(keymap, buf, size, offset, "\txkb_types {\n\n");
361 write_vmods(keymap, buf, size, offset);
363 for (i = 0; i < darray_size(keymap->map->types); i++) {
364 type = &darray_item(keymap->map->types, i);
365 write_buf(keymap, buf, size, offset, "\t\ttype \"%s\" {\n",
367 write_buf(keymap, buf, size, offset, "\t\t\tmodifiers= %s;\n",
368 get_mod_mask_text(keymap, type->mods.real_mods,
371 for (n = 0; n < darray_size(type->map); n++) {
372 struct xkb_kt_map_entry *entry = &darray_item(type->map, n);
375 str = get_mod_mask_text(keymap, entry->mods.real_mods,
377 write_buf(keymap, buf, size, offset, "\t\t\tmap[%s]= Level%d;\n",
378 str, entry->level + 1);
380 if (!type->preserve || (!type->preserve[n].real_mods &&
381 !type->preserve[n].vmods))
383 write_buf(keymap, buf, size, offset, "\t\t\tpreserve[%s]= ", str);
384 write_buf(keymap, buf, size, offset, "%s;\n",
385 get_mod_mask_text(keymap, type->preserve[n].real_mods,
386 type->preserve[n].vmods));
389 if (type->level_names) {
390 for (n = 0; n < type->num_levels; n++) {
391 if (!type->level_names[n])
393 write_buf(keymap, buf, size, offset,
394 "\t\t\tlevel_name[Level%d]= \"%s\";\n", n + 1,
395 type->level_names[n]);
398 write_buf(keymap, buf, size, offset, "\t\t};\n");
401 write_buf(keymap, buf, size, offset, "\t};\n\n");
406 write_indicator_map(struct xkb_keymap *keymap, char **buf, size_t *size,
407 size_t *offset, int num)
409 struct xkb_indicator_map *led = &keymap->indicators->maps[num];
411 write_buf(keymap, buf, size, offset, "\t\tindicator \"%s\" {\n",
412 keymap->names->indicators[num]);
414 if (led->which_groups) {
415 if (led->which_groups != XkbIM_UseEffective) {
416 write_buf(keymap, buf, size, offset, "\t\t\twhichGroupState= %s;\n",
417 get_indicator_state_text(led->which_groups));
419 write_buf(keymap, buf, size, offset, "\t\t\tgroups= 0x%02x;\n",
423 if (led->which_mods) {
424 if (led->which_mods != XkbIM_UseEffective) {
425 write_buf(keymap, buf, size, offset, "\t\t\twhichModState= %s;\n",
426 get_indicator_state_text(led->which_mods));
428 write_buf(keymap, buf, size, offset, "\t\t\tmodifiers= %s;\n",
429 get_mod_mask_text(keymap, led->mods.real_mods,
434 write_buf(keymap, buf, size, offset, "\t\t\tcontrols= %s;\n",
435 get_control_mask_text(led->ctrls));
438 write_buf(keymap, buf, size, offset, "\t\t};\n");
443 get_interp_match_text(uint8_t type)
447 switch (type & XkbSI_OpMask) {
449 sprintf(ret, "NoneOf");
451 case XkbSI_AnyOfOrNone:
452 sprintf(ret, "AnyOfOrNone");
455 sprintf(ret, "AnyOf");
458 sprintf(ret, "AllOf");
461 sprintf(ret, "Exactly");
464 sprintf(ret, "0x%x", type & XkbSI_OpMask);
472 write_action(struct xkb_keymap *keymap, char **buf, size_t *size,
473 size_t *offset, union xkb_action *action, const char *prefix,
476 const char *type = NULL;
477 const char *args = NULL;
484 switch (action->any.type) {
488 case XkbSA_LatchMods:
494 if (action->mods.flags & XkbSA_UseModMapMods)
497 args = get_mod_mask_text(keymap, action->mods.real_mods,
499 write_buf(keymap, buf, size, offset, "%s%s(modifiers=%s%s%s)%s",
501 (action->any.type != XkbSA_LockGroup &&
502 action->mods.flags & XkbSA_ClearLocks) ? ",clearLocks" : "",
503 (action->any.type != XkbSA_LockGroup &&
504 action->mods.flags & XkbSA_LatchToLock) ? ",latchToLock" : "",
510 case XkbSA_LatchGroup:
513 case XkbSA_LockGroup:
516 write_buf(keymap, buf, size, offset, "%s%s(group=%s%d%s%s)%s",
518 (!(action->group.flags & XkbSA_GroupAbsolute) &&
519 action->group.group > 0) ? "+" : "",
520 (action->group.flags & XkbSA_GroupAbsolute) ?
521 action->group.group + 1 : action->group.group,
522 (action->any.type != XkbSA_LockGroup &&
523 action->group.flags & XkbSA_ClearLocks) ? ",clearLocks" : "",
524 (action->any.type != XkbSA_LockGroup &&
525 action->group.flags & XkbSA_LatchToLock) ? ",latchToLock" : "",
528 case XkbSA_Terminate:
529 write_buf(keymap, buf, size, offset, "%sTerminate()%s", prefix, suffix);
532 write_buf(keymap, buf, size, offset, "%sMovePtr(x=%s%d,y=%s%d%s)%s",
534 (!(action->ptr.flags & XkbSA_MoveAbsoluteX) &&
535 action->ptr.x >= 0) ? "+" : "",
537 (!(action->ptr.flags & XkbSA_MoveAbsoluteY) &&
538 action->ptr.y >= 0) ? "+" : "",
540 (action->ptr.flags & XkbSA_NoAcceleration) ? ",!accel" : "",
546 case XkbSA_LockPtrBtn:
549 switch (action->btn.flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
550 case XkbSA_LockNoUnlock:
551 args = ",affect=lock";
553 case XkbSA_LockNoLock:
554 args = ",affect=unlock";
556 case XkbSA_LockNoLock | XkbSA_LockNoUnlock:
557 args = ",affect=neither";
560 args = ",affect=both";
567 write_buf(keymap, buf, size, offset, "%s%s(button=", prefix, type);
568 if (action->btn.button > 0 && action->btn.button <= 5)
569 write_buf(keymap, buf, size, offset, "%d", action->btn.button);
571 write_buf(keymap, buf, size, offset, "default");
572 if (action->btn.count)
573 write_buf(keymap, buf, size, offset, ",count=%d",
576 write_buf(keymap, buf, size, offset, "%s", args);
577 write_buf(keymap, buf, size, offset, ")%s", suffix);
579 case XkbSA_SetPtrDflt:
580 write_buf(keymap, buf, size, offset, "%sSetPtrDflt(", prefix);
581 if (action->dflt.affect == XkbSA_AffectDfltBtn)
582 write_buf(keymap, buf, size, offset, "affect=button,button=%s%d",
583 (!(action->dflt.flags & XkbSA_DfltBtnAbsolute) &&
584 action->dflt.value >= 0) ? "+" : "",
586 write_buf(keymap, buf, size, offset, ")%s", suffix);
588 case XkbSA_SwitchScreen:
589 write_buf(keymap, buf, size, offset,
590 "%sSwitchScreen(screen=%s%d,%ssame)%s", prefix,
591 (!(action->screen.flags & XkbSA_SwitchAbsolute) &&
592 action->screen.screen >= 0) ? "+" : "",
593 action->screen.screen,
594 (action->screen.flags & XkbSA_SwitchApplication) ? "!" : "",
597 /* Deprecated actions below here */
598 case XkbSA_SetControls:
600 type = "SetControls";
601 case XkbSA_LockControls:
603 type = "LockControls";
604 write_buf(keymap, buf, size, offset, "%s%s(controls=%s)%s",
605 prefix, type, get_control_mask_text(action->ctrls.ctrls),
609 case XkbSA_ActionMessage:
610 case XkbSA_RedirectKey:
611 case XkbSA_DeviceBtn:
612 case XkbSA_LockDeviceBtn:
615 write_buf(keymap, buf, size, offset, "%sNoAction()%s", prefix, suffix);
617 case XkbSA_XFree86Private:
619 write_buf(keymap, buf, size, offset,
620 "%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",
621 prefix, action->any.type, action->any.data[0],
622 action->any.data[1], action->any.data[2],
623 action->any.data[3], action->any.data[4],
624 action->any.data[5], action->any.data[6], suffix);
632 write_compat(struct xkb_keymap *keymap, char **buf, size_t *size,
636 struct xkb_sym_interpret *interp;
638 write_buf(keymap, buf, size, offset, "\txkb_compatibility {\n\n");
640 write_vmods(keymap, buf, size, offset);
642 write_buf(keymap, buf, size, offset, "\t\tinterpret.useModMapMods= AnyLevel;\n");
643 write_buf(keymap, buf, size, offset, "\t\tinterpret.repeat= false;\n");
644 write_buf(keymap, buf, size, offset, "\t\tinterpret.locking= false;\n");
646 for (i = 0; i < darray_size(keymap->compat->sym_interpret); i++) {
647 char keysym_name[64];
648 interp = &darray_item(keymap->compat->sym_interpret, i);
650 if (interp->sym == XKB_KEY_NoSymbol)
651 sprintf(keysym_name, "Any");
653 xkb_keysym_get_name(interp->sym, keysym_name, 64);
655 write_buf(keymap, buf, size, offset, "\t\tinterpret %s+%s(%s) {\n",
657 get_interp_match_text(interp->match),
658 get_mod_mask_text(keymap, interp->mods, 0));
660 if (interp->virtual_mod != XkbNoModifier) {
661 write_buf(keymap, buf, size, offset, "\t\t\tvirtualModifier= %s;\n",
662 keymap->names->vmods[interp->virtual_mod]);
665 if (interp->match & XkbSI_LevelOneOnly)
666 write_buf(keymap, buf, size, offset, "\t\t\tuseModMapMods=level1;\n");
667 if (interp->flags & XkbSI_LockingKey)
668 write_buf(keymap, buf, size, offset, "\t\t\tlocking= true;\n");
669 if (interp->flags & XkbSI_AutoRepeat)
670 write_buf(keymap, buf, size, offset, "\t\t\trepeat= true;\n");
672 write_action(keymap, buf, size, offset, &interp->act,
673 "\t\t\taction= ", ";\n");
674 write_buf(keymap, buf, size, offset, "\t\t};\n");
677 for (i = 0; i < XkbNumKbdGroups; i++) {
680 gc = &keymap->compat->groups[i];
681 if (gc->real_mods == 0 && gc->vmods ==0)
683 write_buf(keymap, buf, size, offset,
684 "\t\tgroup %d = %s;\n", i + 1,
685 get_mod_mask_text(keymap, gc->real_mods, gc->vmods));
688 for (i = 0; i < XkbNumIndicators; i++) {
689 struct xkb_indicator_map *map = &keymap->indicators->maps[i];
690 if (map->flags == 0 && map->which_groups == 0 &&
691 map->groups == 0 && map->which_mods == 0 &&
692 map->mods.real_mods == 0 && map->mods.vmods == 0 &&
695 write_indicator_map(keymap, buf, size, offset, i);
698 write_buf(keymap, buf, size, offset, "\t};\n\n");
704 write_keysyms(struct xkb_keymap *keymap, char **buf, size_t *size,
705 size_t *offset, xkb_keycode_t key, unsigned int group)
707 const xkb_keysym_t *syms;
709 #define OUT_BUF_LEN 128
710 char out_buf[OUT_BUF_LEN];
712 for (level = 0; level < XkbKeyGroupWidth(keymap, key, group); level++) {
714 write_buf(keymap, buf, size, offset, ", ");
715 num_syms = xkb_key_get_syms_by_level(keymap, key, group, level,
718 write_buf(keymap, buf, size, offset, "%15s", "NoSymbol");
720 else if (num_syms == 1) {
721 xkb_keysym_get_name(syms[0], out_buf, OUT_BUF_LEN);
722 write_buf(keymap, buf, size, offset, "%15s", out_buf);
726 write_buf(keymap, buf, size, offset, "{ ");
727 for (s = 0; s < num_syms; s++) {
729 write_buf(keymap, buf, size, offset, ", ");
730 xkb_keysym_get_name(syms[s], out_buf, OUT_BUF_LEN);
731 write_buf(keymap, buf, size, offset, "%15s", out_buf);
733 write_buf(keymap, buf, size, offset, " }");
742 write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
745 struct xkb_client_map *map = keymap->map;
746 struct xkb_server_map *srv = keymap->server;
751 write_buf(keymap, buf, size, offset, "\txkb_symbols {\n\n");
753 for (tmp = group = 0; group < XkbNumKbdGroups; group++) {
754 if (!keymap->names->groups[group])
756 write_buf(keymap, buf, size, offset,
757 "\t\tname[group%d]=\"%s\";\n", group + 1,
758 keymap->names->groups[group]);
762 write_buf(keymap, buf, size, offset, "\n");
764 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
767 if (xkb_key_num_groups(keymap, key) == 0)
769 if (XkbcFindKeycodeByName(keymap,
770 darray_item(keymap->names->keys, key).name,
774 write_buf(keymap, buf, size, offset, "\t\tkey %6s {",
775 XkbcKeyNameText(darray_item(keymap->names->keys, key).name));
777 if ((srv->explicit[key] & XkbExplicitKeyTypesMask)) {
778 bool multi_type = false;
779 int type = XkbKeyTypeIndex(keymap, key, 0);
783 for (group = 0; group < xkb_key_num_groups(keymap, key); group++) {
784 if (XkbKeyTypeIndex(keymap, key, group) != type) {
791 group < xkb_key_num_groups(keymap, key);
793 if (!(srv->explicit[key] & (1 << group)))
795 type = XkbKeyTypeIndex(keymap, key, group);
796 write_buf(keymap, buf, size, offset,
797 "\n\t\t\ttype[Group%d]= \"%s\",",
799 darray_item(map->types, type).name);
803 write_buf(keymap, buf, size, offset,
804 "\n\t\t\ttype= \"%s\",",
805 darray_item(map->types, type).name);
808 if (keymap->ctrls && (srv->explicit[key] & XkbExplicitAutoRepeatMask)) {
809 if (keymap->ctrls->per_key_repeat[key / 8] & (1 << (key % 8)))
810 write_buf(keymap, buf, size, offset,
811 "\n\t\t\trepeat= Yes,");
813 write_buf(keymap, buf, size, offset,
814 "\n\t\t\trepeat= No,");
817 if (keymap->server->vmodmap[key] &&
818 (srv->explicit[key] & XkbExplicitVModMapMask)) {
819 write_buf(keymap, buf, size, offset, "\n\t\t\tvirtualMods= %s,",
820 get_mod_mask_text(keymap, 0, keymap->server->vmodmap[key]));
824 switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(keymap, key))) {
825 case XkbClampIntoRange:
826 write_buf(keymap, buf, size, offset, "\n\t\t\tgroupsClamp,");
828 case XkbRedirectIntoRange:
829 write_buf(keymap, buf, size, offset,
830 "\n\t\t\tgroupsRedirect= Group%d,",
831 XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(keymap, key)) + 1);
835 if (srv->explicit == NULL ||
836 (srv->explicit[key] & XkbExplicitInterpretMask))
837 showActions = XkbKeyHasActions(keymap, key);
841 if (xkb_key_num_groups(keymap, key) > 1 || showActions)
845 write_buf(keymap, buf, size, offset, "\t[ ");
846 if (!write_keysyms(keymap, buf, size, offset, key, 0))
848 write_buf(keymap, buf, size, offset, " ] };\n");
851 union xkb_action *acts;
854 acts = XkbKeyActionsPtr(keymap, key);
855 for (group = 0; group < xkb_key_num_groups(keymap, key); group++) {
857 write_buf(keymap, buf, size, offset, ",");
858 write_buf(keymap, buf, size, offset,
859 "\n\t\t\tsymbols[Group%d]= [ ", group + 1);
860 if (!write_keysyms(keymap, buf, size, offset, key, group))
862 write_buf(keymap, buf, size, offset, " ]");
864 write_buf(keymap, buf, size, offset,
865 ",\n\t\t\tactions[Group%d]= [ ", group + 1);
867 level < XkbKeyGroupWidth(keymap, key, group);
870 write_buf(keymap, buf, size, offset, ", ");
871 write_action(keymap, buf, size, offset, &acts[level],
874 write_buf(keymap, buf, size, offset, " ]");
875 acts += XkbKeyGroupsWidth(keymap, key);
878 write_buf(keymap, buf, size, offset, "\n\t\t};\n");
881 if (map && map->modmap) {
882 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
886 if (map->modmap[key] == 0)
889 for (mod = 0; mod < XkbNumModifiers; mod++) {
890 if (!(map->modmap[key] & (1 << mod)))
893 memcpy(name, darray_item(keymap->names->keys, key).name, 4);
896 write_buf(keymap, buf, size, offset,
897 "\t\tmodifier_map %s { <%s> };\n",
898 get_mod_index_text(mod), name);
903 write_buf(keymap, buf, size, offset, "\t};\n\n");
908 xkb_map_get_as_string(struct xkb_keymap *keymap)
914 check_write_buf(keymap, &ret, &size, &offset, "xkb_keymap {\n");
917 if (!write_keycodes(keymap, &ret, &size, &offset))
919 if (!write_types(keymap, &ret, &size, &offset))
921 if (!write_compat(keymap, &ret, &size, &offset))
923 if (!write_symbols(keymap, &ret, &size, &offset))
925 check_write_buf(keymap, &ret, &size, &offset, "};\n");