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:
614 write_buf(keymap, buf, size, offset, "%sNoAction()%s", prefix, suffix);
616 case XkbSA_XFree86Private:
618 write_buf(keymap, buf, size, offset,
619 "%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",
620 prefix, action->any.type, action->any.data[0],
621 action->any.data[1], action->any.data[2],
622 action->any.data[3], action->any.data[4],
623 action->any.data[5], action->any.data[6], suffix);
631 write_compat(struct xkb_keymap *keymap, char **buf, size_t *size,
635 struct xkb_sym_interpret *interp;
637 write_buf(keymap, buf, size, offset, "\txkb_compatibility {\n\n");
639 write_vmods(keymap, buf, size, offset);
641 write_buf(keymap, buf, size, offset, "\t\tinterpret.useModMapMods= AnyLevel;\n");
642 write_buf(keymap, buf, size, offset, "\t\tinterpret.repeat= false;\n");
643 write_buf(keymap, buf, size, offset, "\t\tinterpret.locking= false;\n");
645 for (i = 0; i < darray_size(keymap->compat->sym_interpret); i++) {
646 char keysym_name[64];
647 interp = &darray_item(keymap->compat->sym_interpret, i);
649 if (interp->sym == XKB_KEY_NoSymbol)
650 sprintf(keysym_name, "Any");
652 xkb_keysym_get_name(interp->sym, keysym_name, 64);
654 write_buf(keymap, buf, size, offset, "\t\tinterpret %s+%s(%s) {\n",
656 get_interp_match_text(interp->match),
657 get_mod_mask_text(keymap, interp->mods, 0));
659 if (interp->virtual_mod != XkbNoModifier) {
660 write_buf(keymap, buf, size, offset, "\t\t\tvirtualModifier= %s;\n",
661 keymap->names->vmods[interp->virtual_mod]);
664 if (interp->match & XkbSI_LevelOneOnly)
665 write_buf(keymap, buf, size, offset, "\t\t\tuseModMapMods=level1;\n");
666 if (interp->flags & XkbSI_LockingKey)
667 write_buf(keymap, buf, size, offset, "\t\t\tlocking= true;\n");
668 if (interp->flags & XkbSI_AutoRepeat)
669 write_buf(keymap, buf, size, offset, "\t\t\trepeat= true;\n");
671 write_action(keymap, buf, size, offset, &interp->act,
672 "\t\t\taction= ", ";\n");
673 write_buf(keymap, buf, size, offset, "\t\t};\n");
676 for (i = 0; i < XkbNumKbdGroups; i++) {
679 gc = &keymap->compat->groups[i];
680 if (gc->real_mods == 0 && gc->vmods ==0)
682 write_buf(keymap, buf, size, offset,
683 "\t\tgroup %d = %s;\n", i + 1,
684 get_mod_mask_text(keymap, gc->real_mods, gc->vmods));
687 for (i = 0; i < XkbNumIndicators; i++) {
688 struct xkb_indicator_map *map = &keymap->indicators->maps[i];
689 if (map->flags == 0 && map->which_groups == 0 &&
690 map->groups == 0 && map->which_mods == 0 &&
691 map->mods.real_mods == 0 && map->mods.vmods == 0 &&
694 write_indicator_map(keymap, buf, size, offset, i);
697 write_buf(keymap, buf, size, offset, "\t};\n\n");
703 write_keysyms(struct xkb_keymap *keymap, char **buf, size_t *size,
704 size_t *offset, xkb_keycode_t key, unsigned int group)
706 const xkb_keysym_t *syms;
708 #define OUT_BUF_LEN 128
709 char out_buf[OUT_BUF_LEN];
711 for (level = 0; level < XkbKeyGroupWidth(keymap, key, group); level++) {
713 write_buf(keymap, buf, size, offset, ", ");
714 num_syms = xkb_key_get_syms_by_level(keymap, key, group, level,
717 write_buf(keymap, buf, size, offset, "%15s", "NoSymbol");
719 else if (num_syms == 1) {
720 xkb_keysym_get_name(syms[0], out_buf, OUT_BUF_LEN);
721 write_buf(keymap, buf, size, offset, "%15s", out_buf);
725 write_buf(keymap, buf, size, offset, "{ ");
726 for (s = 0; s < num_syms; s++) {
728 write_buf(keymap, buf, size, offset, ", ");
729 xkb_keysym_get_name(syms[s], out_buf, OUT_BUF_LEN);
730 write_buf(keymap, buf, size, offset, "%15s", out_buf);
732 write_buf(keymap, buf, size, offset, " }");
741 write_symbols(struct xkb_keymap *keymap, char **buf, size_t *size,
744 struct xkb_client_map *map = keymap->map;
745 struct xkb_server_map *srv = keymap->server;
750 write_buf(keymap, buf, size, offset, "\txkb_symbols {\n\n");
752 for (tmp = group = 0; group < XkbNumKbdGroups; group++) {
753 if (!keymap->names->groups[group])
755 write_buf(keymap, buf, size, offset,
756 "\t\tname[group%d]=\"%s\";\n", group + 1,
757 keymap->names->groups[group]);
761 write_buf(keymap, buf, size, offset, "\n");
763 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
766 if (xkb_key_num_groups(keymap, key) == 0)
768 if (XkbcFindKeycodeByName(keymap,
769 darray_item(keymap->names->keys, key).name,
773 write_buf(keymap, buf, size, offset, "\t\tkey %6s {",
774 XkbcKeyNameText(darray_item(keymap->names->keys, key).name));
776 if ((srv->explicit[key] & XkbExplicitKeyTypesMask)) {
777 bool multi_type = false;
778 int type = XkbKeyTypeIndex(keymap, key, 0);
782 for (group = 0; group < xkb_key_num_groups(keymap, key); group++) {
783 if (XkbKeyTypeIndex(keymap, key, group) != type) {
790 group < xkb_key_num_groups(keymap, key);
792 if (!(srv->explicit[key] & (1 << group)))
794 type = XkbKeyTypeIndex(keymap, key, group);
795 write_buf(keymap, buf, size, offset,
796 "\n\t\t\ttype[Group%d]= \"%s\",",
798 darray_item(map->types, type).name);
802 write_buf(keymap, buf, size, offset,
803 "\n\t\t\ttype= \"%s\",",
804 darray_item(map->types, type).name);
807 if (keymap->ctrls && (srv->explicit[key] & XkbExplicitAutoRepeatMask)) {
808 if (keymap->ctrls->per_key_repeat[key / 8] & (1 << (key % 8)))
809 write_buf(keymap, buf, size, offset,
810 "\n\t\t\trepeat= Yes,");
812 write_buf(keymap, buf, size, offset,
813 "\n\t\t\trepeat= No,");
816 if (keymap->server->vmodmap[key] &&
817 (srv->explicit[key] & XkbExplicitVModMapMask)) {
818 write_buf(keymap, buf, size, offset, "\n\t\t\tvirtualMods= %s,",
819 get_mod_mask_text(keymap, 0, keymap->server->vmodmap[key]));
823 switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(keymap, key))) {
824 case XkbClampIntoRange:
825 write_buf(keymap, buf, size, offset, "\n\t\t\tgroupsClamp,");
827 case XkbRedirectIntoRange:
828 write_buf(keymap, buf, size, offset,
829 "\n\t\t\tgroupsRedirect= Group%d,",
830 XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(keymap, key)) + 1);
834 if (srv->explicit == NULL ||
835 (srv->explicit[key] & XkbExplicitInterpretMask))
836 showActions = XkbKeyHasActions(keymap, key);
840 if (xkb_key_num_groups(keymap, key) > 1 || showActions)
844 write_buf(keymap, buf, size, offset, "\t[ ");
845 if (!write_keysyms(keymap, buf, size, offset, key, 0))
847 write_buf(keymap, buf, size, offset, " ] };\n");
850 union xkb_action *acts;
853 acts = XkbKeyActionsPtr(keymap, key);
854 for (group = 0; group < xkb_key_num_groups(keymap, key); group++) {
856 write_buf(keymap, buf, size, offset, ",");
857 write_buf(keymap, buf, size, offset,
858 "\n\t\t\tsymbols[Group%d]= [ ", group + 1);
859 if (!write_keysyms(keymap, buf, size, offset, key, group))
861 write_buf(keymap, buf, size, offset, " ]");
863 write_buf(keymap, buf, size, offset,
864 ",\n\t\t\tactions[Group%d]= [ ", group + 1);
866 level < XkbKeyGroupWidth(keymap, key, group);
869 write_buf(keymap, buf, size, offset, ", ");
870 write_action(keymap, buf, size, offset, &acts[level],
873 write_buf(keymap, buf, size, offset, " ]");
874 acts += XkbKeyGroupsWidth(keymap, key);
877 write_buf(keymap, buf, size, offset, "\n\t\t};\n");
880 if (map && map->modmap) {
881 for (key = keymap->min_key_code; key <= keymap->max_key_code; key++) {
885 if (map->modmap[key] == 0)
888 for (mod = 0; mod < XkbNumModifiers; mod++) {
889 if (!(map->modmap[key] & (1 << mod)))
892 memcpy(name, darray_item(keymap->names->keys, key).name, 4);
895 write_buf(keymap, buf, size, offset,
896 "\t\tmodifier_map %s { <%s> };\n",
897 get_mod_index_text(mod), name);
902 write_buf(keymap, buf, size, offset, "\t};\n\n");
907 xkb_map_get_as_string(struct xkb_keymap *keymap)
913 check_write_buf(keymap, &ret, &size, &offset, "xkb_keymap {\n");
916 if (!write_keycodes(keymap, &ret, &size, &offset))
918 if (!write_types(keymap, &ret, &size, &offset))
920 if (!write_compat(keymap, &ret, &size, &offset))
922 if (!write_symbols(keymap, &ret, &size, &offset))
924 check_write_buf(keymap, &ret, &size, &offset, "};\n");