2012-04-10 12:20:27 -06:00
|
|
|
/*
|
|
|
|
* Copyright © 2012 Ran Benita <ran234@gmail.com>
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
* Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/input.h>
|
|
|
|
|
2012-07-12 07:15:08 -06:00
|
|
|
#include "test.h"
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
enum {
|
|
|
|
DOWN,
|
2012-09-16 06:57:36 -06:00
|
|
|
REPEAT,
|
2012-04-10 12:20:27 -06:00
|
|
|
UP,
|
|
|
|
BOTH,
|
|
|
|
NEXT,
|
|
|
|
FINISH,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define EVDEV_OFFSET 8
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Test a sequence of keysyms, resulting from a sequence of key presses,
|
|
|
|
* against the keysyms they're supposed to generate.
|
|
|
|
*
|
|
|
|
* - Each test runs with a clean state.
|
|
|
|
* - Each line in the test is made up of:
|
|
|
|
* + A keycode, given as a KEY_* from linux/input.h.
|
|
|
|
* + A direction - DOWN for press, UP for release, BOTH for
|
2012-09-16 06:57:36 -06:00
|
|
|
* immediate press + release, REPEAT to just get the syms.
|
2012-04-10 12:20:27 -06:00
|
|
|
* + A sequence of keysyms that should result from this keypress.
|
|
|
|
*
|
|
|
|
* The vararg format is:
|
2012-08-01 15:40:22 -06:00
|
|
|
* <KEY_*> <DOWN | UP | BOTH> <XKB_KEY_* (zero or more)> <NEXT | FINISH>
|
2012-04-10 12:20:27 -06:00
|
|
|
*
|
|
|
|
* See below for examples.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
test_key_seq(struct xkb_keymap *keymap, ...)
|
|
|
|
{
|
|
|
|
struct xkb_state *state;
|
|
|
|
|
|
|
|
va_list ap;
|
2012-07-15 02:52:54 -06:00
|
|
|
xkb_keycode_t kc;
|
2012-04-10 12:20:27 -06:00
|
|
|
int op;
|
|
|
|
xkb_keysym_t keysym;
|
|
|
|
|
|
|
|
const xkb_keysym_t *syms;
|
|
|
|
unsigned int nsyms, i;
|
2012-07-11 09:00:31 -06:00
|
|
|
char ksbuf[64];
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
state = xkb_state_new(keymap);
|
|
|
|
assert(state);
|
|
|
|
|
|
|
|
va_start(ap, keymap);
|
|
|
|
|
|
|
|
for (;;) {
|
2012-07-15 02:52:54 -06:00
|
|
|
kc = va_arg(ap, int) + EVDEV_OFFSET;
|
2012-04-10 12:20:27 -06:00
|
|
|
op = va_arg(ap, int);
|
|
|
|
|
2012-09-21 05:44:17 -06:00
|
|
|
nsyms = xkb_state_key_get_syms(state, kc, &syms);
|
2012-07-15 02:52:54 -06:00
|
|
|
fprintf(stderr, "got %d syms for key 0x%x: [", nsyms, kc);
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
if (op == DOWN || op == BOTH)
|
2012-07-15 02:52:54 -06:00
|
|
|
xkb_state_update_key(state, kc, XKB_KEY_DOWN);
|
2012-04-10 12:20:27 -06:00
|
|
|
if (op == UP || op == BOTH)
|
2012-07-15 02:52:54 -06:00
|
|
|
xkb_state_update_key(state, kc, XKB_KEY_UP);
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
for (i = 0; i < nsyms; i++) {
|
|
|
|
keysym = va_arg(ap, int);
|
|
|
|
xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf));
|
|
|
|
fprintf(stderr, "%s%s", (i != 0) ? ", " : "", ksbuf);
|
|
|
|
|
|
|
|
if (keysym == FINISH || keysym == NEXT) {
|
|
|
|
xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf));
|
|
|
|
fprintf(stderr, "Did not expect keysym: %s.\n", ksbuf);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (keysym != syms[i]) {
|
|
|
|
xkb_keysym_get_name(keysym, ksbuf, sizeof(ksbuf));
|
|
|
|
fprintf(stderr, "Expected keysym: %s. ", ksbuf);;
|
|
|
|
xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf));
|
|
|
|
fprintf(stderr, "Got keysym: %s.\n", ksbuf);;
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(stderr, "]\n");
|
|
|
|
|
|
|
|
keysym = va_arg(ap, int);
|
|
|
|
if (keysym == NEXT)
|
|
|
|
continue;
|
|
|
|
if (keysym == FINISH)
|
|
|
|
break;
|
|
|
|
|
|
|
|
xkb_keysym_get_name(keysym, ksbuf, sizeof(ksbuf));
|
|
|
|
fprintf(stderr, "Expected keysym: %s. Didn't get it.\n", ksbuf);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end(ap);
|
|
|
|
xkb_state_unref(state);
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
va_end(ap);
|
|
|
|
xkb_state_unref(state);
|
2012-06-29 15:07:09 -06:00
|
|
|
return 0;
|
2012-04-10 12:20:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main(void)
|
|
|
|
{
|
2012-07-12 07:15:08 -06:00
|
|
|
struct xkb_context *ctx = test_get_context();
|
2012-04-10 12:20:27 -06:00
|
|
|
struct xkb_keymap *keymap;
|
2012-07-12 07:15:08 -06:00
|
|
|
|
2012-04-10 12:20:27 -06:00
|
|
|
assert(ctx);
|
symbols: fix real/alias key merge ordering bug
Background:
The CopySymbolsDef has a comment on a couple of lines which supposedly
fixed a bug:
/*
* kt_index[i] may have been set by a previous run (if we have two
* layouts specified). Let's not overwrite it with the ONE_LEVEL
* default group if we dont even have keys for this group anyway.
*
* FIXME: There should be a better fix for this.
*/
if (!darray_empty(groupi->levels))
key->kt_index[i] = types[i];
But neither the comment nor the fix make any sense, because the kt_index
is indexed per group, i.e. each group gets its own type.
The original xkbcomp commit which added this (36fecff58) points to this
bug: https://bugzilla.redhat.com/show_bug.cgi?id=436626
which complains about -layout "ru,us" -variant "phonetic," not working
properly. And indeed when we try:
sudo ./test/interactive -l ru,us -v
the first group doesn't get any syms for the main keys.
The problem (Clearly the fix above is useless):
The ru(phonetic) map is specified using aliases, e.g. LatQ, LatW instead
of AD01, AD02, etc. When combined with another layout which uses the
real names (AD01, AD02), the symbols code should recognize they are the
same key and merge them into one KeyInfo. The current code does that,
but it doesn't catch the case where the alias was processes *before* the
real one; so we get two KeyInfo's and the later one wins. So e.g. the
ru(phonetic) symbols are ignored.
The fix:
Before adding a new KeyInfo to the keys array, always replace its name
by the real name, which avoids the entire issue. Luckily this is done
pretty late so most error messages should still show the alias name.
Signed-off-by: Ran Benita <ran234@gmail.com>
2012-09-12 14:51:19 -06:00
|
|
|
keymap = test_compile_rules(ctx, "evdev", "evdev",
|
2012-09-13 02:49:02 -06:00
|
|
|
"us,il,ru,de", ",,phonetic,neo",
|
2012-07-12 07:15:08 -06:00
|
|
|
"grp:alt_shift_toggle,grp:menu_toggle");
|
2012-04-10 12:20:27 -06:00
|
|
|
assert(keymap);
|
|
|
|
|
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_H, BOTH, XKB_KEY_h, NEXT,
|
|
|
|
KEY_E, BOTH, XKB_KEY_e, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_l, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_l, NEXT,
|
|
|
|
KEY_O, BOTH, XKB_KEY_o, FINISH));
|
2012-04-10 12:20:27 -06:00
|
|
|
|
2012-09-16 06:57:36 -06:00
|
|
|
/* Simple shifted level. */
|
2012-04-10 12:20:27 -06:00
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_H, BOTH, XKB_KEY_h, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_E, BOTH, XKB_KEY_E, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_l, NEXT,
|
|
|
|
KEY_O, BOTH, XKB_KEY_o, FINISH));
|
2012-04-10 12:20:27 -06:00
|
|
|
|
2012-09-16 06:57:36 -06:00
|
|
|
/* Key repeat shifted and unshifted in the middle. */
|
|
|
|
assert(test_key_seq(keymap,
|
|
|
|
KEY_H, DOWN, XKB_KEY_h, NEXT,
|
|
|
|
KEY_H, REPEAT, XKB_KEY_h, NEXT,
|
|
|
|
KEY_H, REPEAT, XKB_KEY_h, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_H, REPEAT, XKB_KEY_H, NEXT,
|
|
|
|
KEY_H, REPEAT, XKB_KEY_H, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_H, REPEAT, XKB_KEY_h, NEXT,
|
|
|
|
KEY_H, REPEAT, XKB_KEY_h, NEXT,
|
|
|
|
KEY_H, UP, XKB_KEY_h, NEXT,
|
|
|
|
KEY_H, BOTH, XKB_KEY_h, FINISH));
|
|
|
|
|
2012-04-10 12:20:27 -06:00
|
|
|
/* Base modifier cleared on key release... */
|
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_H, BOTH, XKB_KEY_h, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_E, BOTH, XKB_KEY_E, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_O, BOTH, XKB_KEY_O, FINISH));
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
/* ... But only by the keycode that set it. */
|
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_H, BOTH, XKB_KEY_h, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_E, BOTH, XKB_KEY_E, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_RIGHTSHIFT, UP, XKB_KEY_Shift_R, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_O, BOTH, XKB_KEY_O, FINISH));
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* A base modifier should only be cleared when no other key affecting
|
|
|
|
* the modifier is down.
|
|
|
|
*/
|
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_H, BOTH, XKB_KEY_h, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_E, BOTH, XKB_KEY_E, NEXT,
|
|
|
|
KEY_RIGHTSHIFT, DOWN, XKB_KEY_Shift_R, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_RIGHTSHIFT, UP, XKB_KEY_Shift_R, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_O, BOTH, XKB_KEY_o, FINISH));
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
/* Group switching / locking. */
|
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_H, BOTH, XKB_KEY_h, NEXT,
|
|
|
|
KEY_E, BOTH, XKB_KEY_e, NEXT,
|
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_K, BOTH, XKB_KEY_hebrew_lamed, NEXT,
|
|
|
|
KEY_F, BOTH, XKB_KEY_hebrew_kaph, NEXT,
|
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
symbols: fix real/alias key merge ordering bug
Background:
The CopySymbolsDef has a comment on a couple of lines which supposedly
fixed a bug:
/*
* kt_index[i] may have been set by a previous run (if we have two
* layouts specified). Let's not overwrite it with the ONE_LEVEL
* default group if we dont even have keys for this group anyway.
*
* FIXME: There should be a better fix for this.
*/
if (!darray_empty(groupi->levels))
key->kt_index[i] = types[i];
But neither the comment nor the fix make any sense, because the kt_index
is indexed per group, i.e. each group gets its own type.
The original xkbcomp commit which added this (36fecff58) points to this
bug: https://bugzilla.redhat.com/show_bug.cgi?id=436626
which complains about -layout "ru,us" -variant "phonetic," not working
properly. And indeed when we try:
sudo ./test/interactive -l ru,us -v
the first group doesn't get any syms for the main keys.
The problem (Clearly the fix above is useless):
The ru(phonetic) map is specified using aliases, e.g. LatQ, LatW instead
of AD01, AD02, etc. When combined with another layout which uses the
real names (AD01, AD02), the symbols code should recognize they are the
same key and merge them into one KeyInfo. The current code does that,
but it doesn't catch the case where the alias was processes *before* the
real one; so we get two KeyInfo's and the later one wins. So e.g. the
ru(phonetic) symbols are ignored.
The fix:
Before adding a new KeyInfo to the keys array, always replace its name
by the real name, which avoids the entire issue. Luckily this is done
pretty late so most error messages should still show the alias name.
Signed-off-by: Ran Benita <ran234@gmail.com>
2012-09-12 14:51:19 -06:00
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
2012-09-13 02:49:02 -06:00
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_O, BOTH, XKB_KEY_o, FINISH));
|
2012-04-10 12:20:27 -06:00
|
|
|
|
2012-07-11 05:12:12 -06:00
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_LEFTALT, DOWN, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_LEFTALT, UP, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, FINISH));
|
2012-07-11 05:12:12 -06:00
|
|
|
|
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_LEFTALT, UP, XKB_KEY_Alt_L, FINISH));
|
2012-07-11 05:12:12 -06:00
|
|
|
|
2012-04-10 12:20:27 -06:00
|
|
|
/* Locked modifiers. */
|
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
KEY_H, BOTH, XKB_KEY_H, NEXT,
|
|
|
|
KEY_E, BOTH, XKB_KEY_E, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_O, BOTH, XKB_KEY_O, FINISH));
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_H, BOTH, XKB_KEY_h, NEXT,
|
|
|
|
KEY_E, BOTH, XKB_KEY_e, NEXT,
|
|
|
|
KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
KEY_O, BOTH, XKB_KEY_o, FINISH));
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_H, BOTH, XKB_KEY_h, NEXT,
|
|
|
|
KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
KEY_E, BOTH, XKB_KEY_E, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_L, NEXT,
|
|
|
|
KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
KEY_O, BOTH, XKB_KEY_O, FINISH));
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_H, BOTH, XKB_KEY_h, NEXT,
|
|
|
|
KEY_E, BOTH, XKB_KEY_e, NEXT,
|
|
|
|
KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_l, NEXT,
|
|
|
|
KEY_L, BOTH, XKB_KEY_l, NEXT,
|
|
|
|
KEY_O, BOTH, XKB_KEY_o, FINISH));
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
/*
|
|
|
|
* A key release affecting a locked modifier should clear it
|
|
|
|
* regardless of the key press.
|
|
|
|
*/
|
2012-06-29 15:07:09 -06:00
|
|
|
/* assert(test_key_seq(keymap, */
|
2012-08-01 15:40:22 -06:00
|
|
|
/* KEY_H, BOTH, XKB_KEY_h, NEXT, */
|
|
|
|
/* KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT, */
|
|
|
|
/* KEY_E, BOTH, XKB_KEY_E, NEXT, */
|
|
|
|
/* KEY_L, BOTH, XKB_KEY_L, NEXT, */
|
|
|
|
/* KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT, */
|
|
|
|
/* KEY_L, BOTH, XKB_KEY_L, NEXT, */
|
|
|
|
/* KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT, */
|
|
|
|
/* KEY_O, BOTH, XKB_KEY_o, FINISH)); */
|
2012-04-10 12:20:27 -06:00
|
|
|
|
|
|
|
/* Simple Num Lock sanity check. */
|
|
|
|
assert(test_key_seq(keymap,
|
2012-08-01 15:40:22 -06:00
|
|
|
KEY_KP1, BOTH, XKB_KEY_KP_End, NEXT,
|
|
|
|
KEY_NUMLOCK, BOTH, XKB_KEY_Num_Lock, NEXT,
|
|
|
|
KEY_KP1, BOTH, XKB_KEY_KP_1, NEXT,
|
|
|
|
KEY_KP2, BOTH, XKB_KEY_KP_2, NEXT,
|
|
|
|
KEY_NUMLOCK, BOTH, XKB_KEY_Num_Lock, NEXT,
|
|
|
|
KEY_KP2, BOTH, XKB_KEY_KP_Down, FINISH));
|
2012-04-10 12:20:27 -06:00
|
|
|
|
symbols: fix real/alias key merge ordering bug
Background:
The CopySymbolsDef has a comment on a couple of lines which supposedly
fixed a bug:
/*
* kt_index[i] may have been set by a previous run (if we have two
* layouts specified). Let's not overwrite it with the ONE_LEVEL
* default group if we dont even have keys for this group anyway.
*
* FIXME: There should be a better fix for this.
*/
if (!darray_empty(groupi->levels))
key->kt_index[i] = types[i];
But neither the comment nor the fix make any sense, because the kt_index
is indexed per group, i.e. each group gets its own type.
The original xkbcomp commit which added this (36fecff58) points to this
bug: https://bugzilla.redhat.com/show_bug.cgi?id=436626
which complains about -layout "ru,us" -variant "phonetic," not working
properly. And indeed when we try:
sudo ./test/interactive -l ru,us -v
the first group doesn't get any syms for the main keys.
The problem (Clearly the fix above is useless):
The ru(phonetic) map is specified using aliases, e.g. LatQ, LatW instead
of AD01, AD02, etc. When combined with another layout which uses the
real names (AD01, AD02), the symbols code should recognize they are the
same key and merge them into one KeyInfo. The current code does that,
but it doesn't catch the case where the alias was processes *before* the
real one; so we get two KeyInfo's and the later one wins. So e.g. the
ru(phonetic) symbols are ignored.
The fix:
Before adding a new KeyInfo to the keys array, always replace its name
by the real name, which avoids the entire issue. Luckily this is done
pretty late so most error messages should still show the alias name.
Signed-off-by: Ran Benita <ran234@gmail.com>
2012-09-12 14:51:19 -06:00
|
|
|
/* Test that the aliases in the ru(phonetic) symbols map work. */
|
|
|
|
assert(test_key_seq(keymap,
|
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_1, BOTH, XKB_KEY_1, NEXT,
|
|
|
|
KEY_Q, BOTH, XKB_KEY_Cyrillic_ya, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_1, BOTH, XKB_KEY_exclam, NEXT,
|
|
|
|
KEY_Q, BOTH, XKB_KEY_Cyrillic_YA, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_V, BOTH, XKB_KEY_Cyrillic_zhe, NEXT,
|
|
|
|
KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
KEY_1, BOTH, XKB_KEY_1, NEXT,
|
|
|
|
KEY_V, BOTH, XKB_KEY_Cyrillic_ZHE, NEXT,
|
|
|
|
KEY_RIGHTSHIFT, DOWN, XKB_KEY_Shift_R, NEXT,
|
|
|
|
KEY_V, BOTH, XKB_KEY_Cyrillic_zhe, NEXT,
|
|
|
|
KEY_RIGHTSHIFT, UP, XKB_KEY_Shift_R, NEXT,
|
|
|
|
KEY_V, BOTH, XKB_KEY_Cyrillic_ZHE, FINISH));
|
|
|
|
|
2012-09-13 02:49:02 -06:00
|
|
|
#define KS(name) xkb_keysym_from_name(name)
|
|
|
|
|
|
|
|
/* Test that levels (1-5) in de(neo) symbols map work. */
|
|
|
|
assert(test_key_seq(keymap,
|
|
|
|
/* Switch to the group. */
|
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
|
|
|
|
/* Level 1. */
|
|
|
|
KEY_1, BOTH, XKB_KEY_1, NEXT,
|
|
|
|
KEY_Q, BOTH, XKB_KEY_x, NEXT,
|
|
|
|
KEY_KP7, BOTH, XKB_KEY_KP_7, NEXT,
|
|
|
|
KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
|
|
|
|
|
|
|
|
/* Level 2 with Shift. */
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_1, BOTH, XKB_KEY_degree, NEXT,
|
|
|
|
KEY_Q, BOTH, XKB_KEY_X, NEXT,
|
|
|
|
KEY_KP7, BOTH, KS("U2714"), NEXT,
|
|
|
|
KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
|
|
|
|
/*
|
|
|
|
* XXX: de(neo) uses shift(both_capslock) which causes
|
|
|
|
* the interesting result in the next line. Since it's
|
|
|
|
* a key release, it doesn't actually lock the modifier,
|
|
|
|
* and applications by-and-large ignore the keysym on
|
|
|
|
* release(?). Is this a problem?
|
|
|
|
*/
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
|
|
|
|
/* Level 2 with the Lock modifier. */
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_RIGHTSHIFT, BOTH, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
KEY_6, BOTH, XKB_KEY_6, NEXT,
|
|
|
|
KEY_H, BOTH, XKB_KEY_S, NEXT,
|
|
|
|
KEY_KP3, BOTH, XKB_KEY_KP_3, NEXT,
|
|
|
|
KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_RIGHTSHIFT, BOTH, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
|
|
|
|
/* Level 3. */
|
|
|
|
KEY_CAPSLOCK, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT,
|
|
|
|
KEY_6, BOTH, XKB_KEY_cent, NEXT,
|
|
|
|
KEY_Q, BOTH, XKB_KEY_ellipsis, NEXT,
|
|
|
|
KEY_KP7, BOTH, KS("U2195"), NEXT,
|
|
|
|
KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
|
|
|
|
KEY_CAPSLOCK, UP, XKB_KEY_ISO_Level3_Shift, NEXT,
|
|
|
|
|
|
|
|
/* Level 4. */
|
|
|
|
KEY_CAPSLOCK, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_5, BOTH, XKB_KEY_malesymbol, NEXT,
|
|
|
|
KEY_E, BOTH, XKB_KEY_Greek_lambda, NEXT,
|
|
|
|
KEY_SPACE, BOTH, XKB_KEY_nobreakspace, NEXT,
|
|
|
|
KEY_KP8, BOTH, XKB_KEY_intersection, NEXT,
|
|
|
|
KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT,
|
|
|
|
KEY_CAPSLOCK, UP, XKB_KEY_ISO_Level3_Shift, NEXT,
|
|
|
|
|
|
|
|
/* Level 5. */
|
|
|
|
KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT,
|
|
|
|
/*
|
|
|
|
* XXX: This doesn't work, but gives level1 keysyms.
|
|
|
|
* This does work when when de(neo) is the first layout
|
|
|
|
* (before us,il etc.). It's like that in the X server
|
|
|
|
* as well. Investigate.
|
|
|
|
*/
|
|
|
|
KEY_RIGHTALT, UP, XKB_KEY_ISO_Level5_Shift, NEXT,
|
|
|
|
|
|
|
|
KEY_V, BOTH, XKB_KEY_p, FINISH));
|
|
|
|
|
2012-09-21 07:30:01 -06:00
|
|
|
xkb_keymap_unref(keymap);
|
|
|
|
assert(ctx);
|
|
|
|
keymap = test_compile_rules(ctx, "evdev", "", "us,il,ru", "",
|
|
|
|
"grp:alt_shift_toggle_bidir,grp:menu_toggle");
|
|
|
|
assert(keymap);
|
|
|
|
|
|
|
|
assert(test_key_seq(keymap,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_LEFTALT, DOWN, XKB_KEY_ISO_Prev_Group, NEXT,
|
|
|
|
KEY_LEFTALT, UP, XKB_KEY_ISO_Prev_Group, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, FINISH));
|
|
|
|
|
|
|
|
assert(test_key_seq(keymap,
|
|
|
|
KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_ISO_Prev_Group, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_ISO_Prev_Group, NEXT,
|
|
|
|
KEY_LEFTALT, UP, XKB_KEY_Alt_L, FINISH));
|
|
|
|
|
|
|
|
/* Check backwards (negative) group switching and wrapping. */
|
|
|
|
assert(test_key_seq(keymap,
|
|
|
|
KEY_H, BOTH, XKB_KEY_h, NEXT,
|
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
|
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_LEFTALT, BOTH, XKB_KEY_ISO_Prev_Group, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_LEFTALT, BOTH, XKB_KEY_ISO_Prev_Group, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_H, BOTH, XKB_KEY_h, NEXT,
|
|
|
|
KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_LEFTALT, BOTH, XKB_KEY_ISO_Prev_Group, NEXT,
|
|
|
|
KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
|
|
|
|
KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT,
|
|
|
|
KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
|
|
|
|
KEY_H, BOTH, XKB_KEY_h, FINISH));
|
|
|
|
|
2012-09-21 05:44:17 -06:00
|
|
|
xkb_keymap_unref(keymap);
|
2012-04-10 12:20:27 -06:00
|
|
|
xkb_context_unref(ctx);
|
|
|
|
return 0;
|
|
|
|
}
|