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 if (action->any.type == XkbSA_NoAction)
487 switch (action->any.type) {
491 case XkbSA_LatchMods:
497 if (action->mods.flags & XkbSA_UseModMapMods)
500 args = get_mod_mask_text(keymap, action->mods.real_mods,
502 write_buf(keymap, buf, size, offset, "%s%s(modifiers=%s%s%s)%s",
504 (action->any.type != XkbSA_LockGroup &&
505 action->mods.flags & XkbSA_ClearLocks) ? ",clearLocks" : "",
506 (action->any.type != XkbSA_LockGroup &&
507 action->mods.flags & XkbSA_LatchToLock) ? ",latchToLock" : "",
513 case XkbSA_LatchGroup:
516 case XkbSA_LockGroup:
519 write_buf(keymap, buf, size, offset, "%s%s(group=%s%d%s%s)%s",
521 (!(action->group.flags & XkbSA_GroupAbsolute) &&
522 action->group.group > 0) ? "+" : "",
523 (action->group.flags & XkbSA_GroupAbsolute) ?
524 action->group.group + 1 : action->group.group,
525 (action->any.type != XkbSA_LockGroup &&
526 action->group.flags & XkbSA_ClearLocks) ? ",clearLocks" : "",
527 (action->any.type != XkbSA_LockGroup &&
528 action->group.flags & XkbSA_LatchToLock) ? ",latchToLock" : "",
531 case XkbSA_Terminate:
532 write_buf(keymap, buf, size, offset, "%sTerminate()%s", prefix, suffix);
535 write_buf(keymap, buf, size, offset, "%sMovePtr(x=%s%d,y=%s%d%s)%s",
537 (!(action->ptr.flags & XkbSA_MoveAbsoluteX) &&
538 action->ptr.x >= 0) ? "+" : "",
540 (!(action->ptr.flags & XkbSA_MoveAbsoluteY) &&
541 action->ptr.y >= 0) ? "+" : "",
543 (action->ptr.flags & XkbSA_NoAcceleration) ? ",!accel" : "",
549 case XkbSA_LockPtrBtn:
552 switch (action->btn.flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
553 case XkbSA_LockNoUnlock:
554 args = ",affect=lock";
556 case XkbSA_LockNoLock:
557 args = ",affect=unlock";
559 case XkbSA_LockNoLock | XkbSA_LockNoUnlock:
560 args = ",affect=neither";
563 args = ",affect=both";
570 write_buf(keymap, buf, size, offset, "%s%s(button=", prefix, type);
571 if (action->btn.button > 0 && action->btn.button <= 5)
572 write_buf(keymap, buf, size, offset, "%d", action->btn.button);
574 write_buf(keymap, buf, size, offset, "default");
575 if (action->btn.count)
576 write_buf(keymap, buf, size, offset, ",count=%d",
579 write_buf(keymap, buf, size, offset, "%s", args);
580 write_buf(keymap, buf, size, offset, ")%s", suffix);
582 case XkbSA_SetPtrDflt:
583 write_buf(keymap, buf, size, offset, "%sSetPtrDflt(", prefix);
584 if (action->dflt.affect == XkbSA_AffectDfltBtn)
585 write_buf(keymap, buf, size, offset, "affect=button,button=%s%d",
586 (!(action->dflt.flags & XkbSA_DfltBtnAbsolute) &&
587 action->dflt.value >= 0) ? "+" : "",
589 write_buf(keymap, buf, size, offset, ")%s", suffix);
591 case XkbSA_SwitchScreen:
592 write_buf(keymap, buf, size, offset,
593 "%sSwitchScreen(screen=%s%d,%ssame)%s", prefix,
594 (!(action->screen.flags & XkbSA_SwitchAbsolute) &&
595 action->screen.screen >= 0) ? "+" : "",
596 action->screen.screen,
597 (action->screen.flags & XkbSA_SwitchApplication) ? "!" : "",
600 /* Deprecated actions below here */
601 case XkbSA_SetControls:
603 type = "SetControls";
604 case XkbSA_LockControls:
606 type = "LockControls";
607 write_buf(keymap, buf, size, offset, "%s%s(controls=%s)%s",
608 prefix, type, get_control_mask_text(action->ctrls.ctrls),
612 case XkbSA_ActionMessage:
613 case XkbSA_RedirectKey:
614 case XkbSA_DeviceBtn:
615 case XkbSA_LockDeviceBtn:
617 write_buf(keymap, buf, size, offset, "%sNoAction()%s", prefix, suffix);
619 case XkbSA_XFree86Private:
621 write_buf(keymap, buf, size, offset,
622 "%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",
623 prefix, action->any.type, action->any.data[0],
624 action->any.data[1], action->any.data[2],
625 action->any.data[3], action->any.data[4],
626 action->any.data[5], action->any.data[6], suffix);
634 write_compat(struct xkb_keymap *keymap, char **buf, size_t *size,
638 struct xkb_sym_interpret *interp;
640 write_buf(keymap, buf, size, offset, "\txkb_compatibility {\n\n");
642 write_vmods(keymap, buf, size, offset);
644 write_buf(keymap, buf, size, offset, "\t\tinterpret.useModMapMods= AnyLevel;\n");
645 write_buf(keymap, buf, size, offset, "\t\tinterpret.repeat= false;\n");
646 write_buf(keymap, buf, size, offset, "\t\tinterpret.locking= false;\n");
648 for (i = 0; i < darray_size(keymap->compat->sym_interpret); i++) {
649 char keysym_name[64];
650 interp = &darray_item(keymap->compat->sym_interpret, i);
652 if (interp->sym == XKB_KEY_NoSymbol)
653 sprintf(keysym_name, "Any");
655 xkb_keysym_get_name(interp->sym, keysym_name, 64);
657 write_buf(keymap, buf, size, offset, "\t\tinterpret %s+%s(%s) {\n",
659 get_interp_match_text(interp->match),
660 get_mod_mask_text(keymap, interp->mods, 0));
662 if (interp->virtual_mod != XkbNoModifier) {
663 write_buf(keymap, buf, size, offset, "\t\t\tvirtualModifier= %s;\n",
664 keymap->names->vmods[interp->virtual_mod]);
667 if (interp->match & XkbSI_LevelOneOnly)
668 write_buf(keymap, buf, size, offset, "\t\t\tuseModMapMods=level1;\n");
669 if (interp->flags & XkbSI_LockingKey)
670 write_buf(keymap, buf, size, offset, "\t\t\tlocking= true;\n");
671 if (interp->flags & XkbSI_AutoRepeat)
672 write_buf(keymap, buf, size, offset, "\t\t\trepeat= true;\n");
674 write_action(keymap, buf, size, offset, &interp->act,
675 "\t\t\taction= ", ";\n");
676 write_buf(keymap, buf, size, offset, "\t\t};\n");
679 for (i = 0; i < XkbNumKbdGroups; i++) {
682 gc = &keymap->compat->groups[i];
683 if (gc->real_mods == 0 && gc->vmods ==0)
685 write_buf(keymap, buf, size, offset,
686 "\t\tgroup %d = %s;\n", i + 1,
687 get_mod_mask_text(keymap, gc->real_mods, gc->vmods));
690 for (i = 0; i < XkbNumIndicators; i++) {
691 struct xkb_indicator_map *map = &keymap->indicators->maps[i];
692 if (map->flags == 0 && map->which_groups == 0 &&
693 map->groups == 0 && map->which_mods == 0 &&
694 map->mods.real_mods == 0 && map->mods.vmods == 0 &&
697 write_indicator_map(keymap, buf, size, offset, i);
700 write_buf(keymap, buf, size, offset, "\t};\n\n");
706 write_keysyms(struct xkb_keymap *keymap, char **buf, size_t *size,
707 size_t *offset, xkb_keycode_t key, unsigned int group)
709 const xkb_keysym_t *syms;
711 #define OUT_BUF_LEN 128
712 char out_buf[OUT_BUF_LEN];
714 for (level = 0; level < XkbKeyGroupWidth(keymap, key, group); level++) {
716 write_buf(keymap, buf, size, offset, ", ");
717 num_syms = xkb_key_get_syms_by_level(keymap, key, group, level,
720 write_buf(keymap, buf, size, offset, "%15s", "NoSymbol");
722 else if (num_syms == 1) {
723 xkb_keysym_get_name(syms[0], out_buf, OUT_BUF_LEN);
724 write_buf(keymap, buf, size, offset, "%15s", out_buf);
728 write_buf(keymap, buf, size, offset, "{ ");
729 for (s = 0; s < num_syms; s++) {
731 write_buf(keymap, buf, size, offset, ", ");
732 xkb_keysym_get_name(syms[s], out_buf, OUT_BUF_LEN);
733 write_buf(keymap, buf, size, offset, "%15s", out_buf);
735 write_buf(keymap, buf, size, offset, " }");
744 write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
747 struct xkb_client_map *map = keymap->map;
748 struct xkb_server_map *srv = keymap->server;
753 write_buf(keymap, buf, size, offset, "\txkb_symbols {\n\n");
755 for (tmp = group = 0; group < XkbNumKbdGroups; group++) {
756 if (!keymap->names->groups[group])
758 write_buf(keymap, buf, size, offset,
759 "\t\tname[group%d]=\"%s\";\n", group + 1,
760 keymap->names->groups[group]);
764 write_buf(keymap, buf, size, offset, "\n");
766 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
769 if (xkb_key_num_groups(keymap, key) == 0)
771 if (XkbcFindKeycodeByName(keymap,
772 darray_item(keymap->names->keys, key).name,
776 write_buf(keymap, buf, size, offset, "\t\tkey %6s {",
777 XkbcKeyNameText(darray_item(keymap->names->keys, key).name));
779 if ((srv->explicit[key] & XkbExplicitKeyTypesMask)) {
780 bool multi_type = false;
781 int type = XkbKeyTypeIndex(keymap, key, 0);
785 for (group = 0; group < xkb_key_num_groups(keymap, key); group++) {
786 if (XkbKeyTypeIndex(keymap, key, group) != type) {
793 group < xkb_key_num_groups(keymap, key);
795 if (!(srv->explicit[key] & (1 << group)))
797 type = XkbKeyTypeIndex(keymap, key, group);
798 write_buf(keymap, buf, size, offset,
799 "\n\t\t\ttype[Group%d]= \"%s\",",
801 darray_item(map->types, type).name);
805 write_buf(keymap, buf, size, offset,
806 "\n\t\t\ttype= \"%s\",",
807 darray_item(map->types, type).name);
810 if (keymap->ctrls && (srv->explicit[key] & XkbExplicitAutoRepeatMask)) {
811 if (keymap->ctrls->per_key_repeat[key / 8] & (1 << (key % 8)))
812 write_buf(keymap, buf, size, offset,
813 "\n\t\t\trepeat= Yes,");
815 write_buf(keymap, buf, size, offset,
816 "\n\t\t\trepeat= No,");
819 if (keymap->server->vmodmap[key] &&
820 (srv->explicit[key] & XkbExplicitVModMapMask)) {
821 write_buf(keymap, buf, size, offset, "\n\t\t\tvirtualMods= %s,",
822 get_mod_mask_text(keymap, 0, keymap->server->vmodmap[key]));
826 switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(keymap, key))) {
827 case XkbClampIntoRange:
828 write_buf(keymap, buf, size, offset, "\n\t\t\tgroupsClamp,");
830 case XkbRedirectIntoRange:
831 write_buf(keymap, buf, size, offset,
832 "\n\t\t\tgroupsRedirect= Group%d,",
833 XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(keymap, key)) + 1);
837 if (srv->explicit == NULL ||
838 (srv->explicit[key] & XkbExplicitInterpretMask))
839 showActions = XkbKeyHasActions(keymap, key);
843 if (xkb_key_num_groups(keymap, key) > 1 || showActions)
847 write_buf(keymap, buf, size, offset, "\t[ ");
848 if (!write_keysyms(keymap, buf, size, offset, key, 0))
850 write_buf(keymap, buf, size, offset, " ] };\n");
853 union xkb_action *acts;
856 acts = XkbKeyActionsPtr(keymap, key);
857 for (group = 0; group < xkb_key_num_groups(keymap, key); group++) {
859 write_buf(keymap, buf, size, offset, ",");
860 write_buf(keymap, buf, size, offset,
861 "\n\t\t\tsymbols[Group%d]= [ ", group + 1);
862 if (!write_keysyms(keymap, buf, size, offset, key, group))
864 write_buf(keymap, buf, size, offset, " ]");
866 write_buf(keymap, buf, size, offset,
867 ",\n\t\t\tactions[Group%d]= [ ", group + 1);
869 level < XkbKeyGroupWidth(keymap, key, group);
872 write_buf(keymap, buf, size, offset, ", ");
873 write_action(keymap, buf, size, offset, &acts[level],
876 write_buf(keymap, buf, size, offset, " ]");
877 acts += XkbKeyGroupsWidth(keymap, key);
880 write_buf(keymap, buf, size, offset, "\n\t\t};\n");
883 if (map && map->modmap) {
884 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
888 if (map->modmap[key] == 0)
891 for (mod = 0; mod < XkbNumModifiers; mod++) {
892 if (!(map->modmap[key] & (1 << mod)))
895 memcpy(name, darray_item(keymap->names->keys, key).name, 4);
898 write_buf(keymap, buf, size, offset,
899 "\t\tmodifier_map %s { <%s> };\n",
900 get_mod_index_text(mod), name);
905 write_buf(keymap, buf, size, offset, "\t};\n\n");
910 xkb_map_get_as_string(struct xkb_keymap *keymap)
916 check_write_buf(keymap, &ret, &size, &offset, "xkb_keymap {\n");
919 if (!write_keycodes(keymap, &ret, &size, &offset))
921 if (!write_types(keymap, &ret, &size, &offset))
923 if (!write_compat(keymap, &ret, &size, &offset))
925 if (!write_symbols(keymap, &ret, &size, &offset))
927 check_write_buf(keymap, &ret, &size, &offset, "};\n");