interactive-evdev: add option to print modmaps

Add an option to print modmap and vmodmap of relevant keys, as well as
virtual modifiers mapping to real modifier. This is useful for debugging.
It uses private API, so we compile it separately in the fashion of
`xkbcli-compile-keymap/compile-keymap`.
master
Pierre Le Marre 2023-09-18 12:17:11 +02:00 committed by Wismill
parent b5079dc96d
commit 0e3e2d1730
4 changed files with 139 additions and 2 deletions

View File

@ -416,10 +416,13 @@ man_pages = []
# Tools # Tools
build_tools = get_option('enable-tools') and cc.has_header_symbol('getopt.h', 'getopt_long', prefix: '#define _GNU_SOURCE') build_tools = get_option('enable-tools') and cc.has_header_symbol('getopt.h', 'getopt_long', prefix: '#define _GNU_SOURCE')
if build_tools if build_tools
libxkbcommon_tools_internal = static_library( libxkbcommon_tools_internal_sources = [
'tools-internal',
'tools/tools-common.h', 'tools/tools-common.h',
'tools/tools-common.c', 'tools/tools-common.c',
]
libxkbcommon_tools_internal = static_library(
'tools-internal',
libxkbcommon_tools_internal_sources,
dependencies: dep_libxkbcommon, dependencies: dep_libxkbcommon,
) )
tools_dep = declare_dependency( tools_dep = declare_dependency(
@ -467,6 +470,15 @@ if build_tools
install_dir: dir_libexec) install_dir: dir_libexec)
configh_data.set10('HAVE_XKBCLI_INTERACTIVE_EVDEV', true) configh_data.set10('HAVE_XKBCLI_INTERACTIVE_EVDEV', true)
install_man('tools/xkbcli-interactive-evdev.1') install_man('tools/xkbcli-interactive-evdev.1')
# The same tool again, but with access to some private APIs.
executable('interactive-evdev',
'tools/interactive-evdev.c',
libxkbcommon_sources,
libxkbcommon_tools_internal_sources,
dependencies: [tools_dep],
c_args: ['-DENABLE_PRIVATE_APIS'],
include_directories: [include_directories('src', 'include')],
install: false)
endif endif
if get_option('enable-x11') if get_option('enable-x11')
x11_tools_dep = declare_dependency( x11_tools_dep = declare_dependency(

View File

@ -58,7 +58,12 @@ static int evdev_offset = 8;
static bool report_state_changes; static bool report_state_changes;
static bool with_compose; static bool with_compose;
static enum xkb_consumed_mode consumed_mode = XKB_CONSUMED_MODE_XKB; static enum xkb_consumed_mode consumed_mode = XKB_CONSUMED_MODE_XKB;
#ifdef ENABLE_PRIVATE_APIS
#define DEFAULT_PRINT_FIELDS (PRINT_ALL_FIELDS & ~PRINT_MODMAPS)
#else
#define DEFAULT_PRINT_FIELDS PRINT_ALL_FIELDS #define DEFAULT_PRINT_FIELDS PRINT_ALL_FIELDS
#endif
print_state_fields_mask_t print_fields = DEFAULT_PRINT_FIELDS; print_state_fields_mask_t print_fields = DEFAULT_PRINT_FIELDS;
#define DEFAULT_INCLUDE_PATH_PLACEHOLDER "__defaults__" #define DEFAULT_INCLUDE_PATH_PLACEHOLDER "__defaults__"
@ -378,6 +383,9 @@ usage(FILE *fp, char *progname)
fprintf(fp, " or: %s --keymap <path to keymap file>\n", fprintf(fp, " or: %s --keymap <path to keymap file>\n",
progname); progname);
fprintf(fp, "For both:\n" fprintf(fp, "For both:\n"
#ifdef ENABLE_PRIVATE_APIS
" --print-modmaps (print real & virtual key modmaps)\n"
#endif
" --short (do not print layout nor Unicode keysym translation)\n" " --short (do not print layout nor Unicode keysym translation)\n"
" --report-state-changes (report changes to the state)\n" " --report-state-changes (report changes to the state)\n"
" --enable-compose (enable Compose)\n" " --enable-compose (enable Compose)\n"
@ -418,6 +426,9 @@ main(int argc, char *argv[])
OPT_COMPOSE, OPT_COMPOSE,
OPT_SHORT, OPT_SHORT,
OPT_REPORT_STATE, OPT_REPORT_STATE,
#ifdef ENABLE_PRIVATE_APIS
OPT_PRINT_MODMAPS,
#endif
}; };
static struct option opts[] = { static struct option opts[] = {
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h'},
@ -434,6 +445,9 @@ main(int argc, char *argv[])
{"short", no_argument, 0, OPT_SHORT}, {"short", no_argument, 0, OPT_SHORT},
{"report-state-changes", no_argument, 0, OPT_REPORT_STATE}, {"report-state-changes", no_argument, 0, OPT_REPORT_STATE},
{"without-x11-offset", no_argument, 0, OPT_WITHOUT_X11_OFFSET}, {"without-x11-offset", no_argument, 0, OPT_WITHOUT_X11_OFFSET},
#ifdef ENABLE_PRIVATE_APIS
{"print-modmaps", no_argument, 0, OPT_PRINT_MODMAPS},
#endif
{0, 0, 0, 0}, {0, 0, 0, 0},
}; };
@ -503,6 +517,11 @@ main(int argc, char *argv[])
return EXIT_INVALID_USAGE; return EXIT_INVALID_USAGE;
} }
break; break;
#ifdef ENABLE_PRIVATE_APIS
case OPT_PRINT_MODMAPS:
print_fields |= PRINT_MODMAPS;
break;
#endif
case 'h': case 'h':
usage(stdout, argv[0]); usage(stdout, argv[0]);
return EXIT_SUCCESS; return EXIT_SUCCESS;
@ -584,6 +603,15 @@ main(int argc, char *argv[])
goto out; goto out;
} }
#ifdef ENABLE_PRIVATE_APIS
if (print_fields & PRINT_MODMAPS) {
print_keys_modmaps(keymap);
putchar('\n');
print_keymap_modmaps(keymap);
putchar('\n');
}
#endif
act.sa_handler = sigintr_handler; act.sa_handler = sigintr_handler;
sigemptyset(&act.sa_mask); sigemptyset(&act.sa_mask);
act.sa_flags = 0; act.sa_flags = 0;

