-
-
Save PandorasFox/a701caba8430d86c3f60d5e8f08b83c1 to your computer and use it in GitHub Desktop.
ganked & updated from https://gist.github.com/bluetech/6061368
This file contains 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
/* | |
* gcc ./tmp.c -lxcb -lxcb-xkb -lxkbcommon -lxkbcommon-x11 -g -fsanitize=address -fno-omit-frame-pointer | |
*/ | |
#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> | |
#include <xkbcommon/xkbcommon-x11.h> | |
struct ctx { | |
xcb_connection_t *conn; | |
}; | |
static const char * | |
get_atom_name(struct ctx *ctx, xcb_atom_t atom) { | |
xcb_get_atom_name_reply_t *reply = NULL; | |
char *name; | |
int length; | |
static char buf[16]; /* fixme */ | |
if (atom == 0) | |
return "<empty>"; | |
xcb_get_atom_name_cookie_t cookie; | |
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); | |
free(error); | |
free(reply); | |
return buf; | |
} | |
#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) { | |
uint8_t xkb_base_event; | |
uint8_t xkb_base_error; | |
if (xkb_x11_setup_xkb_extension(ctx->conn, | |
XKB_X11_MIN_MAJOR_XKB_VERSION, | |
XKB_X11_MIN_MINOR_XKB_VERSION, | |
0, | |
NULL, | |
NULL, | |
&xkb_base_event, | |
&xkb_base_error) != 1) | |
errx(EXIT_FAILURE, "Could not setup XKB extension."); | |
xcb_xkb_get_names_reply_t *reply = NULL; | |
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"); | |
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 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++; | |
} | |
free(reply); | |
free(error); | |
} | |
int main(void) { | |
struct ctx ctx; | |
ctx.conn = xcb_connect(NULL, NULL); | |
if (!ctx.conn) | |
errx(1, "couldn't connect to display"); | |
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