# 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(
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(
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__"
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"
OPT_COMPOSE,
OPT_SHORT,
OPT_REPORT_STATE,
+#ifdef ENABLE_PRIVATE_APIS
+ OPT_PRINT_MODMAPS,
+#endif
};
static struct option opts[] = {
{"help", no_argument, 0, 'h'},
{"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},
};
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;
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;
}
}
+#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,
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));
/* 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),
};
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,