View File

@ -61,6 +61,87 @@ print_keycode(struct xkb_keymap *keymap, const char* prefix,
} }
} }
#ifdef ENABLE_PRIVATE_APIS
#include "src/keymap.h"
void
print_keymap_modmaps(struct xkb_keymap *keymap) {
printf("Modifiers mapping:\n");
for (xkb_mod_index_t vmod = 0; vmod < xkb_keymap_num_mods(keymap); vmod++) {
if (keymap->mods.mods[vmod].type & MOD_REAL)
continue;
printf("- %s: ", xkb_keymap_mod_get_name(keymap, vmod));
if (keymap->mods.mods[vmod].mapping) {
bool first = true;
for (xkb_mod_index_t mod = 0; mod < xkb_keymap_num_mods(keymap); mod++) {
if (keymap->mods.mods[vmod].mapping & (1u << mod)) {
if (first) {
first = false;
printf("%s", xkb_keymap_mod_get_name(keymap, mod));
} else {
printf("+ %s", xkb_keymap_mod_get_name(keymap, mod));
}
}
}
} else {
printf("(unmapped)");
}
printf("\n");
}
}
#define MODMAP_PADDING 7
#define VMODMAP_PADDING 9
static void
print_key_modmaps(struct xkb_keymap *keymap, xkb_keycode_t keycode) {
const struct xkb_key *key = XkbKey(keymap, keycode);
if (key != NULL) {
xkb_mod_index_t mod;
printf("modmap [ ");
if (key->modmap) {
for (mod = 0; mod < xkb_keymap_num_mods(keymap); mod++) {
if (key->modmap & (1u << mod)) {
printf("%-*s", (int) MODMAP_PADDING,
xkb_keymap_mod_get_name(keymap, mod));
break;
}
}
} else {
printf("%*c", (int) MODMAP_PADDING, ' ');
}
printf(" ] vmodmap [ ");
int length = 0;
const char *mod_name;
for (mod = 0; mod < xkb_keymap_num_mods(keymap); mod++) {
if (key->vmodmap & (1u << mod)) {
mod_name = xkb_keymap_mod_get_name(keymap, mod);
length += strlen(mod_name) + 1;
printf("%s ", mod_name);
}
}
if (length < VMODMAP_PADDING) {
printf("%*c", (int) VMODMAP_PADDING - length, ' ');
}
printf("] ");
}
}
void
print_keys_modmaps(struct xkb_keymap *keymap) {
const struct xkb_key *key;
printf("Keys modmaps:\n");
xkb_keys_foreach(key, keymap) {
if (key->modmap || key->vmodmap) {
print_keycode(keymap, "- ", key->keycode, ": ");
print_key_modmaps(keymap, key->keycode);
putchar('\n');
}
}
}
#endif
void void
tools_print_keycode_state(struct xkb_state *state, tools_print_keycode_state(struct xkb_state *state,
struct xkb_compose_state *compose_state, struct xkb_compose_state *compose_state,
@ -103,6 +184,12 @@ tools_print_keycode_state(struct xkb_state *state,
print_keycode(keymap, "keycode [ ", keycode, " ] "); print_keycode(keymap, "keycode [ ", keycode, " ] ");
#ifdef ENABLE_PRIVATE_APIS
if (fields & PRINT_MODMAPS) {
print_key_modmaps(keymap, keycode);
}
#endif
printf("keysyms [ "); printf("keysyms [ ");
for (int i = 0; i < nsyms; i++) { for (int i = 0; i < nsyms; i++) {
xkb_keysym_get_name(syms[i], s, sizeof(s)); xkb_keysym_get_name(syms[i], s, sizeof(s));

View File

@ -38,6 +38,9 @@
/* Fields that are printed in the interactive tools. */ /* Fields that are printed in the interactive tools. */
enum print_state_fields { enum print_state_fields {
#ifdef ENABLE_PRIVATE_APIS
PRINT_MODMAPS = (1u << 1),
#endif
PRINT_LAYOUT = (1u << 2), PRINT_LAYOUT = (1u << 2),
PRINT_UNICODE = (1u << 3), PRINT_UNICODE = (1u << 3),
PRINT_ALL_FIELDS = ((PRINT_UNICODE << 1) - 1), PRINT_ALL_FIELDS = ((PRINT_UNICODE << 1) - 1),
@ -50,6 +53,13 @@ enum print_state_fields {
}; };
typedef uint32_t print_state_fields_mask_t; typedef uint32_t print_state_fields_mask_t;
#ifdef ENABLE_PRIVATE_APIS
void
print_keymap_modmaps(struct xkb_keymap *keymap);
void
print_keys_modmaps(struct xkb_keymap *keymap);
#endif
void void
tools_print_keycode_state(struct xkb_state *state, tools_print_keycode_state(struct xkb_state *state,
struct xkb_compose_state *compose_state, struct xkb_compose_state *compose_state,