[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] How to send Ctrl+Alt+F1 to guest OS?
From: |
Fabrice Bellard |
Subject: |
Re: [Qemu-devel] How to send Ctrl+Alt+F1 to guest OS? |
Date: |
Fri, 20 Feb 2004 00:51:10 +0100 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624 |
I tried something like this (see attached patch), but it does not work
reliably. It seems that the X11 server does not always interpret the
XChangeKeyboardMapping() function.
Does anyone have a solution ?
WARNING: if you try this patch, save your keyboard mapping with 'xmodmap
-pke' before !
Fabrice.
Index: sdl.c
===================================================================
RCS file: /cvsroot/qemu/qemu/sdl.c,v
retrieving revision 1.4
diff -u -w -r1.4 sdl.c
--- sdl.c 6 Feb 2004 19:56:42 -0000 1.4
+++ sdl.c 19 Feb 2004 23:44:07 -0000
@@ -42,6 +42,15 @@
#include <SDL.h>
+#if defined(__linux__)
+#define HAVE_X11
+#endif
+
+#ifdef HAVE_X11
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#endif
+
#include "cpu.h"
#include "exec-all.h"
@@ -165,8 +174,123 @@
}
}
+#ifdef HAVE_X11
+
+#define NB_REDEFINED_KEYCODES 12
+#define KEYCODE_MIN 67
+#define KEYCODE_MAX 96
+
+static int redefined_keycodes[NB_REDEFINED_KEYCODES] = {
+ 67, /* F1 */
+ 68,
+ 69,
+ 70,
+ 71,
+ 72,
+ 73,
+ 74,
+ 75,
+ 76, /* F10 */
+ 95, /* F11 */
+ 96, /* F12 */
+#if 0
+ 22, /* backspace (not enabled for easier abort) */
+#endif
+};
+
+static KeySym qemu_keysyms[NB_REDEFINED_KEYCODES] = {
+ XK_F1,
+ XK_F2,
+ XK_F3,
+ XK_F4,
+ XK_F5,
+ XK_F6,
+ XK_F7,
+ XK_F8,
+ XK_F9,
+ XK_F10,
+ XK_F11,
+ XK_F12,
+#if 0
+ XK_BackSpace,
+#endif
+};
+
+static KeySym *saved_keysyms, *new_keysyms;
+static int saved_nb_keysyms;
+static int mappings_modified;
+static Display *x11_dpy;
+
+static void change_x11_mappings(void)
+{
+ int i, j, k;
+
+ if (!x11_dpy)
+ x11_dpy = XOpenDisplay(NULL);
+
+ if (!saved_keysyms) {
+ /* save F1-F12 mappings and X11 specific mappings. We do only
+ one XGetKeyboardMapping and XSetKeyboardMapping because the
+ X11 server is not able to hangdle many mapping change at
+ once. */
+ saved_keysyms = XGetKeyboardMapping(x11_dpy,
+ KEYCODE_MIN,
+ KEYCODE_MAX - KEYCODE_MIN + 1,
+ &saved_nb_keysyms);
+#if 1
+ for(i = 0; i < NB_REDEFINED_KEYCODES; i++) {
+ printf("keycode %d = ", redefined_keycodes[i]);
+ k = (redefined_keycodes[i] - KEYCODE_MIN) * saved_nb_keysyms;
+ for(j=0;j<saved_nb_keysyms;j++)
+ printf(" 0x%lx", saved_keysyms[k + j]);
+ printf("\n");
+ }
+#endif
+ new_keysyms = malloc(sizeof(KeySym) *
+ (KEYCODE_MAX - KEYCODE_MIN + 1) *
+ saved_nb_keysyms);
+ memcpy(new_keysyms, saved_keysyms,
+ sizeof(KeySym) *
+ (KEYCODE_MAX - KEYCODE_MIN + 1) * saved_nb_keysyms);
+ /* redefine the QEMU keycodes */
+ for(i = 0; i < NB_REDEFINED_KEYCODES; i++) {
+ k = (redefined_keycodes[i] - KEYCODE_MIN) * saved_nb_keysyms;
+ saved_keysyms[k] = qemu_keysyms[i];
+ for(j = 1; j < saved_nb_keysyms; j++)
+ saved_keysyms[k + j] = NoSymbol;
+ }
+ }
+
+ if (!mappings_modified) {
+ XChangeKeyboardMapping(x11_dpy,
+ KEYCODE_MIN,
+ saved_nb_keysyms,
+ new_keysyms,
+ KEYCODE_MAX - KEYCODE_MIN + 1);
+ XFlush(x11_dpy);
+ mappings_modified = 1;
+ }
+}
+
+static void restore_x11_mappings(void)
+{
+ if (mappings_modified) {
+ XChangeKeyboardMapping(x11_dpy,
+ KEYCODE_MIN,
+ saved_nb_keysyms,
+ saved_keysyms,
+ KEYCODE_MAX - KEYCODE_MIN + 1);
+ XFlush(x11_dpy);
+ mappings_modified = 0;
+ }
+}
+#endif
+
static void sdl_grab_start(void)
{
+#ifdef HAVE_X11
+ change_x11_mappings();
+#endif
SDL_WM_SetCaption("QEMU - Press Ctrl-Shift to exit grab", "QEMU");
SDL_ShowCursor(0);
SDL_WM_GrabInput(SDL_GRAB_ON);
@@ -180,6 +304,9 @@
SDL_WM_SetCaption("QEMU", "QEMU");
SDL_WM_GrabInput(SDL_GRAB_OFF);
SDL_ShowCursor(1);
+#ifdef HAVE_X11
+ restore_x11_mappings();
+#endif
gui_grab = 0;
}
@@ -260,6 +387,9 @@
static void sdl_cleanup(void)
{
+#ifdef HAVE_X11
+ restore_x11_mappings();
+#endif
SDL_Quit();
}