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},
+};
next prev parent 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).