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 %zu bytes for keymap\n", \
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 if (keymap->names->keycodes)
315 write_buf(keymap, buf, size, offset, "\txkb_keycodes \"%s\" {\n",
316 keymap->names->keycodes);
318 write_buf(keymap, buf, size, offset, "\txkb_keycodes {\n");
320 write_buf(keymap, buf, size, offset, "\t\tminimum = %d;\n",
321 keymap->min_key_code);
322 write_buf(keymap, buf, size, offset, "\t\tmaximum = %d;\n",
323 keymap->max_key_code);
325 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
326 if (darray_item(keymap->names->keys, key).name[0] == '\0')
329 write_buf(keymap, buf, size, offset, "\t\t%6s = %d;\n",
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 darray_foreach(alias, keymap->names->key_aliases)
343 write_buf(keymap, buf, size, offset, "\t\talias %6s = %6s;\n",
344 XkbcKeyNameText(alias->alias),
345 XkbcKeyNameText(alias->real));
347 write_buf(keymap, buf, size, offset, "\t};\n\n");
352 write_types(struct xkb_keymap *keymap, char **buf, size_t *size,
356 struct xkb_key_type *type;
358 if (keymap->names->keytypes)
359 write_buf(keymap, buf, size, offset, "\txkb_types \"%s\" {\n\n",
360 keymap->names->keytypes);
362 write_buf(keymap, buf, size, offset, "\txkb_types {\n\n");
364 write_vmods(keymap, buf, size, offset);
366 darray_foreach(type, keymap->map->types) {
367 write_buf(keymap, buf, size, offset, "\t\ttype \"%s\" {\n",
369 write_buf(keymap, buf, size, offset, "\t\t\tmodifiers= %s;\n",
370 get_mod_mask_text(keymap, type->mods.real_mods,
373 for (n = 0; n < darray_size(type->map); n++) {
374 struct xkb_kt_map_entry *entry = &darray_item(type->map, n);
377 str = get_mod_mask_text(keymap, entry->mods.real_mods,
379 write_buf(keymap, buf, size, offset, "\t\t\tmap[%s]= Level%d;\n",
380 str, entry->level + 1);
382 if (!type->preserve || (!type->preserve[n].real_mods &&
383 !type->preserve[n].vmods))
385 write_buf(keymap, buf, size, offset, "\t\t\tpreserve[%s]= ", str);
386 write_buf(keymap, buf, size, offset, "%s;\n",
387 get_mod_mask_text(keymap, type->preserve[n].real_mods,
388 type->preserve[n].vmods));
391 if (type->level_names) {
392 for (n = 0; n < type->num_levels; n++) {
393 if (!type->level_names[n])
395 write_buf(keymap, buf, size, offset,
396 "\t\t\tlevel_name[Level%d]= \"%s\";\n", n + 1,
397 type->level_names[n]);
400 write_buf(keymap, buf, size, offset, "\t\t};\n");
403 write_buf(keymap, buf, size, offset, "\t};\n\n");
408 write_indicator_map(struct xkb_keymap *keymap, char **buf, size_t *size,
409 size_t *offset, int num)
411 struct xkb_indicator_map *led = &keymap->indicators->maps[num];
413 write_buf(keymap, buf, size, offset, "\t\tindicator \"%s\" {\n",
414 keymap->names->indicators[num]);
416 if (led->which_groups) {
417 if (led->which_groups != XkbIM_UseEffective) {
418 write_buf(keymap, buf, size, offset, "\t\t\twhichGroupState= %s;\n",
419 get_indicator_state_text(led->which_groups));
421 write_buf(keymap, buf, size, offset, "\t\t\tgroups= 0x%02x;\n",
425 if (led->which_mods) {
426 if (led->which_mods != XkbIM_UseEffective) {
427 write_buf(keymap, buf, size, offset, "\t\t\twhichModState= %s;\n",
428 get_indicator_state_text(led->which_mods));
430 write_buf(keymap, buf, size, offset, "\t\t\tmodifiers= %s;\n",
431 get_mod_mask_text(keymap, led->mods.real_mods,
436 write_buf(keymap, buf, size, offset, "\t\t\tcontrols= %s;\n",
437 get_control_mask_text(led->ctrls));
440 write_buf(keymap, buf, size, offset, "\t\t};\n");
445 get_interp_match_text(uint8_t type)
449 switch (type & XkbSI_OpMask) {
451 sprintf(ret, "NoneOf");
453 case XkbSI_AnyOfOrNone:
454 sprintf(ret, "AnyOfOrNone");
457 sprintf(ret, "AnyOf");
460 sprintf(ret, "AllOf");
463 sprintf(ret, "Exactly");
466 sprintf(ret, "0x%x", type & XkbSI_OpMask);
474 write_action(struct xkb_keymap *keymap, char **buf, size_t *size,
475 size_t *offset, union xkb_action *action, const char *prefix,
478 const char *type = NULL;
479 const char *args = NULL;
486 switch (action->any.type) {
490 case XkbSA_LatchMods:
496 if (action->mods.flags & XkbSA_UseModMapMods)
499 args = get_mod_mask_text(keymap, action->mods.real_mods,
501 write_buf(keymap, buf, size, offset, "%s%s(modifiers=%s%s%s)%s",
503 (action->any.type != XkbSA_LockGroup &&
504 action->mods.flags & XkbSA_ClearLocks) ? ",clearLocks" : "",
505 (action->any.type != XkbSA_LockGroup &&
506 action->mods.flags & XkbSA_LatchToLock) ? ",latchToLock" : "",
512 case XkbSA_LatchGroup:
515 case XkbSA_LockGroup:
518 write_buf(keymap, buf, size, offset, "%s%s(group=%s%d%s%s)%s",
520 (!(action->group.flags & XkbSA_GroupAbsolute) &&
521 action->group.group > 0) ? "+" : "",
522 (action->group.flags & XkbSA_GroupAbsolute) ?
523 action->group.group + 1 : action->group.group,
524 (action->any.type != XkbSA_LockGroup &&
525 action->group.flags & XkbSA_ClearLocks) ? ",clearLocks" : "",
526 (action->any.type != XkbSA_LockGroup &&
527 action->group.flags & XkbSA_LatchToLock) ? ",latchToLock" : "",
530 case XkbSA_Terminate:
531 write_buf(keymap, buf, size, offset, "%sTerminate()%s", prefix, suffix);
534 write_buf(keymap, buf, size, offset, "%sMovePtr(x=%s%d,y=%s%d%s)%s",
536 (!(action->ptr.flags & XkbSA_MoveAbsoluteX) &&
537 action->ptr.x >= 0) ? "+" : "",
539 (!(action->ptr.flags & XkbSA_MoveAbsoluteY) &&
540 action->ptr.y >= 0) ? "+" : "",
542 (action->ptr.flags & XkbSA_NoAcceleration) ? ",!accel" : "",
548 case XkbSA_LockPtrBtn:
551 switch (action->btn.flags & (XkbSA_LockNoUnlock | XkbSA_LockNoLock)) {
552 case XkbSA_LockNoUnlock:
553 args = ",affect=lock";
555 case XkbSA_LockNoLock:
556 args = ",affect=unlock";
558 case XkbSA_LockNoLock | XkbSA_LockNoUnlock:
559 args = ",affect=neither";
562 args = ",affect=both";
569 write_buf(keymap, buf, size, offset, "%s%s(button=", prefix, type);
570 if (action->btn.button > 0 && action->btn.button <= 5)
571 write_buf(keymap, buf, size, offset, "%d", action->btn.button);
573 write_buf(keymap, buf, size, offset, "default");
574 if (action->btn.count)
575 write_buf(keymap, buf, size, offset, ",count=%d",
578 write_buf(keymap, buf, size, offset, "%s", args);
579 write_buf(keymap, buf, size, offset, ")%s", suffix);
581 case XkbSA_SetPtrDflt:
582 write_buf(keymap, buf, size, offset, "%sSetPtrDflt(", prefix);
583 if (action->dflt.affect == XkbSA_AffectDfltBtn)
584 write_buf(keymap, buf, size, offset, "affect=button,button=%s%d",
585 (!(action->dflt.flags & XkbSA_DfltBtnAbsolute) &&
586 action->dflt.value >= 0) ? "+" : "",
588 write_buf(keymap, buf, size, offset, ")%s", suffix);
590 case XkbSA_SwitchScreen:
591 write_buf(keymap, buf, size, offset,
592 "%sSwitchScreen(screen=%s%d,%ssame)%s", prefix,
593 (!(action->screen.flags & XkbSA_SwitchAbsolute) &&
594 action->screen.screen >= 0) ? "+" : "",
595 action->screen.screen,
596 (action->screen.flags & XkbSA_SwitchApplication) ? "!" : "",
599 /* Deprecated actions below here */
600 case XkbSA_SetControls:
602 type = "SetControls";
603 case XkbSA_LockControls:
605 type = "LockControls";
606 write_buf(keymap, buf, size, offset, "%s%s(controls=%s)%s",
607 prefix, type, get_control_mask_text(action->ctrls.ctrls),
611 case XkbSA_ActionMessage:
612 case XkbSA_RedirectKey:
613 case XkbSA_DeviceBtn:
614 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 if (keymap->names->compat)
641 write_buf(keymap, buf, size, offset, "\txkb_compatibility \"%s\" {\n\n",
642 keymap->names->compat);
644 write_buf(keymap, buf, size, offset, "\txkb_compatibility {\n\n");
646 write_vmods(keymap, buf, size, offset);
648 write_buf(keymap, buf, size, offset, "\t\tinterpret.useModMapMods= AnyLevel;\n");
649 write_buf(keymap, buf, size, offset, "\t\tinterpret.repeat= False;\n");
650 write_buf(keymap, buf, size, offset, "\t\tinterpret.locking= False;\n");
652 darray_foreach(interp, keymap->compat->sym_interpret) {
653 char keysym_name[64];
655 if (interp->sym == XKB_KEY_NoSymbol)
656 sprintf(keysym_name, "Any");
658 xkb_keysym_get_name(interp->sym, keysym_name, sizeof(keysym_name));
660 write_buf(keymap, buf, size, offset, "\t\tinterpret %s+%s(%s) {\n",
662 get_interp_match_text(interp->match),
663 get_mod_mask_text(keymap, interp->mods, 0));
665 if (interp->virtual_mod != XkbNoModifier) {
666 write_buf(keymap, buf, size, offset, "\t\t\tvirtualModifier= %s;\n",
667 keymap->names->vmods[interp->virtual_mod]);
670 if (interp->match & XkbSI_LevelOneOnly)
671 write_buf(keymap, buf, size, offset, "\t\t\tuseModMapMods=level1;\n");
672 if (interp->flags & XkbSI_LockingKey)
673 write_buf(keymap, buf, size, offset, "\t\t\tlocking= True;\n");
674 if (interp->flags & XkbSI_AutoRepeat)
675 write_buf(keymap, buf, size, offset, "\t\t\trepeat= True;\n");
677 write_action(keymap, buf, size, offset, &interp->act,
678 "\t\t\taction= ", ";\n");
679 write_buf(keymap, buf, size, offset, "\t\t};\n");
682 for (i = 0; i < XkbNumKbdGroups; i++) {
685 gc = &keymap->compat->groups[i];
686 if (gc->real_mods == 0 && gc->vmods ==0)
688 write_buf(keymap, buf, size, offset,
689 "\t\tgroup %d = %s;\n", i + 1,
690 get_mod_mask_text(keymap, gc->real_mods, gc->vmods));
693 for (i = 0; i < XkbNumIndicators; i++) {
694 struct xkb_indicator_map *map = &keymap->indicators->maps[i];
695 if (map->flags == 0 && map->which_groups == 0 &&
696 map->groups == 0 && map->which_mods == 0 &&
697 map->mods.real_mods == 0 && map->mods.vmods == 0 &&
700 write_indicator_map(keymap, buf, size, offset, i);
703 write_buf(keymap, buf, size, offset, "\t};\n\n");
709 write_keysyms(struct xkb_keymap *keymap, char **buf, size_t *size,
710 size_t *offset, xkb_keycode_t key, unsigned int group)
712 const xkb_keysym_t *syms;
714 #define OUT_BUF_LEN 128
715 char out_buf[OUT_BUF_LEN];
717 for (level = 0; level < XkbKeyGroupWidth(keymap, key, group); level++) {
719 write_buf(keymap, buf, size, offset, ", ");
720 num_syms = xkb_key_get_syms_by_level(keymap, key, group, level,
723 write_buf(keymap, buf, size, offset, "%15s", "NoSymbol");
725 else if (num_syms == 1) {
726 xkb_keysym_get_name(syms[0], out_buf, OUT_BUF_LEN);
727 write_buf(keymap, buf, size, offset, "%15s", out_buf);
731 write_buf(keymap, buf, size, offset, "{ ");
732 for (s = 0; s < num_syms; s++) {
734 write_buf(keymap, buf, size, offset, ", ");
735 xkb_keysym_get_name(syms[s], out_buf, OUT_BUF_LEN);
736 write_buf(keymap, buf, size, offset, "%15s", out_buf);
738 write_buf(keymap, buf, size, offset, " }");
747 write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
750 struct xkb_client_map *map = keymap->map;
751 struct xkb_server_map *srv = keymap->server;
756 if (keymap->names->symbols)
757 write_buf(keymap, buf, size, offset, "\txkb_symbols \"%s\" {\n\n",
758 keymap->names->symbols);
760 write_buf(keymap, buf, size, offset, "\txkb_symbols {\n\n");
762 for (tmp = group = 0; group < XkbNumKbdGroups; group++) {
763 if (!keymap->names->groups[group])
765 write_buf(keymap, buf, size, offset,
766 "\t\tname[group%d]=\"%s\";\n", group + 1,
767 keymap->names->groups[group]);
771 write_buf(keymap, buf, size, offset, "\n");
773 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
776 if (xkb_key_num_groups(keymap, key) == 0)
779 write_buf(keymap, buf, size, offset, "\t\tkey %6s {",
780 XkbcKeyNameText(darray_item(keymap->names->keys, key).name));
782 if ((srv->explicit[key] & XkbExplicitKeyTypesMask)) {
783 bool multi_type = false;
784 int type = XkbKeyTypeIndex(keymap, key, 0);
788 for (group = 0; group < xkb_key_num_groups(keymap, key); group++) {
789 if (XkbKeyTypeIndex(keymap, key, group) != type) {
796 group < xkb_key_num_groups(keymap, key);
798 if (!(srv->explicit[key] & (1 << group)))
800 type = XkbKeyTypeIndex(keymap, key, group);
801 write_buf(keymap, buf, size, offset,
802 "\n\t\t\ttype[group%d]= \"%s\",",
804 darray_item(map->types, type).name);
808 write_buf(keymap, buf, size, offset,
809 "\n\t\t\ttype= \"%s\",",
810 darray_item(map->types, type).name);
813 if (keymap->ctrls && (srv->explicit[key] & XkbExplicitAutoRepeatMask)) {
814 if (keymap->ctrls->per_key_repeat[key / 8] & (1 << (key % 8)))
815 write_buf(keymap, buf, size, offset,
816 "\n\t\t\trepeat= Yes,");
818 write_buf(keymap, buf, size, offset,
819 "\n\t\t\trepeat= No,");
822 if (keymap->server->vmodmap[key] &&
823 (srv->explicit[key] & XkbExplicitVModMapMask)) {
824 write_buf(keymap, buf, size, offset, "\n\t\t\tvirtualMods= %s,",
825 get_mod_mask_text(keymap, 0, keymap->server->vmodmap[key]));
829 switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(keymap, key))) {
830 case XkbClampIntoRange:
831 write_buf(keymap, buf, size, offset, "\n\t\t\tgroupsClamp,");
833 case XkbRedirectIntoRange:
834 write_buf(keymap, buf, size, offset,
835 "\n\t\t\tgroupsRedirect= Group%d,",
836 XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(keymap, key)) + 1);
840 if (srv->explicit == NULL ||
841 (srv->explicit[key] & XkbExplicitInterpretMask))
842 showActions = XkbKeyHasActions(keymap, key);
846 if (xkb_key_num_groups(keymap, key) > 1 || showActions)
850 write_buf(keymap, buf, size, offset, "\t[ ");
851 if (!write_keysyms(keymap, buf, size, offset, key, 0))
853 write_buf(keymap, buf, size, offset, " ] };\n");
856 union xkb_action *acts;
859 acts = XkbKeyActionsPtr(keymap, key);
860 for (group = 0; group < xkb_key_num_groups(keymap, key); group++) {
862 write_buf(keymap, buf, size, offset, ",");
863 write_buf(keymap, buf, size, offset,
864 "\n\t\t\tsymbols[Group%d]= [ ", group + 1);
865 if (!write_keysyms(keymap, buf, size, offset, key, group))
867 write_buf(keymap, buf, size, offset, " ]");
869 write_buf(keymap, buf, size, offset,
870 ",\n\t\t\tactions[Group%d]= [ ", group + 1);
872 level < XkbKeyGroupWidth(keymap, key, group);
875 write_buf(keymap, buf, size, offset, ", ");
876 write_action(keymap, buf, size, offset, &acts[level],
879 write_buf(keymap, buf, size, offset, " ]");
880 acts += XkbKeyGroupsWidth(keymap, key);
883 write_buf(keymap, buf, size, offset, "\n\t\t};\n");
886 if (map && map->modmap) {
887 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
890 if (map->modmap[key] == 0)
893 for (mod = 0; mod < XkbNumModifiers; mod++) {
894 if (!(map->modmap[key] & (1 << mod)))
897 write_buf(keymap, buf, size, offset,
898 "\t\tmodifier_map %s { %s };\n",
899 get_mod_index_text(mod),
900 XkbcKeyNameText(darray_item(keymap->names->keys,
906 write_buf(keymap, buf, size, offset, "\t};\n\n");
911 xkb_map_get_as_string(struct xkb_keymap *keymap)
917 check_write_buf(keymap, &ret, &size, &offset, "xkb_keymap {\n");
920 if (!write_keycodes(keymap, &ret, &size, &offset))
922 if (!write_types(keymap, &ret, &size, &offset))
924 if (!write_compat(keymap, &ret, &size, &offset))
926 if (!write_symbols(keymap, &ret, &size, &offset))
928 check_write_buf(keymap, &ret, &size, &offset, "};\n");