struct key_range *numlock_range;
struct key_range *shift_range;
struct key_range *localstate_range;
+ struct key_range *altgr_range;
} kbd_layout_t;
static void add_to_key_range(struct key_range **krp, int code) {
add_to_key_range(&k->localstate_range, keycode);
//fprintf(stderr, "localstate keysym %04x keycode %d\n", keysym, keycode);
}
-
+ if (rest && strstr(rest, "altgr")) {
+ add_to_key_range(&k->altgr_range, keysym);
+ //fprintf(stderr, "altgr keysym %04x keycode %d\n", keysym, keycode);
+ }
+
/* if(keycode&0x80)
keycode=(keycode<<8)^0x80e0; */
if (keysym < MAX_NORMAL_KEYCODE) {
return 0;
return 1;
}
+
+static inline int keysym_is_altgr(void *kbd_layout, int keysym)
+{
+ kbd_layout_t *k = kbd_layout;
+ struct key_range *kr;
+
+ for (kr = k->altgr_range; kr; kr = kr->next)
+ if (keysym >= kr->start && keysym <= kr->end){
+ return 1;
+ }
+ return 0;
+}
+
}
}
+static void press_key_altgr_down(VncState *vs, int down)
+{
+ kbd_put_keycode(0xe0);
+ if (down){
+ kbd_put_keycode(0xb8 & 0x7f);
+ vs->modifiers_state[0xb8] = 1;
+ }
+ else {
+ kbd_put_keycode(0xb8 | 0x80);
+ vs->modifiers_state[0xb8] = 0;
+ }
+}
+
static void do_key_event(VncState *vs, int down, uint32_t sym)
{
int keycode;
int shift_keys = 0;
int shift = 0;
int keypad = 0;
+ int altgr = 0;
+ int altgr_keys = 0;
if (is_graphic_console()) {
if (sym >= 'A' && sym <= 'Z') {
else {
shift = keysym_is_shift(vs->kbd_layout, sym & 0xFFFF);
}
+
+ altgr = keysym_is_altgr(vs->kbd_layout, sym & 0xFFFF);
}
shift_keys = vs->modifiers_state[0x2a] | vs->modifiers_state[0x36];
+ altgr_keys = vs->modifiers_state[0xb8];
keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
if (keycode == 0) {
}
if (is_graphic_console()) {
+
+ if (altgr && !altgr_keys) {
+ press_key_altgr_down(vs, down);
+ }
+
/* If the shift state needs to change then simulate an additional
keypress before sending this one. Ignore for non shiftable keys.
*/