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
build_tools = get_option('enable-tools') and cc.has_header_symbol('getopt.h', 'getopt_long', prefix: '#define _GNU_SOURCE')
if build_tools
libxkbcommon_tools_internal = static_library(
'tools-internal',
libxkbcommon_tools_internal_sources = [
'tools/tools-common.h',
'tools/tools-common.c',
]
libxkbcommon_tools_internal = static_library(
'tools-internal',
libxkbcommon_tools_internal_sources,
dependencies: dep_libxkbcommon,
)
tools_dep = declare_dependency(
@ -467,6 +470,15 @@ if build_tools
install_dir: dir_libexec)
configh_data.set10('HAVE_XKBCLI_INTERACTIVE_EVDEV', true)
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
if get_option('enable-x11')
x11_tools_dep = declare_dependency(

View File

@ -58,7 +58,12 @@ static int evdev_offset = 8;
static bool report_state_changes;
static bool with_compose;
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
#endif
print_state_fields_mask_t print_fields = DEFAULT_PRINT_FIELDS;
#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",
progname);
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"
" --report-state-changes (report changes to the state)\n"
" --enable-compose (enable Compose)\n"
@ -418,6 +426,9 @@ main(int argc, char *argv[])
OPT_COMPOSE,
OPT_SHORT,
OPT_REPORT_STATE,
#ifdef ENABLE_PRIVATE_APIS
OPT_PRINT_MODMAPS,
#endif
};
static struct option opts[] = {
{"help", no_argument, 0, 'h'},
@ -434,6 +445,9 @@ main(int argc, char *argv[])
{"short", no_argument, 0, OPT_SHORT},
{"report-state-changes", no_argument, 0, OPT_REPORT_STATE},
{"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},
};
@ -503,6 +517,11 @@ main(int argc, char *argv[])
return EXIT_INVALID_USAGE;
}
break;
#ifdef ENABLE_PRIVATE_APIS
case OPT_PRINT_MODMAPS:
print_fields |= PRINT_MODMAPS;
break;
#endif
case 'h':
usage(stdout, argv[0]);
return EXIT_SUCCESS;
@ -584,6 +603,15 @@ main(int argc, char *argv[])
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;
sigemptyset(&act.sa_mask);
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
tools_print_keycode_state(struct xkb_state *state,
struct xkb_compose_state *compose_state,
@ -103,6 +184,12 @@ tools_print_keycode_state(struct xkb_state *state,
print_keycode(keymap, "keycode [ ", keycode, " ] ");
#ifdef ENABLE_PRIVATE_APIS
if (fields & PRINT_MODMAPS) {
print_key_modmaps(keymap, keycode);
}
#endif
printf("keysyms [ ");
for (int i = 0; i < nsyms; i++) {
xkb_keysym_get_name(syms[i], s, sizeof(s));

View File

@ -38,6 +38,9 @@
/* Fields that are printed in the interactive tools. */
enum print_state_fields {
#ifdef ENABLE_PRIVATE_APIS
PRINT_MODMAPS = (1u << 1),
#endif
PRINT_LAYOUT = (1u << 2),
PRINT_UNICODE = (1u << 3),
PRINT_ALL_FIELDS = ((PRINT_UNICODE << 1) - 1),
@ -50,6 +53,13 @@ enum print_state_fields {
};
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
tools_print_keycode_state(struct xkb_state *state,
struct xkb_compose_state *compose_state,