Skip to content

Instantly share code, notes, and snippets.

@bluetech
Last active June 16, 2020 02:46
Show Gist options
  • Save bluetech/6038239 to your computer and use it in GitHub Desktop.
Save bluetech/6038239 to your computer and use it in GitHub Desktop.
xcb-xkb XkbGetMap test code
#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 <X11/Xlib.h>
#include <X11/XKBlib.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) {
/* warnx("couldn't get name of atom %d", atom); */
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;
}
#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)
errx(1, "didn't get all components");
}
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->nVModMapKeys,
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 *syms;
length2 = xcb_xkb_key_sym_map_syms_length(sym_map);
syms = xcb_xkb_key_sym_map_syms(sym_map);
for (int j = 0; j < length2; j++) {
xcb_keysym_t keysym = syms[j];
char name[64];
xkb_keysym_get_name(keysym, name, sizeof(name));
printf("\t\t%d %s\n", keysym, name);
}
}
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", reply->firstKeyExplicit + 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", reply->firstModMapKey + 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", reply->firstVModMapKey + 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");
}
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: %d\n", 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");
}
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: %d\n", reply->virtualMods);
printf("firstKey: %d\n", reply->firstKey);
printf("nKeys: %d\n", reply->nKeys);
printf("indicators: %d\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 length;
xcb_atom_t *iter;
length = xcb_xkb_get_names_value_list_type_names_length(reply, &list);
iter = xcb_xkb_get_names_value_list_type_names(&list);
for (int i = 0; i < length; i++) {
xcb_atom_t type_name = *iter;
printf("type name %d: %s\n", i, get_atom_name(ctx, type_name));
iter++;
}
}
/* Dump how many levels each key type has. */
{
int length;
uint8_t *iter;
length = xcb_xkb_get_names_value_list_n_levels_per_type_length(reply, &list);
iter = xcb_xkb_get_names_value_list_n_levels_per_type(&list);
for (int i = 0; i < length; i++) {
uint8_t n_levels_per_type = *iter;
printf("n_levels_per_type %d: %d\n", i, n_levels_per_type);
iter++;
}
}
/* Dump key type level names. */
{
int length;
xcb_atom_t *iter;
length = xcb_xkb_get_names_value_list_kt_level_names_length(reply, &list);
iter = xcb_xkb_get_names_value_list_kt_level_names(&list);
for (int i = 0; i < length; i++) {
xcb_atom_t kt_level_name = *iter;
printf("kt_level_name %d: %s\n", i, get_atom_name(ctx, kt_level_name));
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;
/* FIXME: xcb-xkb bug. */
printf("key_name %d: %.4s\n", 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++;
}
}
}
static void
get_map_xlib(void)
{
Display *dpy;
XkbDescPtr desc;
dpy = XOpenDisplay(NULL);
if (!dpy)
errx(1, "couldn't open xlib display");
desc = XkbGetMap(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
if (!desc)
errx(1, "couldn't get xkb map from xlib");
if (XkbGetIndicatorMap(dpy, XkbAllIndicatorsMask, desc) != Success ||
XkbGetCompatMap(dpy, XkbAllCompatMask, desc) != Success ||
/* XkbGetGeometry(dpy, desc) != Success || */
XkbGetNames(dpy, XkbAllNamesMask, desc) != Success)
errx(1, "couldn't get xkb map component from xlib");
if (desc->map->modmap) {
for (int i = desc->min_key_code; i <= desc->max_key_code; i++) {
printf("xlib modmap[%d] = %d\n", i, desc->map->modmap[i]);
}
}
if (desc->server->vmodmap) {
for (int i = desc->min_key_code; i <= desc->max_key_code; i++) {
printf("xlib vmodmap[%d] = %d\n", i, desc->server->vmodmap[i]);
}
}
if (desc->server->explicit) {
for (int i = desc->min_key_code; i <= desc->max_key_code; i++) {
printf("xlib explicit[%d] = %d\n", i, desc->server->explicit[i]);
}
}
XCloseDisplay(dpy);
}
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);
/* get_map_xlib(); */
xcb_disconnect(ctx.conn);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment