* [Qemu-devel] Keyboard handling patch
@ 2004-07-30 11:10 Johannes Martin
0 siblings, 0 replies; only message in thread
From: Johannes Martin @ 2004-07-30 11:10 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1167 bytes --]
Hi,
the attached patch helps with two things:
- keys no longer stick when leaving/entering the qemu window
(I send part of that patch before, the most common problem was that
ctrl/shift would stick when leaving grab mode)
- qemu can now handle the modifier keys caps and num lock for the
guest operating system. This is useful for two reasons:
- some guest OSs crash when modifier keys change their state
suddenly (i.e. caps lock is pressed when leaving the window
and depressed when entering the window again)
- on some national keyboards and some OSes, caps lock isn't
reset by pushing caps lock again but by pushing one of the
shift keys. This would result in the caps lock led not showing
the actual caps lock state of the guest OS.
I have added another command line option -sdl-mods. If this option is
used, qemu will not report caps and num lock to the guest os but
simulate a pushed-down shift key before any alpha-key while caps lock
is down and before any key of the numeric keypad when num lock is down.
I have tested this patch for some time on OS/2 and it works fine.
Johannes
[-- Attachment #2: Type: TEXT/PLAIN, Size: 5976 bytes --]
Index: sdl.c
===================================================================
RCS file: /cvsroot/qemu/qemu/sdl.c,v
retrieving revision 1.16
diff -c -r1.16 sdl.c
*** sdl.c 14 Jul 2004 17:22:33 -0000 1.16
--- sdl.c 30 Jul 2004 11:01:16 -0000
***************
*** 301,306 ****
--- 301,307 ----
if (i & 0x80)
kbd_put_keycode(0xe0);
kbd_put_keycode(i | 0x80);
+ modifiers_state[i] = 0;
}
}
return;
***************
*** 317,328 ****
break;
case 0x45: /* num lock */
case 0x3a: /* caps lock */
! /* SDL does not send the key up event, so we generate it */
! kbd_put_keycode(keycode);
! kbd_put_keycode(keycode | 0x80);
! return;
}
/* now send the key code */
if (keycode & 0x80)
kbd_put_keycode(0xe0);
--- 318,340 ----
break;
case 0x45: /* num lock */
case 0x3a: /* caps lock */
! if (!sdl_mods) {
! /* SDL does not send the key up event, so we generate it */
! kbd_put_keycode(keycode);
! kbd_put_keycode(keycode | 0x80);
! }
! return;
}
+ if (sdl_mods && (ev->type == SDL_KEYDOWN) &&
+ (((SDL_GetModState() & KMOD_CAPS) &&
+ (ev->keysym.sym >= 'a') &&
+ (ev->keysym.sym <= 'z')) |
+ ((SDL_GetModState() & KMOD_NUM) &&
+ (ev->keysym.sym >= SDLK_KP0) &&
+ (ev->keysym.sym <= SDLK_KP_EQUALS))))
+ kbd_put_keycode(0x2a);
+
/* now send the key code */
if (keycode & 0x80)
kbd_put_keycode(0xe0);
***************
*** 330,335 ****
--- 342,371 ----
kbd_put_keycode(keycode | 0x80);
else
kbd_put_keycode(keycode & 0x7f);
+
+ if (sdl_mods && (ev->type == SDL_KEYDOWN) &&
+ (((SDL_GetModState() & KMOD_CAPS) &&
+ (ev->keysym.sym >= 'a') &&
+ (ev->keysym.sym <= 'z')) |
+ ((SDL_GetModState() & KMOD_NUM) &&
+ (ev->keysym.sym >= SDLK_KP0) &&
+ (ev->keysym.sym <= SDLK_KP_EQUALS))))
+ kbd_put_keycode(0x2a | 0x80);
+
+ }
+
+ /* type: 1 - down, 2 - up, 3 - down/up */
+ static void sdl_fake_key(int type, SDLKey keysym) {
+ SDL_KeyboardEvent ev;
+ ev.keysym.sym = keysym;
+ if (type & 1) {
+ ev.type = SDL_KEYDOWN;
+ sdl_process_key(&ev);
+ }
+ if (type & 2) {
+ ev.type = SDL_KEYUP;
+ sdl_process_key(&ev);
+ }
}
static void sdl_update_caption(void)
***************
*** 491,497 ****
sdl_grab_start();
else
sdl_grab_end();
- break;
}
gui_key_modifier_pressed = 0;
gui_keysym = 0;
--- 527,532 ----
***************
*** 525,530 ****
--- 560,580 ----
}
break;
case SDL_ACTIVEEVENT:
+ if (is_active_console(vga_console))
+ /* if gaining or losing input focus, check which keys are
+ currently pressed and key down (gain) resp. key up (lose)
+ for all those keys so we don't end up with stuck keys
+ in the guest */
+ if (ev->active.state & SDL_APPINPUTFOCUS) {
+ int numkeys;
+ Uint8* keystate;
+ keystate = SDL_GetKeyState(&numkeys);
+ while (numkeys-- > 0)
+ if (keystate[numkeys])
+ sdl_fake_key(ev->active.gain ? 1 : 2, numkeys);
+ if (!ev->active.gain)
+ sdl_fake_key(1, 0);
+ }
if (gui_grab && (ev->active.gain & SDL_ACTIVEEVENTMASK) == 0) {
sdl_grab_end();
}
Index: vl.c
===================================================================
RCS file: /cvsroot/qemu/qemu/vl.c,v
retrieving revision 1.90
diff -c -r1.90 vl.c
*** vl.c 14 Jul 2004 17:27:31 -0000 1.90
--- vl.c 30 Jul 2004 11:01:21 -0000
***************
*** 135,140 ****
--- 135,141 ----
int prep_enabled = 0;
int rtc_utc = 1;
int cirrus_vga_enabled = 1;
+ int sdl_mods = 0;
int graphic_width = 800;
int graphic_height = 600;
int graphic_depth = 15;
***************
*** 2369,2374 ****
--- 2370,2376 ----
"-std-vga simulate a standard VGA card with VESA Bochs Extensions\n"
" (default is CL-GD5446 PCI VGA)\n"
#endif
+ "-sdl-mods handle caps/num lock in emulator (not guest)\n"
"\n"
"During emulation, the following keys are useful:\n"
"ctrl-shift-f toggle full screen\n"
***************
*** 2438,2443 ****
--- 2440,2446 ----
QEMU_OPTION_cirrusvga,
QEMU_OPTION_g,
QEMU_OPTION_std_vga,
+ QEMU_OPTION_sdl_mods,
QEMU_OPTION_monitor,
QEMU_OPTION_serial,
};
***************
*** 2491,2496 ****
--- 2494,2500 ----
{ "localtime", 0, QEMU_OPTION_localtime },
{ "isa", 0, QEMU_OPTION_isa },
{ "std-vga", 0, QEMU_OPTION_std_vga },
+ { "sdl-mods", 0, QEMU_OPTION_sdl_mods },
{ "monitor", 1, QEMU_OPTION_monitor },
{ "serial", 1, QEMU_OPTION_serial },
***************
*** 2792,2797 ****
--- 2796,2804 ----
case QEMU_OPTION_std_vga:
cirrus_vga_enabled = 0;
break;
+ case QEMU_OPTION_sdl_mods:
+ sdl_mods = 1;
+ break;
case QEMU_OPTION_g:
{
const char *p;
Index: vl.h
===================================================================
RCS file: /cvsroot/qemu/qemu/vl.h,v
retrieving revision 1.49
diff -c -r1.49 vl.h
*** vl.h 14 Jul 2004 17:27:33 -0000 1.49
--- vl.h 30 Jul 2004 11:01:23 -0000
***************
*** 238,243 ****
--- 238,244 ----
extern int bios_size;
extern int rtc_utc;
extern int cirrus_vga_enabled;
+ extern int sdl_mods;
extern int graphic_width;
extern int graphic_height;
extern int graphic_depth;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-07-30 11:14 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-30 11:10 [Qemu-devel] Keyboard handling patch Johannes Martin
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).