From: Mark Jonckheere <marc.jonckheere@easynet.be>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] keyboard shift-state problem
Date: Tue, 18 May 2004 02:21:39 +0200 [thread overview]
Message-ID: <40A95713.3050908@easynet.be> (raw)
When the operator switches from qemu to another window while keeping one
of the shift-keys (Shift, Ctrl, Alt) depressed (for example using Alt-TAB),
qemu doesn't receive a Key-UP event for this shift-key. The result is that
when the operator returns back to qemu, the guest OS accepts new keystrokes
as if that shift-key is still depressed.
A solution to this problem is storing the shift-state as every shift-key
is depressed and released, and sending extra key-events when control is
transferred to another window.
I detected that in this case SDL sends a keyboard event with a zero
scancode, so it is easy to detect when the shift-state should be adjusted.
This has been tested on a RedHat 7.3 host (x86) with SDL version
1.2.3-7, it should be verified for other host environments.
A second problem is the CapsLock and Numlock state. I detected that
SDL handles these keys as shift-keys and not as toggles. Depressing
and releasing one of those keys generates only a single event with
alternating key down and key up codes. To turn CapsLock on and again
off, you had to depress that key 4 times. I made a modification to
translate this single event into a key-down, key-up sequence.
This works well for CapsLock, but it can put NumLock into the opposite
state between the host OS and the guest OS. This results in depressing
the NumLock key by the operator at every switch between windows.
There is no simple solution for this problem. One possible solution is
to keep track of the commands from the guest OS to change the state of
the keyboard LEDs and change the state of the host according to these.
Or keeping track of the guest Numlock LED and sending back a Numlock
down-up sequence before each key if the state is different from the host
state.
Another solution is to add a command to change the NumLock state
from the monitor.
Or simply leaving it as it was and documenting to the end-user
that "To change the Numlock or CapsLock state, you should depress
those keys twice".
Greetings,
Mark.
---8<----------------------------------------------------->8---
--- qemu/sdl.c Fri Apr 30 00:15:15 2004
+++ qemu.patched/sdl.c Tue May 18 00:34:19 2004
@@ -130,6 +130,7 @@
static void sdl_process_key(SDL_KeyboardEvent *ev)
{
int keycode, v;
+ static int modif;
/* XXX: not portable, but avoids complicated mappings */
keycode = ev->keysym.scancode;
@@ -151,6 +152,78 @@
keycode = 0;
}
+ /* Adjust shift-key states when leaving window */
+
+ if (ev->keysym.scancode == 0) {
+ if ((modif ^ ev->keysym.mod) & KMOD_LSHIFT)
+ kbd_put_keycode(0x2a | (modif & KMOD_LSHIFT ? 0x80 : 0));
+ if ((modif ^ ev->keysym.mod) & KMOD_RSHIFT)
+ kbd_put_keycode(0x36 | (modif & KMOD_RSHIFT ? 0x80 : 0));
+ if ((modif ^ ev->keysym.mod) & KMOD_LCTRL)
+ kbd_put_keycode(0x1d | (modif & KMOD_LCTRL ? 0x80 : 0));
+ if ((modif ^ ev->keysym.mod) & KMOD_RCTRL) {
+ kbd_put_keycode(0xe0 );
+ kbd_put_keycode(0x1d | (modif & KMOD_RCTRL ? 0x80 : 0));
+ }
+ if ((modif ^ ev->keysym.mod) & KMOD_LALT)
+ kbd_put_keycode(0x38 | (modif & KMOD_LALT ? 0x80 : 0));
+ if ((modif ^ ev->keysym.mod) & KMOD_RALT) {
+ kbd_put_keycode(0xe0 );
+ kbd_put_keycode(0x38 | (modif & KMOD_RALT ? 0x80 : 0));
+ }
+ modif = ev->keysym.mod;
+ }
+
+ /* remember shift-key state */
+
+ switch (keycode) {
+ case 0x2a: /* Left Shift */
+ if (ev->type == SDL_KEYUP)
+ modif &= ~KMOD_LSHIFT;
+ else
+ modif |= KMOD_LSHIFT;
+ break;
+ case 0x36: /* Right Shift */
+ if (ev->type == SDL_KEYUP)
+ modif &= ~KMOD_RSHIFT;
+ else
+ modif |= KMOD_RSHIFT;
+ break;
+ case 0x1d: /* Left CTRL */
+ if (ev->type == SDL_KEYUP)
+ modif &= ~KMOD_LCTRL;
+ else
+ modif |= KMOD_LCTRL;
+ break;
+ case 0x1de0: /* Right CTRL */
+ if (ev->type == SDL_KEYUP)
+ modif &= ~KMOD_RCTRL;
+ else
+ modif |= KMOD_RCTRL;
+ break;
+ case 0x38: /* Left ALT */
+ if (ev->type == SDL_KEYUP)
+ modif &= ~KMOD_LALT;
+ else
+ modif |= KMOD_LALT;
+ break;
+ case 0x38e0: /* Right ALT */
+ if (ev->type == SDL_KEYUP)
+ modif &= ~KMOD_RALT;
+ else
+ modif |= KMOD_RALT;
+ break;
+ case 0x45: /* Num Lock */
+ kbd_put_keycode(0x45);
+ kbd_put_keycode(0xc5);
+ return;
+ case 0x3a: /* Caps Lock */
+ kbd_put_keycode(0x3a);
+ kbd_put_keycode(0xba);
+ return;
+
+ }
+
/* now send the key code */
while (keycode != 0) {
v = keycode & 0xff;
---8<----------------------------------------------------->8---
next reply other threads:[~2004-05-17 23:41 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-05-18 0:21 Mark Jonckheere [this message]
2004-05-18 4:00 ` [Qemu-devel] keyboard shift-state problem Mulyadi Santosa
2004-05-19 1:37 ` kazu
2004-05-19 3:40 ` Mulyadi Santosa
2004-05-20 8:59 ` kazu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=40A95713.3050908@easynet.be \
--to=marc.jonckheere@easynet.be \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).