Created
July 23, 2013 10:17
-
-
Save bluetech/6061368 to your computer and use it in GitHub Desktop.
get_map.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <err.h> | |
#include <stdbool.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <xcb/xcb.h> | |
#include <xcb/xkb.h> | |
#include <xkbcommon/xkbcommon.h> | |
static void cleanup_free_fn(void *p) { free(*(void **)p); } | |
#define _cleanup_free_ __attribute__((cleanup(cleanup_free_fn))) | |
struct ctx { | |
xcb_connection_t *conn; | |
}; | |
static void | |
setup_xkb(struct ctx *ctx) | |
{ | |
{ | |
const xcb_query_extension_reply_t *reply; | |
reply = xcb_get_extension_data(ctx->conn, &xcb_xkb_id); | |
if (!reply) | |
errx(1, "no xkb in x server"); | |
} | |
{ | |
xcb_xkb_use_extension_cookie_t cookie; | |
_cleanup_free_ xcb_xkb_use_extension_reply_t *reply = null; | |
cookie = xcb_xkb_use_extension(ctx->conn, | |
xcb_xkb_major_version, | |
xcb_xkb_minor_version); | |
reply = xcb_xkb_use_extension_reply(ctx->conn, cookie, null); | |
if (!reply) | |
errx(1, "couldn't use xkb extension"); | |
if (!reply->supported) | |
errx(1, "the xkb extension is not supported in x server"); | |
} | |
} | |
static const char * | |
get_atom_name(struct ctx *ctx, xcb_atom_t atom) | |
{ | |
_cleanup_free_ xcb_get_atom_name_reply_t *reply = null; | |
char *name; | |
int length; | |
static char buf[1024]; /* fixme */ | |
if (atom == 0) | |
return "<empty>"; | |
{ | |
xcb_get_atom_name_cookie_t cookie; | |
_cleanup_free_ xcb_generic_error_t *error = null; | |
cookie = xcb_get_atom_name(ctx->conn, atom); | |
reply = xcb_get_atom_name_reply(ctx->conn, cookie, &error); | |
if (!reply || error) | |
return "<invalid>"; | |
} | |
length = xcb_get_atom_name_name_length(reply); | |
name = xcb_get_atom_name_name(reply); | |
snprintf(buf, sizeof(buf), "%.*s", length, name); | |
return buf; | |
} | |
static const char * | |
get_keysym_name(xcb_keysym_t keysym) | |
{ | |
static char name[64]; | |
xkb_keysym_get_name(keysym, name, sizeof(name)); | |
return name; | |
} | |
#define all_components_mask \ | |
(xcb_xkb_map_part_key_types | \ | |
xcb_xkb_map_part_key_syms | \ | |
xcb_xkb_map_part_modifier_map | \ | |
xcb_xkb_map_part_explicit_components | \ | |
xcb_xkb_map_part_key_actions | \ | |
xcb_xkb_map_part_key_behaviors | \ | |
xcb_xkb_map_part_virtual_mods | \ | |
xcb_xkb_map_part_virtual_mod_map) | |
static void | |
get_map(struct ctx *ctx) | |
{ | |
_cleanup_free_ xcb_xkb_get_map_reply_t *reply = null; | |
{ | |
xcb_xkb_get_map_cookie_t cookie; | |
_cleanup_free_ xcb_generic_error_t *error = null; | |
/* send the xkbgetmap request. */ | |
cookie = xcb_xkb_get_map(ctx->conn, | |
xcb_xkb_id_use_core_kbd, | |
all_components_mask, | |
0, | |
0, | |
0, | |
0, | |
0, | |
0, | |
0, | |
0, | |
0, | |
0, | |
0, | |
0, | |
0, | |
0, | |
0, | |
0); | |
reply = xcb_xkb_get_map_reply(ctx->conn, cookie, &error); | |
if (!reply || error) | |
errx(1, "couldn't get get_map reply: error_code %d", error->error_code); | |
if ((reply->present & all_components_mask) != all_components_mask) | |
warnx("didn't get all components: want %x got %x", | |
all_components_mask, reply->present); | |
} | |
printf("minkeycode: %d\n", reply->minkeycode); | |
printf("maxkeycode: %d\n", reply->maxkeycode); | |
/* get the map itself, with all the details. */ | |
xcb_xkb_get_map_map_t map; | |
{ | |
void *buffer; | |
buffer = xcb_xkb_get_map_map(reply); | |
xcb_xkb_get_map_map_unpack(buffer, | |
reply->ntypes, | |
reply->nkeysyms, | |
reply->nkeyactions, | |
reply->totalactions, | |
reply->totalkeybehaviors, | |
reply->virtualmods, | |
reply->totalkeyexplicit, | |
reply->totalmodmapkeys, | |
reply->totalvmodmapkeys, | |
reply->present, | |
&map); | |
} | |
/* dump types. */ | |
{ | |
int length; | |
xcb_xkb_key_type_iterator_t iter; | |
printf("firsttype: %d\n", reply->firsttype); | |
printf("totaltype: %d\n", reply->totaltypes); | |
printf("ntypes: %d\n", reply->ntypes); | |
length = xcb_xkb_get_map_map_types_rtrn_length(reply, &map); | |
iter = xcb_xkb_get_map_map_types_rtrn_iterator(reply, &map); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_key_type_t *type = iter.data; | |
printf("type %d:\n", reply->firsttype + i); | |
printf("\tmods_mask: %d\n", type->mods_mask); | |
printf("\tmods_mods: %d\n", type->mods_mods); | |
printf("\tmods_vmods: %d\n", type->mods_vmods); | |
printf("\tnumlevels: %d\n", type->numlevels); | |
printf("\thaspreserve: %d\n", type->haspreserve); | |
/* dump type's entries. */ | |
{ | |
int length2; | |
xcb_xkb_kt_map_entry_iterator_t iter2; | |
length2 = xcb_xkb_key_type_map_length(type); | |
iter2 = xcb_xkb_key_type_map_iterator(type); | |
for (int j = 0; j < length2; j++) { | |
xcb_xkb_kt_map_entry_t *entry = iter2.data; | |
printf("\tentry %d:\n", j); | |
printf("\t\tactive: %d\n", entry->active); | |
printf("\t\tlevel: %d\n", entry->level); | |
printf("\t\tmods_mask: %d\n", entry->mods_mask); | |
printf("\t\tmods_mods: %d\n", entry->mods_mods); | |
printf("\t\tmods_vmods: %d\n", entry->mods_vmods); | |
xcb_xkb_kt_map_entry_next(&iter2); | |
} | |
} | |
/* dump type's preserve entries. */ | |
{ | |
int length2; | |
xcb_xkb_mod_def_iterator_t iter2; | |
length2 = xcb_xkb_key_type_preserve_length(type); | |
iter2 = xcb_xkb_key_type_preserve_iterator(type); | |
for (int j = 0; j < length2; j++) { | |
xcb_xkb_mod_def_t *preserve = iter2.data; | |
printf("\tpreserve %d:\n", j); | |
printf("\t\tmask: %d\n", preserve->mask); | |
printf("\t\trealmods: %d\n", preserve->realmods); | |
printf("\t\tvmods: %d\n", preserve->vmods); | |
xcb_xkb_mod_def_next(&iter2); | |
} | |
} | |
xcb_xkb_key_type_next(&iter); | |
} | |
} | |
/* dump key sym maps. */ | |
{ | |
int length; | |
xcb_xkb_key_sym_map_iterator_t iter; | |
printf("firstkeysym: %d\n", reply->firstkeysym); | |
printf("totalsyms: %d\n", reply->totalsyms); | |
printf("nkeysyms: %d\n", reply->nkeysyms); | |
length = xcb_xkb_get_map_map_syms_rtrn_length(reply, &map); | |
iter = xcb_xkb_get_map_map_syms_rtrn_iterator(reply, &map); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_key_sym_map_t *sym_map = iter.data; | |
printf("sym_map %d:\n", reply->firstkeysym + i); | |
/* todo: kt_index[4] */ | |
printf("\tgroupinfo: %d\n", sym_map->groupinfo); | |
printf("\twidth: %d\n", sym_map->width); | |
printf("\tnsyms: %d\n", sym_map->nsyms); | |
/* dump sym map's keysyms. */ | |
printf("\tkeysyms:\n"); | |
{ | |
int length2; | |
xcb_keysym_t *iter2; | |
length2 = xcb_xkb_key_sym_map_syms_length(sym_map); | |
iter2 = xcb_xkb_key_sym_map_syms(sym_map); | |
for (int j = 0; j < length2; j++) { | |
xcb_keysym_t keysym = *iter2; | |
printf("\t\t%s\n", get_keysym_name(keysym)); | |
iter2++; | |
} | |
} | |
xcb_xkb_key_sym_map_next(&iter); | |
} | |
} | |
/* dump key actions. */ | |
{ | |
printf("firstkeyaction: %d\n", reply->firstkeyaction); | |
printf("totalactions: %d\n", reply->totalactions); | |
printf("nkeyactions: %d\n", reply->nkeyactions); | |
/* dump number of actions bound to the keys. */ | |
{ | |
int length; | |
uint8_t *iter; | |
length = xcb_xkb_get_map_map_acts_rtrn_count_length(reply, &map); | |
iter = xcb_xkb_get_map_map_acts_rtrn_count(&map); | |
for (int i = 0 ; i < length; i++) { | |
uint8_t count = *iter; | |
printf("action count %d:\n", reply->firstkeyaction + i); | |
printf("\tcount: %d\n", count); | |
iter++; | |
} | |
} | |
/* dump the actions array. */ | |
{ | |
int length; | |
xcb_xkb_action_iterator_t iter; | |
length = xcb_xkb_get_map_map_acts_rtrn_acts_length(reply, &map); | |
iter = xcb_xkb_get_map_map_acts_rtrn_acts_iterator(reply, &map); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_action_t *action = iter.data; | |
/* todo: action union. */ | |
printf("action %d:\n", i); | |
printf("\ttype: %d\n", action->type); | |
xcb_xkb_action_next(&iter); | |
} | |
} | |
} | |
/* dump key behaviors. */ | |
{ | |
int length; | |
xcb_xkb_set_behavior_iterator_t iter; | |
printf("firstkeybehavior: %d\n", reply->firstkeybehavior); | |
printf("nkeybehaviors: %d\n", reply->nkeybehaviors); | |
printf("totalkeybehaviors: %d\n", reply->totalkeybehaviors); | |
length = xcb_xkb_get_map_map_behaviors_rtrn_length(reply, &map); | |
iter = xcb_xkb_get_map_map_behaviors_rtrn_iterator(reply, &map); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_set_behavior_t *set_behavior = iter.data; | |
xcb_xkb_behavior_t *behavior = &set_behavior->behavior; | |
printf("set_behavior %d:\n", reply->firstkeybehavior + i); | |
printf("\tkeycode: %d\n", set_behavior->keycode); | |
/* todo: behavior union. */ | |
printf("\tbehavior type: %d\n", behavior->type); | |
xcb_xkb_set_behavior_next(&iter); | |
} | |
} | |
/* dump virtual mods. */ | |
{ | |
int length; | |
uint8_t *iter; | |
printf("virtualmods: %x\n", reply->virtualmods); | |
length = xcb_xkb_get_map_map_vmods_rtrn_length(reply, &map); | |
iter = xcb_xkb_get_map_map_vmods_rtrn(&map); | |
printf("length: %d\n", length); | |
for (int i = 0; i < length; i++) { | |
uint8_t vmods = *iter; | |
printf("vmods %d:\n", i); | |
printf("\tmask: %x\n", vmods); | |
iter++; | |
} | |
} | |
/* dump key explicit masks. */ | |
{ | |
int length; | |
xcb_xkb_set_explicit_iterator_t iter; | |
printf("firstkeyexplicit: %d\n", reply->firstkeyexplicit); | |
printf("nkeyexplicit: %d\n", reply->nkeyexplicit); | |
printf("totalkeyexplicit: %d\n", reply->totalkeyexplicit); | |
length = xcb_xkb_get_map_map_explicit_rtrn_length(reply, &map); | |
iter = xcb_xkb_get_map_map_explicit_rtrn_iterator(reply, &map); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_set_explicit_t *set_explicit = iter.data; | |
printf("set_explicit %d:\n", i); | |
printf("\tkeycode: %d\n", set_explicit->keycode); | |
printf("\texplicit: %d\n", set_explicit->explicit); | |
xcb_xkb_set_explicit_next(&iter); | |
} | |
} | |
/* dump mod map keys. */ | |
{ | |
int length; | |
xcb_xkb_key_mod_map_iterator_t iter; | |
printf("firstmodmapkey: %d\n", reply->firstmodmapkey); | |
printf("nmodmapkeys: %d\n", reply->nmodmapkeys); | |
printf("totalmodmapkeys: %d\n", reply->totalmodmapkeys); | |
length = xcb_xkb_get_map_map_modmap_rtrn_length(reply, &map); | |
iter = xcb_xkb_get_map_map_modmap_rtrn_iterator(reply, &map); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_key_mod_map_t *key_mod_map = iter.data; | |
printf("key_mod_map %d:\n", i); | |
printf("\tkeycode: %d\n", key_mod_map->keycode); | |
printf("\tmods: %d\n", key_mod_map->mods); | |
xcb_xkb_key_mod_map_next(&iter); | |
} | |
} | |
/* dump key vmod map keys. */ | |
{ | |
int length; | |
xcb_xkb_key_v_mod_map_iterator_t iter; | |
printf("firstvmodmapkey: %d\n", reply->firstvmodmapkey); | |
printf("nvmodmapkeys: %d\n", reply->nvmodmapkeys); | |
printf("totalvmodmapkeys: %d\n", reply->totalvmodmapkeys); | |
length = xcb_xkb_get_map_map_vmodmap_rtrn_length(reply, &map); | |
iter = xcb_xkb_get_map_map_vmodmap_rtrn_iterator(reply, &map); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_key_v_mod_map_t *key_v_mod_map = iter.data; | |
printf("key_v_mod_map %d:\n", i); | |
printf("\tkeycode: %d\n", key_v_mod_map->keycode); | |
printf("\tvmods: %d\n", key_v_mod_map->vmods); | |
xcb_xkb_key_v_mod_map_next(&iter); | |
} | |
} | |
} | |
#define all_indicators 0xffffffff | |
static void | |
get_indicator_map(struct ctx *ctx) | |
{ | |
_cleanup_free_ xcb_xkb_get_indicator_map_reply_t *reply = null; | |
{ | |
_cleanup_free_ xcb_generic_error_t *error = null; | |
xcb_xkb_get_indicator_map_cookie_t cookie; | |
cookie = xcb_xkb_get_indicator_map(ctx->conn, | |
xcb_xkb_id_use_core_kbd, | |
all_indicators); | |
reply = xcb_xkb_get_indicator_map_reply(ctx->conn, cookie, &error); | |
if (!reply || error) | |
errx(1, "couldn't get get_indicator_map reply"); | |
} | |
assert(reply->which == all_indicators); | |
printf("which: %x\n", reply->which); | |
printf("realindicators: %x\n", reply->realindicators); | |
printf("nindicators: %d\n", reply->nindicators); | |
/* dump indicator maps. */ | |
{ | |
int length; | |
xcb_xkb_indicator_map_iterator_t iter; | |
length = xcb_xkb_get_indicator_map_maps_length(reply); | |
iter = xcb_xkb_get_indicator_map_maps_iterator(reply); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_indicator_map_t *indicator_map = iter.data; | |
printf("indicator_map %d:\n", i); | |
printf("\tflags: %d\n", indicator_map->flags); | |
printf("\twhichgroups: %d\n", indicator_map->whichgroups); | |
printf("\tgroups: %d\n", indicator_map->groups); | |
printf("\twhichmods: %d\n", indicator_map->whichmods); | |
printf("\tmods: %d\n", indicator_map->mods); | |
printf("\trealmods: %d\n", indicator_map->realmods); | |
printf("\tvmods: %d\n", indicator_map->vmods); | |
printf("\tctrls: %d\n", indicator_map->ctrls); | |
xcb_xkb_indicator_map_next(&iter); | |
} | |
} | |
} | |
#define all_groups 0xf | |
static void | |
get_compat_map(struct ctx *ctx) | |
{ | |
_cleanup_free_ xcb_xkb_get_compat_map_reply_t *reply = null; | |
{ | |
_cleanup_free_ xcb_generic_error_t *error = null; | |
xcb_xkb_get_compat_map_cookie_t cookie; | |
cookie = xcb_xkb_get_compat_map(ctx->conn, | |
xcb_xkb_id_use_core_kbd, | |
all_groups, | |
true, | |
0, | |
0); | |
reply = xcb_xkb_get_compat_map_reply(ctx->conn, cookie, &error); | |
if (!reply || error) | |
errx(1, "couldn't get reply for get_compat_map"); | |
} | |
printf("groupsrtrn: %#x\n", reply->groupsrtrn); | |
printf("firstsirtrn: %d\n", reply->firstsirtrn); | |
printf("nsirtrn: %d\n", reply->nsirtrn); | |
printf("ntotalsi: %d\n", reply->ntotalsi); | |
/* dump sym interprets. */ | |
{ | |
int length; | |
xcb_xkb_sym_interpret_iterator_t iter; | |
length = xcb_xkb_get_compat_map_si_rtrn_length(reply); | |
iter = xcb_xkb_get_compat_map_si_rtrn_iterator(reply); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_sym_interpret_t *sym_interpret = iter.data; | |
printf("sym_interpret %d\n", reply->firstsirtrn + i); | |
printf("\tsym: %s\n", get_keysym_name(sym_interpret->sym)); | |
printf("\tmods: %d\n", sym_interpret->mods); | |
printf("\tmatch: %d\n", sym_interpret->match); | |
printf("\tvirtualmod: %d\n", sym_interpret->virtualmod); | |
printf("\tflags: %d\n", sym_interpret->flags); | |
printf("\taction type: %d\n", sym_interpret->action.type); | |
/* todo: action fields */ | |
xcb_xkb_sym_interpret_next(&iter); | |
} | |
} | |
/* dump modmap definitons. */ | |
{ | |
int length; | |
xcb_xkb_mod_def_iterator_t iter; | |
length = xcb_xkb_get_compat_map_group_rtrn_length(reply); | |
iter = xcb_xkb_get_compat_map_group_rtrn_iterator(reply); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_mod_def_t *mod_def = iter.data; | |
printf("mod_def %d\n", i); | |
printf("\tmask: %d\n", mod_def->mask); | |
printf("\trealmods: %d\n", mod_def->realmods); | |
printf("\tvmods: %d\n", mod_def->vmods); | |
xcb_xkb_mod_def_next(&iter); | |
} | |
} | |
} | |
#define all_name_details \ | |
(xcb_xkb_name_detail_keycodes | \ | |
xcb_xkb_name_detail_geometry | \ | |
xcb_xkb_name_detail_symbols | \ | |
xcb_xkb_name_detail_phys_symbols | \ | |
xcb_xkb_name_detail_types | \ | |
xcb_xkb_name_detail_compat | \ | |
xcb_xkb_name_detail_key_type_names | \ | |
xcb_xkb_name_detail_kt_level_names | \ | |
xcb_xkb_name_detail_indicator_names | \ | |
xcb_xkb_name_detail_key_names | \ | |
xcb_xkb_name_detail_key_aliases | \ | |
xcb_xkb_name_detail_virtual_mod_names | \ | |
xcb_xkb_name_detail_group_names | \ | |
xcb_xkb_name_detail_rg_names) | |
static void | |
get_names(struct ctx *ctx) | |
{ | |
_cleanup_free_ xcb_xkb_get_names_reply_t *reply = null; | |
{ | |
_cleanup_free_ xcb_generic_error_t *error = null; | |
xcb_xkb_get_names_cookie_t cookie; | |
cookie = xcb_xkb_get_names(ctx->conn, | |
xcb_xkb_id_use_core_kbd, | |
all_name_details); | |
reply = xcb_xkb_get_names_reply(ctx->conn, cookie, &error); | |
if (!reply || error) | |
errx(1, "couldn't get reply for get_names"); | |
/* if ((reply->which & all_name_details) != all_name_details) */ | |
/* warnx("didn't get all name details: want %x got %x", */ | |
/* all_name_details, reply->which); */ | |
} | |
printf("which: %d\n", reply->which); | |
printf("minkeycode: %d\n", reply->minkeycode); | |
printf("maxkeycode: %d\n", reply->maxkeycode); | |
printf("ntypes: %d\n", reply->ntypes); | |
printf("groupnames: %d\n", reply->groupnames); | |
printf("virtualmods: %x\n", reply->virtualmods); | |
printf("firstkey: %d\n", reply->firstkey); | |
printf("nkeys: %d\n", reply->nkeys); | |
printf("indicators: %x\n", reply->indicators); | |
printf("nradiogroups: %d\n", reply->nradiogroups); | |
printf("nkeyaliases: %d\n", reply->nkeyaliases); | |
printf("nktlevels: %d\n", reply->nktlevels); | |
xcb_xkb_get_names_value_list_t list; | |
{ | |
void *buffer; | |
buffer = xcb_xkb_get_names_value_list(reply); | |
xcb_xkb_get_names_value_list_unpack(buffer, | |
reply->ntypes, | |
reply->indicators, | |
reply->virtualmods, | |
reply->groupnames, | |
reply->nkeys, | |
reply->nkeyaliases, | |
reply->nradiogroups, | |
reply->which, | |
&list); | |
} | |
/* dump section names. */ | |
printf("keycodesname: %s\n", get_atom_name(ctx, list.keycodesname)); | |
printf("geometryname: %s\n", get_atom_name(ctx, list.geometryname)); | |
printf("symbolsname: %s\n", get_atom_name(ctx, list.symbolsname)); | |
printf("physsymbolsname: %s\n", get_atom_name(ctx, list.physsymbolsname)); | |
printf("typesname: %s\n", get_atom_name(ctx, list.typesname)); | |
printf("compatname: %s\n", get_atom_name(ctx, list.compatname)); | |
/* dump key type names. */ | |
{ | |
int key_type_names_length; | |
xcb_atom_t *key_type_names_iter; | |
int n_levels_per_type_length; | |
uint8_t *n_levels_per_type_iter; | |
int kt_level_names_length; | |
xcb_atom_t *kt_level_names_iter; | |
key_type_names_length = xcb_xkb_get_names_value_list_type_names_length(reply, &list); | |
key_type_names_iter = xcb_xkb_get_names_value_list_type_names(&list); | |
n_levels_per_type_length = xcb_xkb_get_names_value_list_n_levels_per_type_length(reply, &list); | |
n_levels_per_type_iter = xcb_xkb_get_names_value_list_n_levels_per_type(&list); | |
kt_level_names_length = xcb_xkb_get_names_value_list_kt_level_names_length(reply, &list); | |
kt_level_names_iter = xcb_xkb_get_names_value_list_kt_level_names(&list); | |
assert(key_type_names_length == n_levels_per_type_length); | |
/* assert(kt_level_names_length == sum of num_levels); */ | |
for (int i = 0; i < key_type_names_length; i++) { | |
xcb_atom_t type_name = *key_type_names_iter; | |
uint8_t num_levels = *n_levels_per_type_iter; | |
printf("type name %d: %s\n", i, get_atom_name(ctx, type_name)); | |
for (int j = 0; j < num_levels; j++) { | |
xcb_atom_t level_name = *kt_level_names_iter; | |
printf("\tlevel name %d: %s\n", j, get_atom_name(ctx, level_name)); | |
kt_level_names_iter++; | |
} | |
key_type_names_iter++; | |
n_levels_per_type_iter++; | |
} | |
} | |
/* dump indicator names. */ | |
{ | |
int length; | |
xcb_atom_t *iter; | |
length = xcb_xkb_get_names_value_list_indicator_names_length(reply, &list); | |
iter = xcb_xkb_get_names_value_list_indicator_names(&list); | |
for (int i = 0; i < length; i++) { | |
xcb_atom_t indicator_name = *iter; | |
printf("indicator_name %d: %s\n", i, get_atom_name(ctx, indicator_name)); | |
iter++; | |
} | |
} | |
/* dump virtual modifier names. */ | |
{ | |
int length; | |
xcb_atom_t *iter; | |
length = xcb_xkb_get_names_value_list_virtual_mod_names_length(reply, &list); | |
iter = xcb_xkb_get_names_value_list_virtual_mod_names(&list); | |
for (int i = 0; i < length; i++) { | |
xcb_atom_t virtual_mod_name = *iter; | |
printf("virtual_mod_name %d: %s\n", i, get_atom_name(ctx, virtual_mod_name)); | |
iter++; | |
} | |
} | |
/* dump group names. */ | |
{ | |
int length; | |
xcb_atom_t *iter; | |
length = xcb_xkb_get_names_value_list_groups_length(reply, &list); | |
iter = xcb_xkb_get_names_value_list_groups(&list); | |
for (int i = 0; i < length; i++) { | |
xcb_atom_t group_name = *iter; | |
printf("group_name %d: %s\n", i, get_atom_name(ctx, group_name)); | |
iter++; | |
} | |
} | |
/* dump key names. */ | |
{ | |
int length; | |
xcb_xkb_key_name_iterator_t iter; | |
length = xcb_xkb_get_names_value_list_key_names_length(reply, &list); | |
iter = xcb_xkb_get_names_value_list_key_names_iterator(reply, &list); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_key_name_t *key_name = iter.data; | |
printf("key_name %d: %.4s\n", reply->firstkey + i, key_name->name); | |
xcb_xkb_key_name_next(&iter); | |
} | |
} | |
/* dump key aliases. */ | |
{ | |
int length; | |
xcb_xkb_key_alias_iterator_t iter; | |
length = xcb_xkb_get_names_value_list_key_aliases_length(reply, &list); | |
iter = xcb_xkb_get_names_value_list_key_aliases_iterator(reply, &list); | |
for (int i = 0; i < length; i++) { | |
xcb_xkb_key_alias_t *alias = iter.data; | |
printf("key_alias %d: real %.4s; alias %.4s\n", i, alias->real, alias->alias); | |
xcb_xkb_key_alias_next(&iter); | |
} | |
} | |
/* dump radio group names. */ | |
{ | |
int length; | |
xcb_atom_t *iter; | |
length = xcb_xkb_get_names_value_list_radio_group_names_length(reply, &list); | |
iter = xcb_xkb_get_names_value_list_radio_group_names(&list); | |
for (int i = 0; i < length; i++) { | |
xcb_atom_t radio_group_name = *iter; | |
printf("radio_group_name %d: %s\n", i, get_atom_name(ctx, radio_group_name)); | |
iter++; | |
} | |
} | |
} | |
int | |
main(void) | |
{ | |
struct ctx ctx; | |
ctx.conn = xcb_connect(null, null); | |
if (!ctx.conn) | |
errx(1, "couldn't connect to display"); | |
setup_xkb(&ctx); | |
get_map(&ctx); | |
get_indicator_map(&ctx); | |
get_compat_map(&ctx); | |
get_names(&ctx); | |
xcb_disconnect(ctx.conn); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment