qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Brad Campbell <brad@wasp.net.au>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] USB Tablet Emulation
Date: Mon, 10 Apr 2006 12:23:05 +0400	[thread overview]
Message-ID: <443A15E9.4060806@wasp.net.au> (raw)
In-Reply-To: <4439D396.6010006@us.ibm.com>

[-- Attachment #1: Type: text/plain, Size: 864 bytes --]

Anthony Liguori wrote:
> I spent some time cleaning this all up.  The following integrates Brad's 
> patches and the patch from 
> http://gnome.dnsalias.net/patches/qemu-hidmousexp.patch
> 
> It adds a new emulated USB device that reports absolute coordinates.  It 
> also modifies SDL to operate in grabless mode when an absolute input 
> device is enabled.  I think it's pretty close to apply-able.  To use, 
> just specify: -usbdevice tablet
> 
> With Xorg from CVS, the evdev driver segfaults.  This is apparently 
> expected behavior.  Hopefully it will be fixed soon.  It works quite 
> nicely under Win2k.

Here is the vnc patch to go on top of that and the latest cvs.


-- 
"Human beings, who are almost unique in having the ability
to learn from the experience of others, are also remarkable
for their apparent disinclination to do so." -- Douglas Adams

[-- Attachment #2: qemu-rfb-bkc-001.patch --]
[-- Type: text/plain, Size: 37140 bytes --]

diff -urN -x CVS qemu-clean/configure qemu/configure
--- qemu-clean/configure	2006-04-09 23:06:58.000000000 +0400
+++ qemu/configure	2006-04-10 11:08:05.000000000 +0400
@@ -181,6 +181,8 @@
   ;;
   --disable-sdl) sdl="no"
   ;;
+  --disable-vnc) vnc="no"
+  ;;
   --enable-coreaudio) coreaudio="yes"
   ;;
   --enable-alsa) alsa="yes"
@@ -240,6 +242,8 @@
 echo "  --interp-prefix=PREFIX   where to find shared libraries, etc."
 echo "                           use %M for cpu name [$interp_prefix]"
 echo "  --target-list=LIST       set target list [$target_list]"
+echo "  --disable-vnc            disable vnc support (else configure checks"
+echo "                           for libvncserver-config in your PATH)"
 echo ""
 echo "kqemu kernel acceleration support:"
 echo "  --disable-kqemu          disable kqemu support"
@@ -363,6 +367,19 @@
 fi
 
 ##########################################
+# VNC probe
+
+if test -z "$vnc"; then
+
+if libvncserver-config --version > /dev/null; then
+    vnc=yes
+else
+    vnc=no
+fi
+
+fi
+
+##########################################
 # SDL probe
 
 sdl_too_old=no
@@ -448,6 +465,7 @@
 echo "gprof enabled     $gprof"
 echo "profiler          $profiler"
 echo "static build      $static"
+echo "VNC support       $vnc"
 if test "$darwin" = "yes" ; then
     echo "Cocoa support     $cocoa"
 fi
@@ -561,6 +579,8 @@
 if test "$darwin" = "yes" ; then
   echo "CONFIG_DARWIN=yes" >> $config_mak
   echo "#define CONFIG_DARWIN 1" >> $config_h
+  echo "#define socklen_t int" >> $config_h
+  echo "#define sqrtf sqrt" >> $config_h
 fi
 if test "$gdbstub" = "yes" ; then
   echo "CONFIG_GDBSTUB=yes" >> $config_mak
@@ -624,6 +644,16 @@
   echo "#define _BSD 1" >> $config_h
 fi
 
+if test "$vnc" = "yes"; then
+  echo "CONFIG_VNC=yes" >> $config_mak
+  echo "VNC_CFLAGS=`libvncserver-config --cflags`" >> $config_mak
+fi
+
+if test "$sdl" = "yes"; then
+  echo "CONFIG_SDL=yes" >> $config_mak
+  echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
+fi
+
 for target in $target_list; do
 
 target_dir="$target"
@@ -735,13 +765,22 @@
   echo "#define CONFIG_USER_ONLY 1" >> $config_h
 fi
 
+if test "$target_user_only" = "no"; then
+    if test "$vnc" = "yes"; then
+	echo "#define CONFIG_VNC 1" >> $config_h
+	echo "CONFIG_VNC=yes" >> $config_mak
+	echo "VNC_CFLAGS=`libvncserver-config --cflags`" >> $config_mak
+	echo "VNC_LIBS=`libvncserver-config --libs`" >> $config_mak
+    fi
+fi
+
 if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" ; then
   echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
   echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
 fi
 # sdl defines
 
-if test "$target_user_only" = "no"; then
+if test "$sdl" = "yes" -a "$target_user_only" = "no"; then
     if test "$target_softmmu" = "no" -o "$static" = "yes"; then
         sdl1=$sdl_static
     else
diff -urN -x CVS qemu-clean/hw/pckbd.c qemu/hw/pckbd.c
--- qemu-clean/hw/pckbd.c	2006-04-09 23:07:05.000000000 +0400
+++ qemu/hw/pckbd.c	2006-04-10 11:07:37.000000000 +0400
@@ -333,7 +333,11 @@
 static void kbd_save(QEMUFile* f, void* opaque)
 {
     KBDState *s = (KBDState*)opaque;
-    
+
+    /* release alt, ctrl */
+    kbd_put_keycode(0x38|0x80); /* alt */
+    kbd_put_keycode(0x1d|0x80); /* ctrl */
+
     qemu_put_8s(f, &s->write_cmd);
     qemu_put_8s(f, &s->status);
     qemu_put_8s(f, &s->mode);
diff -urN -x CVS qemu-clean/keymaps.c qemu/keymaps.c
--- qemu-clean/keymaps.c	2006-04-09 23:06:58.000000000 +0400
+++ qemu/keymaps.c	2006-04-10 11:07:37.000000000 +0400
@@ -93,6 +93,12 @@
 		    if (keysym < MAX_NORMAL_KEYCODE) {
 			//fprintf(stderr,"Setting keysym %s (%d) to %d\n",line,keysym,keycode);
 			k->keysym2keycode[keysym] = keycode;
+#ifdef KEYBOARD_HANDLE_UPPER_CASE
+			line[0]=toupper(line[0]);
+			keysym=get_keysym(line);
+			if(keysym)
+			    k->keysym2keycode[keysym]=keycode;
+#endif
 		    } else {
 			if (k->extra_count >= MAX_EXTRA_COUNT) {
 			    fprintf(stderr,
diff -urN -x CVS qemu-clean/Makefile.target qemu/Makefile.target
--- qemu-clean/Makefile.target	2006-04-10 02:03:49.000000000 +0400
+++ qemu/Makefile.target	2006-04-10 11:07:37.000000000 +0400
@@ -345,6 +345,9 @@
 ifdef CONFIG_GDBSTUB
 VL_OBJS+=gdbstub.o 
 endif
+ifdef CONFIG_VNC
+VL_OBJS+=vnc.o
+endif
 ifdef CONFIG_SDL
 VL_OBJS+=sdl.o
 endif
@@ -390,7 +393,10 @@
 endif
 
 $(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
-	$(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS)
+	$(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VNC_LIBS) $(VL_LIBS)
+
+vnc.o: vnc.c keymaps.c vnc_keysym.h
+	$(CC) $(CFLAGS) $(DEFINES) $(VNC_CFLAGS) $(SDL_CFLAGS) -c -o $@ $<
 
 cocoa.o: cocoa.m
 	$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
@@ -401,6 +407,9 @@
 sdlaudio.o: sdlaudio.c
 	$(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $<
 
+vl.o: vl.c
+	$(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $<
+
 depend: $(SRCS)
 	$(CC) -MM $(CFLAGS) $(DEFINES) $^ 1>.depend
 
diff -urN -x CVS qemu-clean/monitor.c qemu/monitor.c
--- qemu-clean/monitor.c	2006-04-09 23:06:59.000000000 +0400
+++ qemu/monitor.c	2006-04-10 11:07:37.000000000 +0400
@@ -69,7 +69,10 @@
 void term_flush(void)
 {
     if (term_outbuf_index > 0) {
+	if(monitor_hd)
         qemu_chr_write(monitor_hd, term_outbuf, term_outbuf_index);
+	else
+	    fwrite(term_outbuf, term_outbuf_index, 1, stderr);
         term_outbuf_index = 0;
     }
 }
diff -urN -x CVS qemu-clean/sdl.c qemu/sdl.c
--- qemu-clean/sdl.c	2006-04-10 12:10:47.000000000 +0400
+++ qemu/sdl.c	2006-04-10 11:07:37.000000000 +0400
@@ -44,6 +44,10 @@
 static SDL_Cursor *sdl_cursor_hidden;
 static int absolute_enabled = 0;
 
+SDL_PixelFormat* sdl_get_format() {
+	return screen->format;
+}
+
 static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
 {
     //    printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
diff -urN -x CVS qemu-clean/slirp/main.h qemu/slirp/main.h
--- qemu-clean/slirp/main.h	2006-04-09 23:07:05.000000000 +0400
+++ qemu/slirp/main.h	2006-04-10 11:07:37.000000000 +0400
@@ -9,6 +9,8 @@
 #include <sys/select.h>
 #endif
 
+#include <inttypes.h>
+
 #define TOWRITEMAX 512
 
 extern struct timeval tt;
diff -urN -x CVS qemu-clean/vl.c qemu/vl.c
--- qemu-clean/vl.c	2006-04-10 12:10:47.000000000 +0400
+++ qemu/vl.c	2006-04-10 11:07:37.000000000 +0400
@@ -72,7 +72,7 @@
 
 #ifdef CONFIG_SDL
 #ifdef __APPLE__
-#include <SDL/SDL.h>
+#include "SDL.h"
 #endif
 #endif /* CONFIG_SDL */
 
@@ -117,6 +117,8 @@
 int bios_size;
 static DisplayState display_state;
 int nographic;
+int usevnc; /* 1=vnc only, 2=vnc and sdl */
+int vnc_port = 0;
 const char* keyboard_layout = NULL;
 int64_t ticks_per_sec;
 int boot_device = 'c';
@@ -4142,6 +4144,13 @@
            "-m megs         set virtual RAM size to megs MB [default=%d]\n"
            "-smp n          set the number of CPUs to 'n' [default=1]\n"
            "-nographic      disable graphical output and redirect serial I/Os to console\n"
+#ifdef CONFIG_VNC
+	   "-vnc            use vnc instead of sdl\n"
+	   "-vncport <port> use this vnc port. Default is auto-choosing\n"
+#ifdef CONFIG_SDL
+	   "-vnc-and-sdl    use vnc and sdl simultaneously\n"
+#endif
+#endif
 #ifndef _WIN32
 	   "-k language     use keyboard layout (for example \"fr\" for French)\n"
 #endif
@@ -4267,7 +4276,14 @@
     QEMU_OPTION_boot,
     QEMU_OPTION_snapshot,
     QEMU_OPTION_m,
+    QEMU_OPTION_vncport,
     QEMU_OPTION_nographic,
+#ifdef CONFIG_VNC
+    QEMU_OPTION_vnc,
+#ifdef CONFIG_SDL
+    QEMU_OPTION_vnc_and_sdl,
+#endif
+#endif
 #ifdef HAS_AUDIO
     QEMU_OPTION_audio_help,
     QEMU_OPTION_soundhw,
@@ -4328,7 +4344,14 @@
     { "boot", HAS_ARG, QEMU_OPTION_boot },
     { "snapshot", 0, QEMU_OPTION_snapshot },
     { "m", HAS_ARG, QEMU_OPTION_m },
+    { "vncport", HAS_ARG, QEMU_OPTION_vncport },
     { "nographic", 0, QEMU_OPTION_nographic },
+#ifdef CONFIG_VNC
+    { "vnc", 0, QEMU_OPTION_vnc },
+#ifdef CONFIG_SDL
+    { "vnc-and-sdl", 0, QEMU_OPTION_vnc_and_sdl },
+#endif
+#endif
     { "k", HAS_ARG, QEMU_OPTION_k },
 #ifdef HAS_AUDIO
     { "audio-help", 0, QEMU_OPTION_audio_help },
@@ -4608,6 +4631,7 @@
 #endif
     snapshot = 0;
     nographic = 0;
+    usevnc = 0;
     kernel_filename = NULL;
     kernel_cmdline = "";
 #ifdef TARGET_PPC
@@ -4742,6 +4766,16 @@
                 pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
                 nographic = 1;
                 break;
+#ifdef CONFIG_VNC
+	    case QEMU_OPTION_vnc:
+		usevnc = 1;
+		break;
+#ifdef CONFIG_SDL
+	    case QEMU_OPTION_vnc_and_sdl:
+		usevnc = 2;
+		break;
+#endif
+#endif
             case QEMU_OPTION_kernel:
                 kernel_filename = optarg;
                 break;
@@ -4819,6 +4853,9 @@
                     exit(1);
                 }
                 break;
+            case QEMU_OPTION_vncport:
+                vnc_port = atoi(optarg);
+		break;
             case QEMU_OPTION_d:
                 {
                     int mask;
@@ -5125,6 +5162,13 @@
     if (nographic) {
         dumb_display_init(ds);
     } else {
+	if (usevnc) {
+#ifdef CONFIG_VNC
+	    vnc_display_init(ds, (usevnc==2));
+#else
+	    perror("qemu not configured with vnc support");
+#endif
+	} else {
 #if defined(CONFIG_SDL)
         sdl_display_init(ds, full_screen);
 #elif defined(CONFIG_COCOA)
@@ -5133,6 +5177,7 @@
         dumb_display_init(ds);
 #endif
     }
+    }
 
     monitor_hd = qemu_chr_open(monitor_device);
     if (!monitor_hd) {
diff -urN -x CVS qemu-clean/vl.h qemu/vl.h
--- qemu-clean/vl.h	2006-04-10 12:10:47.000000000 +0400
+++ qemu/vl.h	2006-04-10 11:07:37.000000000 +0400
@@ -684,6 +684,9 @@
                    unsigned long vga_ram_offset, int vga_ram_size,
                    unsigned long vga_bios_offset, int vga_bios_size);
 
+/* vnc.c */
+void vnc_display_init(DisplayState *ds, int useAlsoSDL);
+
 /* cirrus_vga.c */
 void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, 
                          unsigned long vga_ram_offset, int vga_ram_size);
@@ -757,6 +760,7 @@
 /* pckbd.c */
 
 void kbd_init(void);
+extern const char* keyboard_layout;
 
 /* mc146818rtc.c */
 
diff -urN -x CVS qemu-clean/vnc.c qemu/vnc.c
--- qemu-clean/vnc.c	1970-01-01 04:00:00.000000000 +0400
+++ qemu/vnc.c	2006-04-10 12:08:19.000000000 +0400
@@ -0,0 +1,600 @@
+/*
+ * QEMU VNC display driver (uses LibVNCServer, based on QEMU SDL driver)
+ * 
+ * Copyright (c) 2003,2004,2005 Fabrice Bellard, Matthew Mastracci,
+ * Johannes E. Schindelin, Donald D. Dugger
+ * 
+ * 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 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 "vl.h"
+
+#include <rfb/rfb.h>
+
+/* keyboard stuff */
+#include <rfb/keysym.h>
+#include "vnc_keysym.h"
+#define KEYBOARD_HANDLE_UPPER_CASE
+#include "keymaps.c"
+
+
+#ifndef _WIN32
+#include <signal.h>
+#endif
+
+static rfbScreenInfoPtr screen;
+static DisplayState* ds_sdl;
+static void* kbd_layout; // TODO: move into rfbClient
+static int ctl_keys; // Ctrl+Alt starts calibration
+
+/* mouse stuff */
+
+typedef struct mouse_magic_t {
+	/* When calibrating, mouse_calibration contains a copy of the 
+	 * current frame buffer. After a simulated mouse movement, the
+	 * update function only gets (0,y1,width,y2) as bounding box 
+	 * of the changed region, so we refine that with the help of
+	 * this copy, and then update the copy. */
+	char* calibration;
+	/* Mouse handling using VNC used to be wrong, because if moving the
+	 * mouse very fast, the pointer got even faster. The reason for this:
+	 * when the mouse sends a delta of at least 4 (Windows: 3) pixels, 
+	 * it is treated as if it were double the amount. I call this the
+	 * sonic wall. */
+	int sonic_wall_x;
+	int sonic_wall_y;
+	/* Unfortunately, Windows and X behave differently, when the sonic
+	 * wall was reached in one axis, but not the other: Windows treats
+	 * them independently. I call this orthogonal. */
+	char sonic_wall_is_orthogonal;
+	/* last_dy contains the last delta sent on the y axis. We don't
+	 * use the x axis (see mouse_calibration). */
+	//static int last_dy=0;
+} mouse_magic_t;
+
+mouse_magic_t* init_mouse_magic() {
+	mouse_magic_t* ret=(mouse_magic_t*)malloc(sizeof(mouse_magic_t));
+
+	ret->calibration=0;
+#ifdef EXPECT_WINDOWS_GUEST
+	ret->sonic_wall_x=3;
+	ret->sonic_wall_y=3;
+	ret->sonic_wall_is_orthogonal=1;
+#else
+	ret->sonic_wall_x=4;
+	ret->sonic_wall_y=4;
+	ret->sonic_wall_is_orthogonal=0;
+#endif
+	return ret;
+}
+
+static void vnc_save(QEMUFile* f,void* opaque)
+{
+	mouse_magic_t* s=(mouse_magic_t*)opaque;
+
+	qemu_put_be32s(f, &s->sonic_wall_x);
+	qemu_put_be32s(f, &s->sonic_wall_y);
+	qemu_put_8s(f, &s->sonic_wall_is_orthogonal);
+}
+
+static int vnc_load(QEMUFile* f,void* opaque,int version_id)
+{
+	mouse_magic_t* s=(mouse_magic_t*)opaque;
+
+	if (version_id != 1)
+		return -EINVAL;
+
+	qemu_get_be32s(f, &s->sonic_wall_x);
+	qemu_get_be32s(f, &s->sonic_wall_y);
+	qemu_get_8s(f, &s->sonic_wall_is_orthogonal);
+
+	return 0;
+}
+
+static mouse_magic_t* mouse_magic;
+
+typedef struct {
+	int x,y,w,h;
+} rectangle_t;
+/* In order to calibrate the mouse, we have to know about the bounding boxes
+ * of the last changes. */
+static rectangle_t last_update, before_update;
+static int updates_since_mouse=0;
+
+int mouse_maxx;
+int mouse_maxy;
+static int mouse_x,mouse_y;
+static int new_mouse_x,new_mouse_y,new_mouse_z,new_mouse_buttons;
+
+static void init_mouse(int max_x,int max_y) {
+	mouse_maxx=max_x - 1;
+	mouse_maxy=max_y - 1;
+	mouse_x=new_mouse_x=max_x/2;
+	mouse_y=new_mouse_y=max_y/2;
+	new_mouse_z=new_mouse_buttons=0;
+	mouse_magic->calibration = 0;
+}
+
+static void mouse_refresh() {
+	int dx=0,dy=0,dz=new_mouse_z;
+	static int counter=1;
+
+	/*
+	 *  Simulate lifting the mouse by pressing left <ctl><alt> together
+	 *  e.g. don't send mouse events.
+	 */
+#if 0
+	if(1) {
+		if(dx!=0) {
+			if(1 || abs(dx)<10) { dx=(dx>0?2:-2); mouse_x-=dx/2; }
+		}
+		if(dy!=0) {
+			if(1 || abs(dy)<10) { dy=(dy>0?2:-2); mouse_y-=dy/2; }
+		}
+	} else
+	if(mouse_magic->sonic_wall_is_orthogonal) {
+		if(abs(dx)>=mouse_magic->sonic_wall_x) { dx/=2; mouse_x+=dx; }
+		if(abs(dy)>=mouse_magic->sonic_wall_y) { dy/=2; mouse_y+=dy; }
+	} else {
+		if(abs(dx)>=mouse_magic->sonic_wall_x || abs(dy)>=mouse_magic->sonic_wall_y) {
+			dx/=2; mouse_x+=dx;
+			dy/=2; mouse_y+=dy;
+		}
+	}
+#endif
+	//fprintf(stderr,"sending mouse event %d,%d\n",dx,dy);
+	if (kbd_mouse_is_absolute()) {
+		dx = new_mouse_x * 0x7FFF / screen->width;
+		dy = new_mouse_y * 0x7FFF / screen->height;
+	} else {
+		if (ctl_keys == 3) {
+			mouse_x = new_mouse_x;
+			mouse_y = new_mouse_y;
+			return;
+		}
+		counter++;
+//		if(!mouse_magic->calibration && counter>=2) { counter=0; return; }
+
+		dx=new_mouse_x-mouse_x;
+		dy=new_mouse_y-mouse_y;
+	}	
+		
+//	printf("%i \n",new_mouse_buttons);
+	kbd_mouse_event(dx,dy,dz,new_mouse_buttons);
+	mouse_x+=dx;
+	mouse_y+=dy;
+	new_mouse_z=0;
+		
+	updates_since_mouse=0;
+}
+
+static int calibration_step=0;
+//static int calibration_count=0;
+
+static void mouse_find_bounding_box_of_difference(int* x,int* y,int* w,int* h) {
+	int i,j,X=*x,Y=*y,W=*w,H=*h;
+	int bpp=screen->depth/8;
+
+	*x=screen->width; *w=-*x;
+	*y=screen->height; *h=-*y;
+	for(i=X;i<X+W;i++)
+		for(j=Y;j<Y+H;j++) {
+			int offset=i*bpp+j*screen->paddedWidthInBytes;
+			if(memcmp(mouse_magic->calibration+offset,screen->frameBuffer+offset,bpp)) {
+				if(i<((*x))) { (*w)+=(*x)-i; (*x)=i; }
+				if(i>(*x)+(*w)) (*w)=i-(*x);
+				if(j<(*y)) { (*h)+=(*y)-j; (*y)=j; }
+				if(j>(*y)+(*h)) (*h)=j-(*y); 
+			}
+		}
+	if(h>0)
+		memcpy(mouse_magic->calibration+Y*screen->paddedWidthInBytes,
+				screen->frameBuffer+Y*screen->paddedWidthInBytes,
+				H*screen->paddedWidthInBytes);
+}
+
+static void start_mouse_calibration() {
+	int size = screen->height*screen->paddedWidthInBytes;
+	if(mouse_magic->calibration)
+		free(mouse_magic->calibration);
+	mouse_magic->calibration = malloc(size);
+	memcpy(mouse_magic->calibration, screen->frameBuffer, size);
+	calibration_step=0;
+	// calibration_count=-1;
+	//calibration_count=1000; updates_since_mouse=1;
+	term_printf("Starting mouse calibration:\n");
+}
+
+static void stop_mouse_calibration() {
+	if(mouse_magic->calibration)
+		free(mouse_magic->calibration);
+	mouse_magic->calibration = 0;
+}
+
+#if 0
+static void adjust_last_update(int x,int y,int w,int h,char enlarge)
+{
+	if(enlarge && !(last_update.w<=0 || last_update.h<=0)) {
+		if(w<=0||h<=0)
+			return;
+		if(x<last_update.x) { last_update.w+=last_update.x-x; last_update.x=x; }
+		if(x+w>last_update.x+last_update.w) { last_update.w=x+w-last_update.w; }
+		if(y<last_update.y) { last_update.h+=last_update.y-y; last_update.y=y; }
+		if(y+h>last_update.y+last_update.h) { last_update.h=y+h-last_update.h; }
+	} else {
+		last_update.x=x;
+		last_update.y=y;
+		last_update.w=w;
+		last_update.h=h;
+	}
+}
+#endif
+
+static void mouse_calibration_update(int x,int y,int w,int h) {
+	mouse_find_bounding_box_of_difference(&x,&y,&w,&h);
+	if(w<=0 || h<=0)
+		return;
+	last_update.x=x;
+	last_update.y=y;
+	last_update.w=w;
+	last_update.h=h;
+	updates_since_mouse++;
+#if 0
+	adjust_last_update(x,y,w,h,(updates_since_mouse>1));
+	if(last_dy<0) {
+		fprintf(stderr,"\t\t\tcount: %d, dy: %d, real_dy: %d\n",
+				updates_since_mouse,last_dy,y-before_update.y);
+	} else if (last_dy>0) {
+		fprintf(stderr,"\t\t\tcount: %d, dy: %d, real_dy: %d\n",
+				updates_since_mouse,last_dy,y+h-before_update.y-before_update.h);
+	} //else
+		fprintf(stderr,"got update with last_dy=%d: %d,%d - %d,%d\n",
+				last_dy,x,y,w,h);
+#endif
+}
+
+static void mouse_calibration_refresh() {
+	static rectangle_t cursor;
+	static int x,y;
+	static int idle_counter;
+	//fprintf(stderr,"refresh: %d\n",updates_since_mouse);
+
+	if(calibration_step==0)
+		idle_counter=0;
+	else {
+		idle_counter++;
+		if(idle_counter<10)
+			return;
+		idle_counter=0;
+		if(updates_since_mouse!=1) {
+			term_printf("Calibration failed: updates=%d\n",updates_since_mouse);
+			stop_mouse_calibration();
+			return;
+		}
+	}
+	/* fprintf(stderr,"step: %d\n",calibration_step);
+	fprintf(stderr,"-%d,%d,%d,%d\n",
+			before_update.x,before_update.y,before_update.w,before_update.h);
+	fprintf(stderr,"+%d,%d,%d,%d\n",
+			last_update.x,last_update.y,last_update.w,last_update.h);
+	*/
+	if(calibration_step==0) {
+		x=0; y=1;
+		kbd_mouse_event(0,-1,0,0);
+		calibration_step++;
+	} else if(calibration_step==1) {
+		// find out the initial position of the cursor
+		cursor=last_update;
+		cursor.h--;
+		calibration_step++;
+		mouse_magic->sonic_wall_y=-1;
+		last_update=cursor;
+		x=0; y=2;
+		goto move_calibrate;
+	} else if(calibration_step==2) {
+		// find out the sonic_wall
+		if(last_update.y==before_update.y-2*y) {
+			mouse_magic->sonic_wall_y=y;
+			// test orthogonality
+			calibration_step++;
+			x=mouse_magic->sonic_wall_y+1; y=1;
+			goto move_calibrate;
+		} else if(last_update.y<=2) {
+			if(y<6)
+				term_printf("Calibration failed: not enough head room!\n");
+			else
+				term_printf("Calibration finished.\n");
+			mouse_magic->sonic_wall_x=mouse_magic->sonic_wall_y=32768;
+			goto stop_calibration;
+		} else if(last_update.y!=before_update.y-y) {
+			if(last_update.y==before_update.y-y/2) {
+				term_printf("XP detected!\n");
+			} else {
+				term_printf("Calibration failed: delta=%d (expected: %d)\n",last_update.y-before_update.y,-y);
+				goto stop_calibration;
+			}
+		} else {
+			y++;
+move_calibrate:
+		kbd_mouse_event(-x,-y,0,0);
+			before_update=last_update;
+		}
+	} else if(calibration_step==3) {
+		if(last_update.y==before_update.y-2)
+			mouse_magic->sonic_wall_is_orthogonal=0;
+		else if(last_update.y==before_update.y-1)
+			mouse_magic->sonic_wall_is_orthogonal=-1;
+		else
+			term_printf("Calibration failed: no clue of orthogonal.\n");
+		mouse_magic->sonic_wall_x=mouse_magic->sonic_wall_y;
+		if(last_update.x==before_update.x-mouse_magic->sonic_wall_x)
+			mouse_magic->sonic_wall_x++;
+		else if(last_update.x!=before_update.x-x*2)
+			term_printf("Calibration failed: could not determine horizontal sonic wall x\n");
+		term_printf("Calibration finished\n");
+stop_calibration:
+		/*
+		mouse_x+=last_update.x-cursor.x;
+		mouse_y+=last_update.y-cursor.y-1;
+		*/
+		mouse_x=last_update.x;
+		mouse_y=last_update.y;
+		stop_mouse_calibration();
+	}
+	updates_since_mouse=0;
+}
+
+/* end of mouse stuff */
+
+static void vnc_update(DisplayState *ds, int x, int y, int w, int h)
+{
+	if(ds_sdl)
+		ds_sdl->dpy_update(ds_sdl,x,y,w,h);
+	if(0) term_printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
+	rfbMarkRectAsModified(screen,x,y,x+w,y+h);
+	if(mouse_magic->calibration) {
+		mouse_calibration_update(x,y,w,h);
+	}
+}
+
+#ifdef CONFIG_SDL
+#include <SDL_video.h>
+extern SDL_PixelFormat* sdl_get_format();
+#endif
+extern int vnc_port;
+
+static void vnc_resize(DisplayState *ds, int w, int h)
+{
+	int depth = screen->bitsPerPixel;
+	rfbClientIteratorPtr iter;
+	rfbClientPtr cl;
+
+	if(w==screen->width && h==screen->height)
+		return;
+
+	if(ds_sdl) {
+#ifdef CONFIG_SDL
+		SDL_PixelFormat* sdl_format;
+		ds_sdl->dpy_resize(ds_sdl,w,h);
+		ds->data = ds_sdl->data;
+		ds->linesize = screen->paddedWidthInBytes = ds_sdl->linesize;
+		screen->serverFormat.bitsPerPixel = screen->serverFormat.depth
+			= screen->bitsPerPixel = depth = ds->depth = ds_sdl->depth;
+		w = ds->width = ds_sdl->width;
+		h = ds->height = ds_sdl->height;
+		sdl_format=sdl_get_format();
+		if(sdl_format->palette==0) {
+			screen->serverFormat.trueColour=TRUE;
+			screen->serverFormat.redShift=sdl_format->Rshift;
+			screen->serverFormat.greenShift=sdl_format->Gshift;
+			screen->serverFormat.blueShift=sdl_format->Bshift;
+			screen->serverFormat.redMax=sdl_format->Rmask>>screen->serverFormat.redShift;
+			screen->serverFormat.greenMax=sdl_format->Gmask>>screen->serverFormat.greenShift;
+			screen->serverFormat.blueMax=sdl_format->Bmask>>screen->serverFormat.blueShift;
+		} else {
+			rfbColourMap* cmap=&(screen->colourMap);
+			int i;
+			screen->serverFormat.trueColour=FALSE;
+			cmap->is16=FALSE;
+			cmap->count=sdl_format->palette->ncolors;
+			if(cmap->data.bytes==0)
+				cmap->data.bytes=malloc(256*3);
+			for(i=0;i<cmap->count;i++) {
+				cmap->data.bytes[3*i+0]=sdl_format->palette->colors[i].r;
+				cmap->data.bytes[3*i+1]=sdl_format->palette->colors[i].g;
+				cmap->data.bytes[3*i+2]=sdl_format->palette->colors[i].b;
+			}
+		}
+#else
+		term_printf("Warning: SDL not configured\n");
+#endif
+	} else {
+		ds->data = (unsigned char*)realloc(ds->data, w*h*depth/8);
+		ds->linesize = screen->paddedWidthInBytes = w*2;
+		ds->width = w;
+		ds->height = h;
+		ds->depth = depth;
+		screen->paddedWidthInBytes = w*depth/8;
+	}
+	screen->frameBuffer = ds->data;
+
+	screen->width = w;
+	screen->height = h;
+
+	iter=rfbGetClientIterator(screen);
+	while((cl=rfbClientIteratorNext(iter)))
+		if(cl->useNewFBSize)
+			cl->newFBSizePending = TRUE;
+		else
+			rfbLog("Warning: Client %s does not support NewFBSize!\n",cl->host);
+	rfbReleaseClientIterator(iter);
+
+	if(mouse_magic->calibration) {
+		term_printf("Warning: mouse calibration interrupted by video mode change\n");
+		stop_mouse_calibration();
+	}
+	init_mouse(w,h);
+}
+
+static void vnc_process_key(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
+{
+	/* handle Ctrl+Alt (AKA magic keys) first */
+	if(down) {
+		if(keySym==XK_Control_L)
+			ctl_keys|=1;
+		else if(keySym==XK_Alt_L)
+			ctl_keys|=2;
+		else if((ctl_keys&3)==3)
+			return;
+	} else {
+		if (keySym == XK_Control_L)
+			ctl_keys &= ~1;
+		else if (keySym == XK_Alt_L)
+			ctl_keys &= ~2;
+		else if((ctl_keys&3)==3) {
+			switch(keySym) {
+				case XK_m:
+					start_mouse_calibration();
+					break;
+				case XK_1 ... XK_9:
+					//fprintf(stderr,"switch to %d\n",keySym-XK_1);
+					console_select(keySym - XK_1);
+					if (!is_graphic_console()) {
+						/* tell the vga console to redisplay itself */
+						vga_hw_invalidate();
+						vnc_update(0,0,0,screen->width,screen->height);
+					}
+					break;
+			}
+			return;
+		}
+	}
+
+	if(is_graphic_console()) {
+		int keycode=keysym2scancode(kbd_layout, keySym);
+		if(keycode>=0x80)
+			keycode=(keycode<<8)^0x80e0;
+		//fprintf(stdout,"vnc key out %s: 0x%x,\n",down?"down":"up",keycode);
+		while(keycode!=0) {
+			kbd_put_keycode((keycode&0xff)|(down?0:0x80));
+			keycode>>=8;
+		}
+	} else if(down) {
+		if(!(keySym>=XK_Shift_L && keySym<=XK_Hyper_R)
+		  && !(keySym>=XK_ISO_Lock && keySym<=XK_Pointer_DfltBtnPrev))
+			kbd_put_keysym(keySym);
+		//fprintf(stderr,"vnc key %s: 0x%x (magic=%d)\n",down?"down":"up",keySym,ctl_keys);
+	}
+}
+
+static void vnc_process_mouse(int buttonMask, int x, int y, rfbClientPtr cl)
+{
+	new_mouse_x=x; new_mouse_y=y; new_mouse_buttons=0;
+	if(buttonMask&1) new_mouse_buttons|=MOUSE_EVENT_LBUTTON;
+	if(buttonMask&2) new_mouse_buttons|=MOUSE_EVENT_MBUTTON;
+	if(buttonMask&4) new_mouse_buttons|=MOUSE_EVENT_RBUTTON;
+	if(buttonMask&8) new_mouse_z--;
+	if(buttonMask&16) new_mouse_z++;
+	if(mouse_magic->calibration && (kbd_mouse_is_absolute() == 0)) {
+		printf("mouse_calibration_refresg\n");
+		mouse_calibration_refresh();
+	} else {
+	//	printf("mouse_refresh\n");
+		mouse_refresh();
+	}
+
+}
+
+static void vnc_refresh(DisplayState *ds) {
+	if(ds_sdl)
+		ds_sdl->dpy_refresh(ds_sdl);
+	else if(!is_graphic_console())
+		vga_hw_update();
+	rfbProcessEvents(screen,0);
+}
+
+static void vnc_cleanup(void) 
+{
+	rfbScreenCleanup(screen);
+}
+
+void vnc_display_init(DisplayState *ds, int useAlsoSDL)
+{
+	if(!keyboard_layout) {
+		fprintf(stderr, "No keyboard language specified\n");
+		exit(1);
+	}
+
+	kbd_layout=init_keyboard_layout(keyboard_layout);
+	if(!kbd_layout) {
+		fprintf(stderr, "Could not initialize keyboard\n");
+		exit(1);
+	}
+
+	mouse_magic=init_mouse_magic();
+	register_savevm("vnc", 0, 1, vnc_save, vnc_load, mouse_magic);
+
+	rfbLog=rfbErr=term_printf;
+	screen=rfbGetScreen(0,0,0,0,5,3,2);
+	if(screen==0) {
+		fprintf(stderr, "Could not initialize VNC - exiting\n");
+		exit(1);
+	}
+
+	screen->serverFormat.redShift = 11;
+	screen->serverFormat.greenShift = 5;
+	screen->serverFormat.blueShift = 0;
+	screen->serverFormat.redMax = 31;
+	screen->serverFormat.greenMax = 63;
+	screen->serverFormat.blueMax = 31;
+
+	if(useAlsoSDL) {
+#ifdef CONFIG_SDL
+		ds_sdl=(DisplayState*)malloc(sizeof(DisplayState));
+		sdl_display_init(ds_sdl,0);
+		screen->frameBuffer = ds_sdl->data;
+#else
+		term_printf("SDL not configured!\n");
+#endif
+	} else
+		screen->frameBuffer = malloc(640*400*2);
+
+	screen->desktopName = "QEMU/VNC";
+	screen->cursor = 0;
+
+	/* Did we get a VNC port in the command line? */
+	if (vnc_port) {
+	   screen->autoPort = FALSE;
+	   screen->port = vnc_port;
+	}
+	else
+	   screen->autoPort = TRUE;
+
+	screen->kbdAddEvent = vnc_process_key;
+	screen->ptrAddEvent = vnc_process_mouse;
+	rfbInitServer(screen);
+
+	vnc_resize(ds,640,400);
+
+	ds->dpy_update = vnc_update;
+	ds->dpy_resize = vnc_resize;
+	ds->dpy_refresh = vnc_refresh;
+
+	atexit(vnc_cleanup);
+}
+
diff -urN -x CVS qemu-clean/vnc_keysym.h qemu/vnc_keysym.h
--- qemu-clean/vnc_keysym.h	1970-01-01 04:00:00.000000000 +0400
+++ qemu/vnc_keysym.h	2006-04-10 11:07:37.000000000 +0400
@@ -0,0 +1,278 @@
+typedef struct {
+	const char* name;
+	int keysym;
+} name2keysym_t;
+static name2keysym_t name2keysym[]={
+/* ascii */
+    { "space",                0x020},
+    { "exclam",               0x021},
+    { "quotedbl",             0x022},
+    { "numbersign",           0x023},
+    { "dollar",               0x024},
+    { "percent",              0x025},
+    { "ampersand",            0x026},
+    { "apostrophe",           0x027},
+    { "parenleft",            0x028},
+    { "parenright",           0x029},
+    { "asterisk",             0x02a},
+    { "plus",                 0x02b},
+    { "comma",                0x02c},
+    { "minus",                0x02d},
+    { "period",               0x02e},
+    { "slash",                0x02f},
+    { "0",                    0x030},
+    { "1",                    0x031},
+    { "2",                    0x032},
+    { "3",                    0x033},
+    { "4",                    0x034},
+    { "5",                    0x035},
+    { "6",                    0x036},
+    { "7",                    0x037},
+    { "8",                    0x038},
+    { "9",                    0x039},
+    { "colon",                0x03a},
+    { "semicolon",            0x03b},
+    { "less",                 0x03c},
+    { "equal",                0x03d},
+    { "greater",              0x03e},
+    { "question",             0x03f},
+    { "at",                   0x040},
+    { "A",                    0x041},
+    { "B",                    0x042},
+    { "C",                    0x043},
+    { "D",                    0x044},
+    { "E",                    0x045},
+    { "F",                    0x046},
+    { "G",                    0x047},
+    { "H",                    0x048},
+    { "I",                    0x049},
+    { "J",                    0x04a},
+    { "K",                    0x04b},
+    { "L",                    0x04c},
+    { "M",                    0x04d},
+    { "N",                    0x04e},
+    { "O",                    0x04f},
+    { "P",                    0x050},
+    { "Q",                    0x051},
+    { "R",                    0x052},
+    { "S",                    0x053},
+    { "T",                    0x054},
+    { "U",                    0x055},
+    { "V",                    0x056},
+    { "W",                    0x057},
+    { "X",                    0x058},
+    { "Y",                    0x059},
+    { "Z",                    0x05a},
+    { "bracketleft",          0x05b},
+    { "backslash",            0x05c},
+    { "bracketright",         0x05d},
+    { "asciicircum",          0x05e},
+    { "underscore",           0x05f},
+    { "grave",                0x060},
+    { "a",                    0x061},
+    { "b",                    0x062},
+    { "c",                    0x063},
+    { "d",                    0x064},
+    { "e",                    0x065},
+    { "f",                    0x066},
+    { "g",                    0x067},
+    { "h",                    0x068},
+    { "i",                    0x069},
+    { "j",                    0x06a},
+    { "k",                    0x06b},
+    { "l",                    0x06c},
+    { "m",                    0x06d},
+    { "n",                    0x06e},
+    { "o",                    0x06f},
+    { "p",                    0x070},
+    { "q",                    0x071},
+    { "r",                    0x072},
+    { "s",                    0x073},
+    { "t",                    0x074},
+    { "u",                    0x075},
+    { "v",                    0x076},
+    { "w",                    0x077},
+    { "x",                    0x078},
+    { "y",                    0x079},
+    { "z",                    0x07a},
+    { "braceleft",            0x07b},
+    { "bar",                  0x07c},
+    { "braceright",           0x07d},
+    { "asciitilde",           0x07e},
+
+/* latin 1 extensions */
+{ "nobreakspace",         0x0a0},
+{ "exclamdown",           0x0a1},
+{ "cent",         	  0x0a2},
+{ "sterling",             0x0a3},
+{ "currency",             0x0a4},
+{ "yen",                  0x0a5},
+{ "brokenbar",            0x0a6},
+{ "section",              0x0a7},
+{ "diaeresis",            0x0a8},
+{ "copyright",            0x0a9},
+{ "ordfeminine",          0x0aa},
+{ "guillemotleft",        0x0ab},
+{ "notsign",              0x0ac},
+{ "hyphen",               0x0ad},
+{ "registered",           0x0ae},
+{ "macron",               0x0af},
+{ "degree",               0x0b0},
+{ "plusminus",            0x0b1},
+{ "twosuperior",          0x0b2},
+{ "threesuperior",        0x0b3},
+{ "acute",                0x0b4},
+{ "mu",                   0x0b5},
+{ "paragraph",            0x0b6},
+{ "periodcentered",       0x0b7},
+{ "cedilla",              0x0b8},
+{ "onesuperior",          0x0b9},
+{ "masculine",            0x0ba},
+{ "guillemotright",       0x0bb},
+{ "onequarter",           0x0bc},
+{ "onehalf",              0x0bd},
+{ "threequarters",        0x0be},
+{ "questiondown",         0x0bf},
+{ "Agrave",               0x0c0},
+{ "Aacute",               0x0c1},
+{ "Acircumflex",          0x0c2},
+{ "Atilde",               0x0c3},
+{ "Adiaeresis",           0x0c4},
+{ "Aring",                0x0c5},
+{ "AE",                   0x0c6},
+{ "Ccedilla",             0x0c7},
+{ "Egrave",               0x0c8},
+{ "Eacute",               0x0c9},
+{ "Ecircumflex",          0x0ca},
+{ "Ediaeresis",           0x0cb},
+{ "Igrave",               0x0cc},
+{ "Iacute",               0x0cd},
+{ "Icircumflex",          0x0ce},
+{ "Idiaeresis",           0x0cf},
+{ "ETH",                  0x0d0},
+{ "Eth",                  0x0d0},
+{ "Ntilde",               0x0d1},
+{ "Ograve",               0x0d2},
+{ "Oacute",               0x0d3},
+{ "Ocircumflex",          0x0d4},
+{ "Otilde",               0x0d5},
+{ "Odiaeresis",           0x0d6},
+{ "multiply",             0x0d7},
+{ "Ooblique",             0x0d8},
+{ "Oslash",               0x0d8},
+{ "Ugrave",               0x0d9},
+{ "Uacute",               0x0da},
+{ "Ucircumflex",          0x0db},
+{ "Udiaeresis",           0x0dc},
+{ "Yacute",               0x0dd},
+{ "THORN",                0x0de},
+{ "Thorn",                0x0de},
+{ "ssharp",               0x0df},
+{ "agrave",               0x0e0},
+{ "aacute",               0x0e1},
+{ "acircumflex",          0x0e2},
+{ "atilde",               0x0e3},
+{ "adiaeresis",           0x0e4},
+{ "aring",                0x0e5},
+{ "ae",                   0x0e6},
+{ "ccedilla",             0x0e7},
+{ "egrave",               0x0e8},
+{ "eacute",               0x0e9},
+{ "ecircumflex",          0x0ea},
+{ "ediaeresis",           0x0eb},
+{ "igrave",               0x0ec},
+{ "iacute",               0x0ed},
+{ "icircumflex",          0x0ee},
+{ "idiaeresis",           0x0ef},
+{ "eth",                  0x0f0},
+{ "ntilde",               0x0f1},
+{ "ograve",               0x0f2},
+{ "oacute",               0x0f3},
+{ "ocircumflex",          0x0f4},
+{ "otilde",               0x0f5},
+{ "odiaeresis",           0x0f6},
+{ "division",             0x0f7},
+{ "oslash",               0x0f8},
+{ "ooblique",             0x0f8},
+{ "ugrave",               0x0f9},
+{ "uacute",               0x0fa},
+{ "ucircumflex",          0x0fb},
+{ "udiaeresis",           0x0fc},
+{ "yacute",               0x0fd},
+{ "thorn",                0x0fe},
+{ "ydiaeresis",           0x0ff},
+{"EuroSign", XK_EuroSign},
+
+    /* modifiers */
+{"Control_L", XK_Control_L},
+{"Control_R", XK_Control_R},
+{"Alt_L", XK_Alt_L},
+{"Alt_R", XK_Alt_R},
+{"Caps_Lock", XK_Caps_Lock},
+{"Meta_L", XK_Meta_L},
+{"Meta_R", XK_Meta_R},
+{"Shift_L", XK_Shift_L},
+{"Shift_R", XK_Shift_R},
+{"Super_L", XK_Super_L},
+{"Super_R", XK_Super_R},
+
+    /* special keys */
+{"BackSpace", XK_BackSpace},
+{"Tab", XK_Tab},
+{"Return", XK_Return},
+{"Right", XK_Right},
+{"Left", XK_Left},
+{"Up", XK_Up},
+{"Down", XK_Down},
+{"Page_Down", XK_Page_Down},
+{"Page_Up", XK_Page_Up},
+{"Insert", XK_Insert},
+{"Delete", XK_Delete},
+{"Home", XK_Home},
+{"End", XK_End},
+{"Scroll_Lock", XK_Scroll_Lock},
+{"F1", XK_F1},
+{"F2", XK_F2},
+{"F3", XK_F3},
+{"F4", XK_F4},
+{"F5", XK_F5},
+{"F6", XK_F6},
+{"F7", XK_F7},
+{"F8", XK_F8},
+{"F9", XK_F9},
+{"F10", XK_F10},
+{"F11", XK_F11},
+{"F12", XK_F12},
+{"F13", XK_F13},
+{"F14", XK_F14},
+{"F15", XK_F15},
+{"Sys_Req", XK_Sys_Req},
+{"KP_0", XK_KP_0},
+{"KP_1", XK_KP_1},
+{"KP_2", XK_KP_2},
+{"KP_3", XK_KP_3},
+{"KP_4", XK_KP_4},
+{"KP_5", XK_KP_5},
+{"KP_6", XK_KP_6},
+{"KP_7", XK_KP_7},
+{"KP_8", XK_KP_8},
+{"KP_9", XK_KP_9},
+{"KP_Add", XK_KP_Add},
+{"KP_Decimal", XK_KP_Decimal},
+{"KP_Divide", XK_KP_Divide},
+{"KP_Enter", XK_KP_Enter},
+{"KP_Equal", XK_KP_Equal},
+{"KP_Multiply", XK_KP_Multiply},
+{"KP_Subtract", XK_KP_Subtract},
+{"help", XK_Help},
+{"Menu", XK_Menu},
+/*{"Power", XK_Power},*/
+{"Print", XK_Print},
+{"Mode_switch", XK_Mode_switch},
+/*{"Multi_Key", XK_Multi_Key},*/
+{"Num_Lock", XK_Num_Lock},
+{"Pause", XK_Pause},
+{"Escape", XK_Escape},
+
+{0,0},
+};

  reply	other threads:[~2006-04-10  8:21 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-08 16:20 [Qemu-devel] VNC terminal server? Samuel Hunt
2006-04-08 18:12 ` Brad Campbell
2006-04-21 15:31   ` Troy Benjegerdes
2006-04-21 15:58     ` WaxDragon
2006-04-08 18:24 ` Johannes Schindelin
2006-04-08 18:37   ` Leonardo E. Reiter
2006-04-08 19:04     ` Johannes Schindelin
2006-04-08 19:15       ` Leonardo E. Reiter
2006-04-09  2:54       ` Anthony Liguori
2006-04-08 20:19     ` Brad Campbell
2006-04-08 20:29       ` Leonardo E. Reiter
2006-04-08 21:06       ` [Qemu-devel] Absolute USB-HID device musings (was Re: VNC Terminal Server) Leonardo E. Reiter
2006-04-08 21:18         ` Leonardo E. Reiter
2006-04-08 21:22         ` Brad Campbell
2006-04-08 21:36           ` Leonardo E. Reiter
2006-04-09  4:36         ` Anthony Liguori
2006-04-09 15:14           ` Jim C. Brown
2006-04-09 16:03           ` Leonardo E. Reiter
2006-04-09 16:49             ` Brad Campbell
2006-04-09 18:07             ` andrzej zaborowski
2006-04-09 18:35         ` Brad Campbell
2006-04-09 18:41           ` Lonnie Mendez
2006-04-09 19:22             ` Brad Campbell
2006-04-09 20:27               ` [Qemu-devel] Gentlemen we have absolute movement! was:Absolute " Brad Campbell
2006-04-09 20:31                 ` Anthony Liguori
2006-04-09 20:57                 ` Anthony Liguori
2006-04-09 21:02                   ` Brad Campbell
2006-04-09 21:10                   ` Brad Campbell
2006-04-09 21:20                     ` Johannes Schindelin
2006-04-09 21:35                       ` Brad Campbell
2006-04-09 21:39                     ` Anthony Liguori
2006-04-09 22:01                       ` Brad Campbell
2006-04-09 22:08                         ` Anthony Liguori
2006-04-09 22:12                           ` Brad Campbell
2006-04-09 22:18                           ` Brad Campbell
2006-04-09 23:14                           ` Brad Campbell
2006-04-10  3:40                             ` [Qemu-devel] USB Tablet Emulation (was: Gentlemen we have absolute movement! was:Absolute USB-HID device musings (was Re: VNC Terminal Server)) Anthony Liguori
2006-04-10  8:23                               ` Brad Campbell [this message]
2006-04-10  8:32                                 ` [Qemu-devel] USB Tablet Emulation Johannes Schindelin
2006-04-10 10:27                                   ` Brad Campbell
2006-04-10 11:27                                     ` Johannes Schindelin
2006-04-19 17:18                                 ` [Qemu-devel] USB Tablet Emulation + VNC patch Troy Benjegerdes
2006-04-21 21:13                                   ` Brad Campbell
2006-04-26  0:55                                     ` Troy Benjegerdes
2006-04-26  7:37                                       ` Brad Campbell
2006-04-10 14:58                               ` [Qemu-devel] USB Tablet Emulation Leonardo E. Reiter
2006-04-10 15:27                                 ` Anthony Liguori
2006-04-10 15:39                                   ` Leonardo E. Reiter
2006-04-10 16:08                                     ` Brad Campbell
2006-04-10 19:28                                       ` Brad Campbell
2006-04-10 19:44                                         ` Brad Campbell
2006-04-10 21:27                                           ` Brad Campbell
2006-04-10 21:39                                             ` Brad Campbell
2006-04-08 18:38   ` [Qemu-devel] VNC terminal server? Mark Williamson
2006-04-08 18:53     ` Johannes Schindelin
2006-04-08 19:01   ` Jim C. Brown
2006-04-08 19:12     ` Johannes Schindelin
2006-04-08 19:30       ` Jim C. Brown
2006-04-08 19:40         ` Johannes Schindelin
2006-04-09  2:55       ` Anthony Liguori
2006-04-09  2:53     ` Anthony Liguori
2006-04-08 19:21   ` andrzej zaborowski
2006-04-08 19:33     ` Leonardo E. Reiter
2006-04-09  2:59       ` Anthony Liguori
2006-04-09 16:06         ` Leonardo E. Reiter
2006-04-09 16:40           ` Anthony Liguori
2006-04-09  2:57     ` Anthony Liguori
2006-04-09  2:52   ` Anthony Liguori

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=443A15E9.4060806@wasp.net.au \
    --to=brad@wasp.net.au \
    --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).