Commit 8a827442edfd2aac479960ad0bca5c494a5ee81e

Authored by samuel thibault
1 parent 4d86652c

add missing file

Showing 1 changed file with 140 additions and 0 deletions   Show diff stats
debian/patches/git-xbrlapi 0 → 100644
... ... @@ -0,0 +1,140 @@
  1 +commit b1e831709e2c524c5e2bbe0b106bcdb239502183
  2 +Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
  3 +Date: Tue Apr 24 02:12:08 2018 +0200
  4 +
  5 + xbrlapi: map unmapped keysyms to temporary keycodes
  6 +
  7 + So that we can simulate any keysym, independently from the keyboard
  8 + layout, and notably characters only reachable with dead keys.
  9 +
  10 +diff --git a/Programs/xbrlapi.c b/Programs/xbrlapi.c
  11 +index 0a6e59a11..d546273da 100644
  12 +--- a/Programs/xbrlapi.c
  13 ++++ b/Programs/xbrlapi.c
  14 +@@ -581,6 +581,11 @@ static void toX_f(const char *display) {
  15 + unsigned int keysym, keycode, modifiers, next_modifiers = 0;
  16 + Bool haveXTest;
  17 + int eventBase, errorBase, majorVersion, minorVersion;
  18 ++ XkbDescPtr xkb = NULL;
  19 ++ XkbMapChangesRec changes = { .changed = XkbKeyTypesMask|XkbKeySymsMask };
  20 ++ int oneGroupType[XkbNumKbdGroups] = { XkbOneLevelIndex };
  21 ++ Status status;
  22 ++ int last_remap_keycode = -1, remap_keycode;
  23 + #endif /* CAN_SIMULATE_KEY_PRESSES */
  24 +
  25 + Xdisplay = display;
  26 +@@ -591,7 +596,6 @@ static void toX_f(const char *display) {
  27 +
  28 + #ifdef CAN_SIMULATE_KEY_PRESSES
  29 + haveXTest = XTestQueryExtension(dpy, &eventBase, &errorBase, &majorVersion, &minorVersion);
  30 +-#endif /* CAN_SIMULATE_KEY_PRESSES */
  31 +
  32 + {
  33 + int foo;
  34 +@@ -601,6 +605,7 @@ static void toX_f(const char *display) {
  35 + if (!XkbQueryExtension(dpy, &foo, &foo, &foo, &major, &minor))
  36 + fatal(gettext("Incompatible XKB server support\n"));
  37 + }
  38 ++#endif /* CAN_SIMULATE_KEY_PRESSES */
  39 +
  40 + X_fd = XConnectionNumber(dpy);
  41 +
  42 +@@ -796,9 +801,10 @@ static void toX_f(const char *display) {
  43 + modifiers = ((code & BRLAPI_KEY_FLAGS_MASK) >> BRLAPI_KEY_FLAGS_SHIFT) & 0xFF;
  44 + keysym = code & BRLAPI_KEY_CODE_MASK;
  45 + keycode = XKeysymToKeycode(dpy,keysym);
  46 ++ remap_keycode = -1;
  47 + if (keycode == NoSymbol) {
  48 +- fprintf(stderr,gettext("xbrlapi: Couldn't translate keysym %08X to keycode.\n"),keysym);
  49 +- continue;
  50 ++ debugf(gettext("xbrlapi: Couldn't translate keysym %08X to keycode.\n"),keysym);
  51 ++ goto needRemap;
  52 + }
  53 +
  54 + {
  55 +@@ -821,21 +827,80 @@ static void toX_f(const char *display) {
  56 + if (tryModifiers(keycode, &modifiers, *try, keysym)) goto foundModifiers;
  57 + } while (*++try);
  58 +
  59 +- fprintf(stderr,gettext("xbrlapi: Couldn't find modifiers to apply to %d for getting keysym %08X\n"),keycode,keysym);
  60 +- continue;
  61 ++ debugf(gettext("xbrlapi: Couldn't find modifiers to apply to %d for getting keysym %08X\n"),keycode,keysym);
  62 ++ }
  63 ++
  64 ++ needRemap:
  65 ++ {
  66 ++ /* Try tofind an unassigned keycode to remap it temporarily to the requested keysym. */
  67 ++ xkb = XkbGetMap(dpy,XkbKeyTypesMask|XkbKeySymsMask,XkbUseCoreKbd);
  68 ++ /* Start from big keycodes, usually unassigned. */
  69 ++ for (i = xkb->max_key_code;
  70 ++ i >= xkb->min_key_code && (XkbKeyNumGroups(xkb,i) != 0 || i == last_remap_keycode);
  71 ++ i--)
  72 ++ ;
  73 ++ if (i < xkb->min_key_code) {
  74 ++ fprintf(stderr,gettext("xbrlapi: Couldn't find a keycode to remap for simulating unbound keysym %08X\n"),keysym);
  75 ++ goto abortRemap;
  76 ++ }
  77 ++ remap_keycode = keycode = i;
  78 ++ next_modifiers = modifiers = 0;
  79 ++
  80 ++ /* Remap this keycode. */
  81 ++ changes.first_key_sym = keycode;
  82 ++ changes.num_key_syms = 1;
  83 ++ if ((status = XkbChangeTypesOfKey(xkb,keycode,1,XkbGroup1Mask,oneGroupType,&changes))) {
  84 ++ debugf("Error while changing client keymap: %d\n", status);
  85 ++ goto abortRemap;
  86 ++ }
  87 ++ XkbKeySymEntry(xkb,keycode,0,0) = keysym;
  88 ++ if (!XkbChangeMap(dpy,xkb,&changes)) {
  89 ++ debugf("Error while changing server keymap\n");
  90 ++ goto abortRemap;
  91 ++ }
  92 ++ XkbFreeKeyboard(xkb,0,True);
  93 ++ debugf("Remapped keycode %d to keysym %08X\n",keycode,keysym);
  94 + }
  95 +- foundModifiers:
  96 +
  97 ++ foundModifiers:
  98 + debugf("key %08X: (%d,%x,%x)\n", keysym, keycode, next_modifiers, modifiers);
  99 + modifiers |= next_modifiers;
  100 + next_modifiers = 0;
  101 + if (modifiers)
  102 + XkbLockModifiers(dpy, XkbUseCoreKbd, modifiers, modifiers);
  103 +- XTestFakeKeyEvent(dpy,keycode,True,CurrentTime);
  104 +- XTestFakeKeyEvent(dpy,keycode,False,CurrentTime);
  105 ++ XTestFakeKeyEvent(dpy,keycode,True,1);
  106 ++ XTestFakeKeyEvent(dpy,keycode,False,1);
  107 + if (modifiers)
  108 + XkbLockModifiers(dpy, XkbUseCoreKbd, modifiers, 0);
  109 ++
  110 ++ /* Remove previous keycode mapping */
  111 ++ if (last_remap_keycode != -1) {
  112 ++ /* Note: since X11 is asynchronous, we should not immediately
  113 ++ * unmap the just-mapped keycode, otherwise when the client
  114 ++ * eventually gets to read the new Xkb state from the server,
  115 ++ * the key might have been synthesized and the keycode unmapped
  116 ++ * already. We just hope the user does not type too fast for the
  117 ++ * application to catch up. */
  118 ++ xkb = XkbGetMap(dpy,XkbKeyTypesMask|XkbKeySymsMask,XkbUseCoreKbd);
  119 ++ changes.first_key_sym = last_remap_keycode;
  120 ++ changes.num_key_syms = 1;
  121 ++ if ((status = XkbChangeTypesOfKey(xkb,last_remap_keycode,0,XkbGroup1Mask,NULL,&changes))) {
  122 ++ debugf("Oops, error while restoring client keymap: %d\n", status);
  123 ++ } else {
  124 ++ XkbChangeMap(dpy,xkb,&changes);
  125 ++ debugf("restored last keycode %d\n", last_remap_keycode);
  126 ++ }
  127 ++ XkbFreeKeyboard(xkb,0,True);
  128 ++ }
  129 ++ XFlush(dpy);
  130 ++ last_remap_keycode = remap_keycode;
  131 + break;
  132 ++
  133 ++ abortRemap:
  134 ++ XkbFreeKeyboard(xkb, 0, True);
  135 ++ xkb = NULL;
  136 ++ break;
  137 ++
  138 + default:
  139 + fprintf(stderr, "xbrlapi: %s: %" BRLAPI_PRIxKEYCODE "\n",
  140 + gettext("unexpected block type"), code);
... ...