ia64/xen-unstable

changeset 9303:58d1ef215706

Add Summagraphics Tablet emulation for VNC users. The current PS/2 emulation
is unusable under VNC since a PS/2 mouse provides deltas while VNC only
provides absolute coordinates. Fortunately, the Summagraphics Tablet provides
absolute coordinates and works perfectly with VNC.

Signed-off-by: Don Dugger <donald.d.dugger@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Mar 16 18:57:54 2006 +0100 (2006-03-16)
parents d6bab69e856f
children 796ac2386a24
files tools/ioemu/configure tools/ioemu/hw/pckbd.c tools/ioemu/hw/serial.c tools/ioemu/sdl.c tools/ioemu/vl.c tools/ioemu/vl.h tools/ioemu/vnc.c
line diff
     1.1 --- a/tools/ioemu/configure	Thu Mar 16 18:43:07 2006 +0100
     1.2 +++ b/tools/ioemu/configure	Thu Mar 16 18:57:54 2006 +0100
     1.3 @@ -238,6 +238,29 @@ fi
     1.4  
     1.5  fi
     1.6  
     1.7 +if test "$vnc" = "yes" ; then
     1.8 +
     1.9 +# check for eager event handling
    1.10 +cat > $TMPC <<EOF
    1.11 +#include "rfb/rfb.h"
    1.12 +int main(void) {
    1.13 +	rfbScreenInfoPtr screen;
    1.14 +
    1.15 +	screen->handleEventsEagerly = 1;
    1.16 +}
    1.17 +EOF
    1.18 +
    1.19 +if $cc `libvncserver-config --cflags` -o $TMPO $TMPC 2> /dev/null ; then
    1.20 +   have_eager_events="yes"
    1.21 +else
    1.22 +   echo "!!"
    1.23 +   echo "!! Slow VNC mouse, LibVNCServer doesn't support eager events"
    1.24 +   echo "!!"
    1.25 +   have_eager_events="no"
    1.26 +fi
    1.27 +
    1.28 +fi
    1.29 +
    1.30  ##########################################
    1.31  # SDL probe
    1.32  
    1.33 @@ -472,6 +495,9 @@ if test "$vnc" = "yes"; then
    1.34      vnc_cflags="/usr/include"
    1.35    fi
    1.36    echo "VNC_CFLAGS=$vnc_cflags" >> $config_mak
    1.37 +  if test "$have_eager_events" = "yes" ; then
    1.38 +    echo "#define VNC_EAGER_EVENTS 1" >> $config_h
    1.39 +  fi
    1.40  fi
    1.41  
    1.42  if test "$sdl" = "yes"; then
     2.1 --- a/tools/ioemu/hw/pckbd.c	Thu Mar 16 18:43:07 2006 +0100
     2.2 +++ b/tools/ioemu/hw/pckbd.c	Thu Mar 16 18:57:54 2006 +0100
     2.3 @@ -29,9 +29,6 @@
     2.4  /* debug PC keyboard : only mouse */
     2.5  //#define DEBUG_MOUSE
     2.6  
     2.7 -/* enable synapatic touchpad device model */
     2.8 -//#define SYNAPTIC
     2.9 -
    2.10  /*	Keyboard Controller Commands */
    2.11  #define KBD_CCMD_READ_MODE	0x20	/* Read mode bits */
    2.12  #define KBD_CCMD_WRITE_MODE	0x60	/* Write mode bits */
    2.13 @@ -114,18 +111,27 @@
    2.14  
    2.15  #define KBD_QUEUE_SIZE 256
    2.16  
    2.17 +/*
    2.18 + * Summagraphics tablet defines
    2.19 + */
    2.20 +#define SUMMA_BORDER	100
    2.21 +#define SUMMA_MAXX	(16000 - 1)
    2.22 +#define SUMMA_MAXY	(16000 - 1)
    2.23 +
    2.24  typedef struct {
    2.25      uint8_t aux[KBD_QUEUE_SIZE];
    2.26      uint8_t data[KBD_QUEUE_SIZE];
    2.27      int rptr, wptr, count;
    2.28  } KBDQueue;
    2.29  
    2.30 -#ifdef SYNAPTIC
    2.31 -typedef struct {
    2.32 -    int absolute;
    2.33 -    int high;
    2.34 -} TouchPad;
    2.35 -#endif
    2.36 +/*
    2.37 + *  Mouse types
    2.38 + */
    2.39 +#define PS2	0
    2.40 +#define IMPS2	3
    2.41 +#define IMEX	4
    2.42 +#define PAD	10
    2.43 +#define TABLET	11
    2.44  
    2.45  typedef struct KBDState {
    2.46      KBDQueue queue;
    2.47 @@ -143,17 +149,20 @@ typedef struct KBDState {
    2.48      uint8_t mouse_wrap;
    2.49      uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
    2.50      uint8_t mouse_detect_state;
    2.51 +    int mouse_x;  /* absolute coordinates (for mousepad) */
    2.52 +    int mouse_y;
    2.53      int mouse_dx; /* current values, needed for 'poll' mode */
    2.54      int mouse_dy;
    2.55      int mouse_dz;
    2.56      uint8_t mouse_buttons;
    2.57 -#ifdef SYNAPTIC
    2.58 -    TouchPad touchpad;
    2.59 -#endif
    2.60 +    CharDriverState *chr;
    2.61 +    void *cookie;
    2.62  } KBDState;
    2.63  
    2.64  KBDState kbd_state;
    2.65  
    2.66 +int summa_ok;		/* Allow Summagraphics emulation if true */
    2.67 +
    2.68  /* update irq and KBD_STAT_[MOUSE_]OBF */
    2.69  /* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be
    2.70     incorrect, but it avoids having to simulate exact delays */
    2.71 @@ -398,7 +407,9 @@ static void kbd_write_keyboard(KBDState 
    2.72      }
    2.73  }
    2.74  
    2.75 -static void kbd_mouse_send_packet(KBDState *s)
    2.76 +int mouse_maxx, mouse_maxy;
    2.77 +
    2.78 +static int kbd_mouse_send_packet(KBDState *s)
    2.79  {
    2.80      unsigned int b;
    2.81      int dx1, dy1, dz1;
    2.82 @@ -406,95 +417,73 @@ static void kbd_mouse_send_packet(KBDSta
    2.83      dx1 = s->mouse_dx;
    2.84      dy1 = s->mouse_dy;
    2.85      dz1 = s->mouse_dz;
    2.86 -#ifdef SYNAPTIC
    2.87 -    if (s->touchpad.absolute)
    2.88 -    {
    2.89 -	int dz2, dleftnright, dg, df;
    2.90 -	if (dx1 > 6143)
    2.91 -	    dx1 = 6143;
    2.92 -	else if (dx1 < 0)
    2.93 -	    dx1 = 0;
    2.94 -	if (dy1 > 6143)
    2.95 -	    dy1 = 6143;
    2.96 -	else if (dy1 < 0)
    2.97 -	    dy1 = 0;
    2.98 -	dz2 = 80; /* normal finger pressure */
    2.99 -	dg = 0; /* guesture not supported */
   2.100 -	df = 0; /* finger not supported */
   2.101 -	dleftnright = (s->mouse_buttons & 0x07);
   2.102 -	/*
   2.103 -	X: 13 bits --return absolute x ord
   2.104 -	Y: 13 bits --return absolute y ord
   2.105 -	Z: 8 bits --return constant 80 since we don't know how hard the user
   2.106 -		is pressing on the mouse button ;) 80 is the default for pen
   2.107 -		pressure, as touchpads cant sense what pressure a pen makes.
   2.108 -	W: 4 bits --return 0, we don't support finger width (should we?)
   2.109 -	left: 1 bit --is left button pressed
   2.110 -	right: 1 bit --is right button pressed
   2.111 -	guesture: 1 bit --we dont support, return 0
   2.112 -	finger: 1 bit --ditto
   2.113 -	total: 42 bits in 6 bytes
   2.114 -	note that Synaptics drivers ignore the finger and guesture bits and
   2.115 -	consider them redundant
   2.116 -	*/
   2.117 -	/*
   2.118 -	note: the packet setup is different when Wmode = 1, but
   2.119 -	    this doesn't apply since we don't support Wmode capability
   2.120 -	format of packet is as follows:
   2.121 -	*/
   2.122 -	// 1 0 finger reserved 0 gesture right left
   2.123 -	kbd_queue(s, (0x80 | (df ? 0x20 : 0) | (dg ? 0x04 : 0) | dleftnright), 1);
   2.124 -	kbd_queue(s, ((dy1 & 0xF) * 256) + (dx1 & 0xF), 1);
   2.125 -	kbd_queue(s, 80, 1); //byte 3
   2.126 -	// 1 1 y-12 x-12 0 gesture right left
   2.127 -	kbd_queue(s, (0xC0 | ((dy1 & 1000) ? 0x20 : 0) | ((dx1 & 1000) ? 0x10 : 0) | (dg ? 0x04 : 0) | dleftnright), 1);
   2.128 -	kbd_queue(s, dx1 & 0xFF, 1);
   2.129 -	kbd_queue(s, dy1 & 0xFF, 1);
   2.130 -	return;
   2.131 +    switch(s->mouse_type) {
   2.132 +  
   2.133 +    case TABLET:        /* Summagraphics pen tablet */
   2.134 +	dx1 = s->mouse_x;
   2.135 +	dy1 = s->mouse_y;
   2.136 +	dx1 = ((dx1 * SUMMA_MAXX) / mouse_maxx) + SUMMA_BORDER;
   2.137 +	dy1 = ((dy1 * SUMMA_MAXY) / mouse_maxy) + SUMMA_BORDER;
   2.138 +	ser_queue(s->cookie, 0x80 | (s->mouse_buttons & 7));
   2.139 +	ser_queue(s->cookie, dx1 & 0x7f);
   2.140 +	ser_queue(s->cookie, dx1 >> 7);
   2.141 +	ser_queue(s->cookie, dy1 & 0x7f);
   2.142 +	ser_queue(s->cookie, dy1 >> 7);
   2.143 +	s->mouse_dx = 0; 
   2.144 +	s->mouse_dy = 0;
   2.145 +	s->mouse_dz = 0;
   2.146 +	return 0;
   2.147 +
   2.148 +    default:	/* PS/2 style mice */
   2.149 +	/* XXX: increase range to 8 bits ? */
   2.150 +	if (dx1 > 127)
   2.151 +	    dx1 = 127;
   2.152 +	else if (dx1 < -127)
   2.153 +	    dx1 = -127;
   2.154 +	if (dy1 > 127)
   2.155 +	    dy1 = 127;
   2.156 +	else if (dy1 < -127)
   2.157 +	    dy1 = -127;
   2.158 +	b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
   2.159 +	kbd_queue(s, b, 1);
   2.160 +	kbd_queue(s, dx1 & 0xff, 1);
   2.161 +	kbd_queue(s, dy1 & 0xff, 1);
   2.162 +	/* extra byte for IMPS/2 or IMEX */
   2.163 +	switch(s->mouse_type) {
   2.164 +
   2.165 +	default:
   2.166 +	    break;
   2.167 +
   2.168 +	case IMPS2:
   2.169 +	    if (dz1 > 127)
   2.170 +		dz1 = 127;
   2.171 +	    else if (dz1 < -127)
   2.172 +		dz1 = -127;
   2.173 +	    kbd_queue(s, dz1 & 0xff, 1);
   2.174 +	    break;
   2.175 +
   2.176 +	case IMEX:
   2.177 +	    if (dz1 > 7)
   2.178 +		dz1 = 7;
   2.179 +	    else if (dz1 < -7)
   2.180 +		dz1 = -7;
   2.181 +	    b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
   2.182 +	    kbd_queue(s, b, 1);
   2.183 +	    break;
   2.184 +	}
   2.185 +
   2.186 +	/* update deltas */
   2.187 +	s->mouse_dx -= dx1;
   2.188 +	s->mouse_dy -= dy1;
   2.189 +	s->mouse_dz -= dz1;
   2.190 +	return s->mouse_dx || s->mouse_dy || s->mouse_dz;
   2.191 +
   2.192      }
   2.193 -#endif
   2.194 -    /* XXX: increase range to 8 bits ? */
   2.195 -    if (dx1 > 127)
   2.196 -        dx1 = 127;
   2.197 -    else if (dx1 < -127)
   2.198 -        dx1 = -127;
   2.199 -    if (dy1 > 127)
   2.200 -        dy1 = 127;
   2.201 -    else if (dy1 < -127)
   2.202 -        dy1 = -127;
   2.203 -    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
   2.204 -    kbd_queue(s, b, 1);
   2.205 -    kbd_queue(s, dx1 & 0xff, 1);
   2.206 -    kbd_queue(s, dy1 & 0xff, 1);
   2.207 -    /* extra byte for IMPS/2 or IMEX */
   2.208 -    switch(s->mouse_type) {
   2.209 -    default:
   2.210 -        break;
   2.211 -    case 3:
   2.212 -        if (dz1 > 127)
   2.213 -            dz1 = 127;
   2.214 -        else if (dz1 < -127)
   2.215 -                dz1 = -127;
   2.216 -        kbd_queue(s, dz1 & 0xff, 1);
   2.217 -        break;
   2.218 -    case 4:
   2.219 -        if (dz1 > 7)
   2.220 -            dz1 = 7;
   2.221 -        else if (dz1 < -7)
   2.222 -            dz1 = -7;
   2.223 -        b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
   2.224 -        kbd_queue(s, b, 1);
   2.225 -        break;
   2.226 -    }
   2.227 -
   2.228 -    /* update deltas */
   2.229 -    s->mouse_dx -= dx1;
   2.230 -    s->mouse_dy -= dy1;
   2.231 -    s->mouse_dz -= dz1;
   2.232  }
   2.233  
   2.234  static void pc_kbd_mouse_event(void *opaque, 
   2.235 -                               int dx, int dy, int dz, int buttons_state)
   2.236 +                               int dx, int dy, int dz, int buttons_state,
   2.237 +			       int x, int y)
   2.238  {
   2.239      KBDState *s = opaque;
   2.240  
   2.241 @@ -502,6 +491,8 @@ static void pc_kbd_mouse_event(void *opa
   2.242      if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
   2.243          return;
   2.244  
   2.245 +    s->mouse_x = x;
   2.246 +    s->mouse_y = y;
   2.247      s->mouse_dx += dx;
   2.248      s->mouse_dy -= dy;
   2.249      s->mouse_dz += dz;
   2.250 @@ -513,23 +504,76 @@ static void pc_kbd_mouse_event(void *opa
   2.251      
   2.252      if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
   2.253          (s->queue.count < (KBD_QUEUE_SIZE - 16))) {
   2.254 -        for(;;) {
   2.255 -            /* if not remote, send event. Multiple events are sent if
   2.256 -               too big deltas */
   2.257 -            kbd_mouse_send_packet(s);
   2.258 -            if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
   2.259 -                break;
   2.260 -        }
   2.261 +		while (kbd_mouse_send_packet(s))
   2.262 +		    ;
   2.263      }
   2.264  }
   2.265  
   2.266 +static void summa(KBDState *s, int val)
   2.267 +{
   2.268 +    static int summa = 0;
   2.269 +
   2.270 +    if (s->mouse_type == TABLET) {
   2.271 +	switch (val) {
   2.272 +
   2.273 +	case '?':	/* read firmware ID */
   2.274 +	    ser_queue(s->cookie, '0');
   2.275 +	    break;
   2.276 +
   2.277 +	case 'a':	/* read config */
   2.278 +	    /*
   2.279 +	     *  Config looks like a movement packet but, because of scaling
   2.280 +	     *    issues we can't use `kbd_send_packet' to do this.
   2.281 +	     */
   2.282 +	    ser_queue(s->cookie, 0);
   2.283 +	    ser_queue(s->cookie, (SUMMA_MAXX & 0x7f));
   2.284 +	    ser_queue(s->cookie, (SUMMA_MAXX >> 7));
   2.285 +	    ser_queue(s->cookie, (SUMMA_MAXY & 0x7f));
   2.286 +	    ser_queue(s->cookie, (SUMMA_MAXY >> 7));
   2.287 +	    break;
   2.288 +
   2.289 +	default:	/* ignore all others */
   2.290 +	    break;
   2.291 +
   2.292 +	}
   2.293 +	return;
   2.294 +    }
   2.295 +    if (val == 'B') {
   2.296 +	summa++;
   2.297 +	return;
   2.298 +    } else if (summa && val == 'z') {
   2.299 +	s->mouse_type = TABLET;
   2.300 +	return;
   2.301 +    }
   2.302 +    summa = 0;
   2.303 +    return;
   2.304 +}
   2.305 +
   2.306 +int summa_write(CharDriverState *chr, const uint8_t *buf, int len)
   2.307 +{
   2.308 +    KBDState *s = (KBDState *)chr->opaque;
   2.309 +    int n;
   2.310 +
   2.311 +    n = len;
   2.312 +    while (n-- > 0)
   2.313 +	summa(s, *buf++);
   2.314 +    return len;
   2.315 +}
   2.316 +
   2.317 +void summa_init(void *cookie, CharDriverState *chr)
   2.318 +{
   2.319 +
   2.320 +    if (summa_ok == 0)
   2.321 +	return;
   2.322 +    kbd_state.chr = chr;
   2.323 +    kbd_state.cookie = (void *)cookie;
   2.324 +    chr->chr_write = summa_write;
   2.325 +    chr->opaque = (void *)&kbd_state;
   2.326 +    return;
   2.327 +}
   2.328 +
   2.329  static void kbd_write_mouse(KBDState *s, int val)
   2.330  {
   2.331 -#ifdef SYNAPTIC
   2.332 -/* variables needed to store synaptics command info */
   2.333 -static int rr = 0, ss = 0, tt = 0, uu = 0, res_count = 0, last_com = 0;
   2.334 -int spare;
   2.335 -#endif
   2.336  #ifdef DEBUG_MOUSE
   2.337      printf("kbd: write mouse 0x%02x\n", val);
   2.338  #endif
   2.339 @@ -547,9 +591,6 @@ int spare;
   2.340                  return;
   2.341              }
   2.342          }
   2.343 -#ifdef SYNAPTIC
   2.344 -	last_com = val;
   2.345 -#endif
   2.346          switch(val) {
   2.347          case AUX_SET_SCALE11:
   2.348              s->mouse_status &= ~MOUSE_STATUS_SCALE21;
   2.349 @@ -581,121 +622,6 @@ int spare;
   2.350              kbd_queue(s, AUX_ACK, 1);
   2.351              break;
   2.352          case AUX_GET_SCALE:
   2.353 -#ifdef SYNAPTIC
   2.354 -	    if (res_count == 4)
   2.355 -	    {
   2.356 -		    /* time for the special stuff */
   2.357 -		    kbd_queue(s, AUX_ACK, 1);
   2.358 -		    /* below is how we get the real synaptic command */
   2.359 -		    val = (rr*64) + (ss*16) + (tt*4) + uu;
   2.360 -		    switch(val)
   2.361 -		    {
   2.362 -			    /* id touchpad */
   2.363 -			    case 0x00:
   2.364 -				    /* info Minor */
   2.365 -				    kbd_queue(s, 0x00, 1);
   2.366 -				    /* special verification byte */
   2.367 -				    kbd_queue(s, 0x47, 1);
   2.368 -				    /* info Major * 0x10 + Info ModelCode*/
   2.369 -				    kbd_queue(s, 4 * 0x10 + 0, 1);
   2.370 -				    break;
   2.371 -				    /* read touchpad modes */
   2.372 -			    case 0x01:
   2.373 -				    /* special verification byte */
   2.374 -				    kbd_queue(s, 0x3B, 1);
   2.375 -				    /* mode */
   2.376 -				    /*
   2.377 -					bit 7 - absolute or relative position
   2.378 -					bit 6 - 0 for 40 packets/sec, 1 for 80 pack/sec
   2.379 -					bit 3 - 1 for sleep mode, 0 for normal
   2.380 -					bit 2 - 1 to detect tap/drag, 0 to disable
   2.381 -					bit 1 - packet size, only valid for serial protocol
   2.382 -					bit 0 - 0 for normal packets, 1 for enhanced packets
   2.383 -					(absolute mode packets which have finger width)
   2.384 -					*/
   2.385 -				    if (s->touchpad.absolute && s->touchpad.high)
   2.386 -				    {
   2.387 -					    spare = 0xC0;
   2.388 -				    }
   2.389 -				    else if (s->touchpad.absolute)
   2.390 -				    {
   2.391 -					    spare = 0x80;
   2.392 -				    }
   2.393 -				    else if (s->touchpad.high)
   2.394 -				    {
   2.395 -					    spare = 0x40;
   2.396 -				    }
   2.397 -				    else
   2.398 -				    {
   2.399 -					    spare = 0x00;
   2.400 -				    }
   2.401 -				    kbd_queue(s, spare, 1);
   2.402 -				    /* special verification byte */
   2.403 -				    kbd_queue(s, 0x47, 1);
   2.404 -				    break;
   2.405 -				    /* read touchpad capabilites */
   2.406 -			    case 0x02:
   2.407 -				    /* extended capability first 8 bits */
   2.408 -				    kbd_queue(s, 0x00, 1);
   2.409 -				    /* special verification byte */
   2.410 -				    kbd_queue(s, 0x47, 1);
   2.411 -				    /* extended capability last 8 bits */
   2.412 -				    kbd_queue(s, 0x00, 1);
   2.413 -				    /* basicly, we don't have any capabilites ;0 */
   2.414 -				    break;
   2.415 -				    /* read model id */
   2.416 -			    case 0x03:
   2.417 -				    /*
   2.418 -					bit 23 = 0 (1 for upsidedownpad)
   2.419 -					bit 22 = 0 (1 for 90 degree rotated pad)
   2.420 -					bits 21-16 = 1 (standard model)
   2.421 -					bits 15-9 = ??? (reserved for synaptics use)
   2.422 -					bit 7 = 1
   2.423 -					bit 6 = 0 (1 for sensing pens)
   2.424 -					bit 5 = 1
   2.425 -					bits 3-0 = 1 (rectangular geometery)
   2.426 -				    */
   2.427 -				    kbd_queue(s, 0xFC, 1);
   2.428 -				    kbd_queue(s, 0x00, 1);
   2.429 -				    kbd_queue(s, 0xF5, 1); //F7 for sensing pens
   2.430 -				    break;
   2.431 -				    /* read serial number prefix */
   2.432 -			    case 0x06:
   2.433 -				    /* strange how they have this query even though
   2.434 -					no touchpad actually has serial numbers */
   2.435 -				    /* return serial prefix of 0 if we dont have one */
   2.436 -				    kbd_queue(s, 0x00, 1);
   2.437 -				    kbd_queue(s, 0x00, 1);
   2.438 -				    kbd_queue(s, 0x00, 1);
   2.439 -				    break;
   2.440 -				    /* read serial number suffix */
   2.441 -			    case 0x07:
   2.442 -				    /* undefined if we dont have a valid serial prefix */
   2.443 -				    kbd_queue(s, 0x00, 1);
   2.444 -				    kbd_queue(s, 0x00, 1);
   2.445 -				    kbd_queue(s, 0x00, 1);
   2.446 -				    break;
   2.447 -				    /* read resolutions */
   2.448 -			    case 0x08:
   2.449 -				    /* going to go with infoSensor = 1 (Standard model) here */
   2.450 -				    /* absolute X in abolute units per mm */
   2.451 -				    kbd_queue(s, 85, 1);
   2.452 -				    /* undefined but first bit 7 will be set to 1...
   2.453 -					hell I'm going to set them all to 1 */
   2.454 -				    kbd_queue(s, 0xFF, 1);
   2.455 -				    /* absolute Y in abolute units per mm */
   2.456 -				    kbd_queue(s, 94, 1);
   2.457 -				    break;
   2.458 -			    default:
   2.459 -				    /* invalid commands return undefined data */
   2.460 -				    kbd_queue(s, 0x00, 1);
   2.461 -				    kbd_queue(s, 0x00, 1);
   2.462 -				    kbd_queue(s, 0x00, 1);
   2.463 -				    break;
   2.464 -		    }
   2.465 -	    }
   2.466 -	    else
   2.467 -#endif
   2.468  	    {
   2.469  		    /* not a special command, just do the regular stuff */
   2.470              kbd_queue(s, AUX_ACK, 1);
   2.471 @@ -720,18 +646,12 @@ int spare;
   2.472              s->mouse_sample_rate = 100;
   2.473              s->mouse_resolution = 2;
   2.474              s->mouse_status = 0;
   2.475 -#ifdef SYNAPTIC
   2.476 -       	    s->touchpad.absolute = 0;
   2.477 -#endif
   2.478              kbd_queue(s, AUX_ACK, 1);
   2.479              break;
   2.480          case AUX_RESET:
   2.481              s->mouse_sample_rate = 100;
   2.482              s->mouse_resolution = 2;
   2.483              s->mouse_status = 0;
   2.484 -#ifdef SYNAPTIC
   2.485 -	    s->touchpad.absolute = 0;
   2.486 -#endif
   2.487              kbd_queue(s, AUX_ACK, 1);
   2.488              kbd_queue(s, 0xaa, 1);
   2.489              kbd_queue(s, s->mouse_type, 1);
   2.490 @@ -741,15 +661,6 @@ int spare;
   2.491          }
   2.492          break;
   2.493      case AUX_SET_SAMPLE:
   2.494 -#ifdef SYNAPTIC
   2.495 -	if (res_count == 4 && val == 0x14)
   2.496 -	{
   2.497 -		/* time for the special stuff */
   2.498 -		/* below is how we get the real synaptic command */
   2.499 -		val = (rr*64) + (ss*16) + (tt*4) + uu;
   2.500 -		/* TODO: set the mode byte */
   2.501 -	} else
   2.502 -#endif
   2.503          s->mouse_sample_rate = val;
   2.504  #if 0
   2.505          /* detect IMPS/2 or IMEX */
   2.506 @@ -769,12 +680,12 @@ int spare;
   2.507              break;
   2.508          case 2:
   2.509              if (val == 80) 
   2.510 -                s->mouse_type = 3; /* IMPS/2 */
   2.511 +                s->mouse_type = IMPS2; /* IMPS/2 */
   2.512              s->mouse_detect_state = 0;
   2.513              break;
   2.514          case 3:
   2.515              if (val == 80) 
   2.516 -                s->mouse_type = 4; /* IMEX */
   2.517 +                s->mouse_type = IMEX; /* IMEX */
   2.518              s->mouse_detect_state = 0;
   2.519              break;
   2.520          }
   2.521 @@ -783,36 +694,6 @@ int spare;
   2.522          s->mouse_write_cmd = -1;
   2.523          break;
   2.524      case AUX_SET_RES:
   2.525 -#ifdef SYNAPTIC
   2.526 -	if (last_com != AUX_SET_RES)
   2.527 -	{
   2.528 -		/* if its not 4 in a row, its not a command */
   2.529 -		/* FIXME: if we are set 8 of these in a row, or 12, or 16,
   2.530 -		   or etc ... or 4^n commands, then the nth'd mode byte sent might
   2.531 -		   still work. not sure if this is how things are suppose to be
   2.532 -		   or not. */
   2.533 -		res_count = 0;
   2.534 -	}
   2.535 -	res_count++;
   2.536 -	if (res_count > 4) res_count = 4;
   2.537 -	switch(res_count)
   2.538 -		/* we need to save the val in the right spots to get the
   2.539 -		   real command later */
   2.540 -	{
   2.541 -		case 1:
   2.542 -			break;
   2.543 -			rr = val;
   2.544 -		case 2:
   2.545 -			ss = val;
   2.546 -			break;
   2.547 -		case 3:
   2.548 -			tt = val;
   2.549 -			break;
   2.550 -		case 4:
   2.551 -			uu = val;
   2.552 -			break;
   2.553 -	}
   2.554 -#endif
   2.555          s->mouse_resolution = val;
   2.556          kbd_queue(s, AUX_ACK, 1);
   2.557          s->mouse_write_cmd = -1;
   2.558 @@ -881,23 +762,19 @@ static void kbd_save(QEMUFile* f, void* 
   2.559      qemu_put_8s(f, &s->write_cmd);
   2.560      qemu_put_8s(f, &s->status);
   2.561      qemu_put_8s(f, &s->mode);
   2.562 -    qemu_put_be32s(f, &s->kbd_write_cmd);
   2.563 -    qemu_put_be32s(f, &s->scan_enabled);
   2.564 -    qemu_put_be32s(f, &s->mouse_write_cmd);
   2.565 +    qemu_put_be32s(f, (uint32_t *)&s->kbd_write_cmd);
   2.566 +    qemu_put_be32s(f, (uint32_t *)&s->scan_enabled);
   2.567 +    qemu_put_be32s(f, (uint32_t *)&s->mouse_write_cmd);
   2.568      qemu_put_8s(f, &s->mouse_status);
   2.569      qemu_put_8s(f, &s->mouse_resolution);
   2.570      qemu_put_8s(f, &s->mouse_sample_rate);
   2.571      qemu_put_8s(f, &s->mouse_wrap);
   2.572      qemu_put_8s(f, &s->mouse_type);
   2.573      qemu_put_8s(f, &s->mouse_detect_state);
   2.574 -    qemu_put_be32s(f, &s->mouse_dx);
   2.575 -    qemu_put_be32s(f, &s->mouse_dy);
   2.576 -    qemu_put_be32s(f, &s->mouse_dz);
   2.577 +    qemu_put_be32s(f, (uint32_t *)&s->mouse_dx);
   2.578 +    qemu_put_be32s(f, (uint32_t *)&s->mouse_dy);
   2.579 +    qemu_put_be32s(f, (uint32_t *)&s->mouse_dz);
   2.580      qemu_put_8s(f, &s->mouse_buttons);
   2.581 -#ifdef SYNAPTIC
   2.582 -    qemu_put_be32s(f, &s->touchpad.absolute);
   2.583 -    qemu_put_be32s(f, &s->touchpad.high);
   2.584 -#endif
   2.585  }
   2.586  
   2.587  static int kbd_load(QEMUFile* f, void* opaque, int version_id)
   2.588 @@ -909,23 +786,19 @@ static int kbd_load(QEMUFile* f, void* o
   2.589      qemu_get_8s(f, &s->write_cmd);
   2.590      qemu_get_8s(f, &s->status);
   2.591      qemu_get_8s(f, &s->mode);
   2.592 -    qemu_get_be32s(f, &s->kbd_write_cmd);
   2.593 -    qemu_get_be32s(f, &s->scan_enabled);
   2.594 -    qemu_get_be32s(f, &s->mouse_write_cmd);
   2.595 +    qemu_get_be32s(f, (uint32_t *)&s->kbd_write_cmd);
   2.596 +    qemu_get_be32s(f, (uint32_t *)&s->scan_enabled);
   2.597 +    qemu_get_be32s(f, (uint32_t *)&s->mouse_write_cmd);
   2.598      qemu_get_8s(f, &s->mouse_status);
   2.599      qemu_get_8s(f, &s->mouse_resolution);
   2.600      qemu_get_8s(f, &s->mouse_sample_rate);
   2.601      qemu_get_8s(f, &s->mouse_wrap);
   2.602      qemu_get_8s(f, &s->mouse_type);
   2.603      qemu_get_8s(f, &s->mouse_detect_state);
   2.604 -    qemu_get_be32s(f, &s->mouse_dx);
   2.605 -    qemu_get_be32s(f, &s->mouse_dy);
   2.606 -    qemu_get_be32s(f, &s->mouse_dz);
   2.607 +    qemu_get_be32s(f, (uint32_t *)&s->mouse_dx);
   2.608 +    qemu_get_be32s(f, (uint32_t *)&s->mouse_dy);
   2.609 +    qemu_get_be32s(f, (uint32_t *)&s->mouse_dz);
   2.610      qemu_get_8s(f, &s->mouse_buttons);
   2.611 -#ifdef SYNAPTIC
   2.612 -    qemu_get_be32s(f, &s->touchpad.absolute);
   2.613 -    qemu_get_be32s(f, &s->touchpad.high);
   2.614 -#endif
   2.615      return 0;
   2.616  }
   2.617  
   2.618 @@ -933,6 +806,7 @@ void kbd_init(void)
   2.619  {
   2.620      KBDState *s = &kbd_state;
   2.621      
   2.622 +    s->mouse_type = PS2;
   2.623      kbd_reset(s);
   2.624      register_savevm("pckbd", 0, 2, kbd_save, kbd_load, s);
   2.625      register_ioport_read(0x60, 1, 1, kbd_read_data, s);
     3.1 --- a/tools/ioemu/hw/serial.c	Thu Mar 16 18:43:07 2006 +0100
     3.2 +++ b/tools/ioemu/hw/serial.c	Thu Mar 16 18:57:54 2006 +0100
     3.3 @@ -70,6 +70,11 @@
     3.4  #define UART_LSR_OE	0x02	/* Overrun error indicator */
     3.5  #define UART_LSR_DR	0x01	/* Receiver data ready */
     3.6  
     3.7 +/*
     3.8 + * Size of ring buffer for characters to send to host
     3.9 + */
    3.10 +#define MAXCHRS	256
    3.11 +
    3.12  struct SerialState {
    3.13      uint8_t divider;
    3.14      uint8_t rbr; /* receive register */
    3.15 @@ -84,11 +89,22 @@ struct SerialState {
    3.16         it can be reset while reading iir */
    3.17      int thr_ipending;
    3.18      int irq;
    3.19 +    struct cbuf {
    3.20 +	    uint8_t buf[MAXCHRS];
    3.21 +	    int in;
    3.22 +	    int out;
    3.23 +    } cbuf;
    3.24      CharDriverState *chr;
    3.25  };
    3.26  
    3.27  static void serial_update_irq(SerialState *s)
    3.28  {
    3.29 +    if ((s->lsr & UART_LSR_DR) == 0 && s->cbuf.in != s->cbuf.out) {
    3.30 +	s->rbr = s->cbuf.buf[s->cbuf.out++];
    3.31 +	if (s->cbuf.out >= MAXCHRS)
    3.32 +	    s->cbuf.out = 0;
    3.33 +	s->lsr |= UART_LSR_DR;
    3.34 +    }
    3.35      if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
    3.36          s->iir = UART_IIR_RDI;
    3.37      } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
    3.38 @@ -220,6 +236,22 @@ static uint32_t serial_ioport_read(void 
    3.39      return ret;
    3.40  }
    3.41  
    3.42 +void ser_queue(SerialState *s, unsigned char c)
    3.43 +{
    3.44 +    int n;
    3.45 +
    3.46 +    n = s->cbuf.in - s->cbuf.out;
    3.47 +    if (n < 0)
    3.48 +	n += MAXCHRS;
    3.49 +    if (n < (MAXCHRS - 1)) {
    3.50 +	s->cbuf.buf[s->cbuf.in++] = c;
    3.51 +	if (s->cbuf.in >= MAXCHRS)
    3.52 +	    s->cbuf.in = 0;
    3.53 +	serial_update_irq(s);
    3.54 +    }
    3.55 +    return;
    3.56 +}
    3.57 +
    3.58  static int serial_can_receive(SerialState *s)
    3.59  {
    3.60      return !(s->lsr & UART_LSR_DR);
    3.61 @@ -227,6 +259,9 @@ static int serial_can_receive(SerialStat
    3.62  
    3.63  static void serial_receive_byte(SerialState *s, int ch)
    3.64  {
    3.65 +#ifdef	DEBUG_SERIAL
    3.66 +    printf("serial: serial_receive_byte: ch=0x%02x\n", ch);
    3.67 +#endif	// DEBUG_SERIAL
    3.68      s->rbr = ch;
    3.69      s->lsr |= UART_LSR_DR;
    3.70      serial_update_irq(s);
    3.71 @@ -266,6 +301,8 @@ SerialState *serial_init(int base, int i
    3.72      s = qemu_mallocz(sizeof(SerialState));
    3.73      if (!s)
    3.74          return NULL;
    3.75 +    s->cbuf.in = 0;
    3.76 +    s->cbuf.out = 0;
    3.77      s->irq = irq;
    3.78      s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
    3.79      s->iir = UART_IIR_NO_INT;
    3.80 @@ -273,6 +310,7 @@ SerialState *serial_init(int base, int i
    3.81      register_ioport_write(base, 8, 1, serial_ioport_write, s);
    3.82      register_ioport_read(base, 8, 1, serial_ioport_read, s);
    3.83      s->chr = chr;
    3.84 +    summa_init(s, chr);
    3.85      qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
    3.86      qemu_chr_add_event_handler(chr, serial_event);
    3.87      return s;
     4.1 --- a/tools/ioemu/sdl.c	Thu Mar 16 18:43:07 2006 +0100
     4.2 +++ b/tools/ioemu/sdl.c	Thu Mar 16 18:57:54 2006 +0100
     4.3 @@ -405,7 +405,7 @@ static void sdl_send_mouse_event(void)
     4.4      if (state & SDL_BUTTON(SDL_BUTTON_WHEELDOWN))
     4.5          dz++;
     4.6  #endif
     4.7 -    kbd_mouse_event(dx, dy, dz, buttons);
     4.8 +    kbd_mouse_event(dx, dy, dz, buttons, 0, 0);
     4.9  }
    4.10  
    4.11  static void toggle_full_screen(DisplayState *ds)
     5.1 --- a/tools/ioemu/vl.c	Thu Mar 16 18:43:07 2006 +0100
     5.2 +++ b/tools/ioemu/vl.c	Thu Mar 16 18:57:54 2006 +0100
     5.3 @@ -464,11 +464,11 @@ void kbd_put_keycode(int keycode)
     5.4      }
     5.5  }
     5.6  
     5.7 -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
     5.8 +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y)
     5.9  {
    5.10      if (qemu_put_mouse_event) {
    5.11          qemu_put_mouse_event(qemu_put_mouse_event_opaque,
    5.12 -                             dx, dy, dz, buttons_state);
    5.13 +                             dx, dy, dz, buttons_state, x, y);
    5.14      }
    5.15  }
    5.16  
     6.1 --- a/tools/ioemu/vl.h	Thu Mar 16 18:43:07 2006 +0100
     6.2 +++ b/tools/ioemu/vl.h	Thu Mar 16 18:57:54 2006 +0100
     6.3 @@ -139,13 +139,13 @@ extern int graphic_depth;
     6.4  #define MOUSE_EVENT_MBUTTON 0x04
     6.5  
     6.6  typedef void QEMUPutKBDEvent(void *opaque, int keycode);
     6.7 -typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
     6.8 +typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state, int x, int y);
     6.9  
    6.10  void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
    6.11  void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque);
    6.12  
    6.13  void kbd_put_keycode(int keycode);
    6.14 -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
    6.15 +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y);
    6.16  
    6.17  /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
    6.18     constants) */
    6.19 @@ -618,6 +618,12 @@ void kbd_init(void);
    6.20  extern const char* keyboard_layout;
    6.21  extern int repeat_key;
    6.22  
    6.23 +/* Mice */
    6.24 +
    6.25 +void summa_init(void *cookie, CharDriverState *chr);
    6.26 +
    6.27 +extern int summa_ok;
    6.28 +
    6.29  /* mc146818rtc.c */
    6.30  
    6.31  typedef struct RTCState RTCState;
    6.32 @@ -630,6 +636,7 @@ void rtc_set_date(RTCState *s, const str
    6.33  
    6.34  typedef struct SerialState SerialState;
    6.35  SerialState *serial_init(int base, int irq, CharDriverState *chr);
    6.36 +void ser_queue(SerialState *s, unsigned char c);
    6.37  
    6.38  /* i8259.c */
    6.39  
     7.1 --- a/tools/ioemu/vnc.c	Thu Mar 16 18:43:07 2006 +0100
     7.2 +++ b/tools/ioemu/vnc.c	Thu Mar 16 18:57:54 2006 +0100
     7.3 @@ -46,8 +46,9 @@
     7.4  #endif
     7.5  
     7.6  static rfbScreenInfoPtr screen;
     7.7 -static DisplayState* ds_sdl=0;
     7.8 -static void* kbd_layout=0; // TODO: move into rfbClient
     7.9 +static DisplayState* ds_sdl;
    7.10 +static void* kbd_layout; // TODO: move into rfbClient
    7.11 +static int ctl_keys; // Ctrl+Alt starts calibration
    7.12  
    7.13  /* mouse stuff */
    7.14  
    7.15 @@ -123,12 +124,15 @@ typedef struct {
    7.16  static rectangle_t last_update, before_update;
    7.17  static int updates_since_mouse=0;
    7.18  
    7.19 +extern int mouse_maxx, mouse_maxy;
    7.20  static int mouse_x,mouse_y;
    7.21  static int new_mouse_x,new_mouse_y,new_mouse_z,new_mouse_buttons;
    7.22  
    7.23 -static void init_mouse(int initial_x,int initial_y) {
    7.24 -	mouse_x=new_mouse_x=initial_x;
    7.25 -	mouse_y=new_mouse_y=initial_y;
    7.26 +static void init_mouse(int max_x,int max_y) {
    7.27 +	mouse_maxx=max_x - 1;
    7.28 +	mouse_maxy=max_y - 1;
    7.29 +	mouse_x=new_mouse_x=max_x/2;
    7.30 +	mouse_y=new_mouse_y=max_y/2;
    7.31  	new_mouse_z=new_mouse_buttons=0;
    7.32  	mouse_magic->calibration = 0;
    7.33  }
    7.34 @@ -137,6 +141,15 @@ static void mouse_refresh() {
    7.35  	int dx=0,dy=0,dz=new_mouse_z;
    7.36  	static int counter=1;
    7.37  
    7.38 +	/*
    7.39 +	 *  Simulate lifting the mouse by pressing left <ctl><alt> together
    7.40 +	 *  e.g. don't send mouse events.
    7.41 +	 */
    7.42 +	if (ctl_keys == 3) {
    7.43 +		mouse_x = new_mouse_x;
    7.44 +		mouse_y = new_mouse_y;
    7.45 +		return;
    7.46 +	}
    7.47  	counter++;
    7.48  	if(!mouse_magic->calibration && counter>=2) { counter=0; return; }
    7.49  
    7.50 @@ -153,7 +166,7 @@ static void mouse_refresh() {
    7.51  		}
    7.52  	}
    7.53  	//fprintf(stderr,"sending mouse event %d,%d\n",dx,dy);
    7.54 -	kbd_mouse_event(dx,dy,dz,new_mouse_buttons);
    7.55 +	kbd_mouse_event(dx,dy,dz,new_mouse_buttons,new_mouse_x,new_mouse_y);
    7.56  	mouse_x+=dx;
    7.57  	mouse_y+=dy;
    7.58  		
    7.59 @@ -237,7 +250,7 @@ static void mouse_calibration_refresh() 
    7.60  	
    7.61  	if(calibration_step==0) {
    7.62  		x=0; y=1;
    7.63 -		kbd_mouse_event(0,-1,0,0);
    7.64 +		kbd_mouse_event(0,-1,0,0,x,y);
    7.65  		calibration_step++;
    7.66  	} else if(calibration_step==1) {
    7.67  		// find out the initial position of the cursor
    7.68 @@ -269,7 +282,7 @@ static void mouse_calibration_refresh() 
    7.69  		} else {
    7.70  			y++;
    7.71  move_calibrate:
    7.72 -			kbd_mouse_event(-x,-y,0,0);
    7.73 +			kbd_mouse_event(-x,-y,0,0,x,y);
    7.74  			before_update=last_update;
    7.75  		}
    7.76  	} else if(calibration_step==3) {
    7.77 @@ -375,12 +388,11 @@ static void vnc_resize(DisplayState *ds,
    7.78  		fprintf(stderr,"Warning: mouse calibration interrupted by video mode change\n");
    7.79  		stop_mouse_calibration();
    7.80  	}
    7.81 -	init_mouse(w/2,h/2);
    7.82 +	init_mouse(w,h);
    7.83  }
    7.84  
    7.85  static void vnc_process_key(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
    7.86  {
    7.87 -	static int magic=0; // Ctrl+Alt starts calibration
    7.88  
    7.89  	if(is_active_console(vga_console)) {
    7.90  		WORD keycode=keysym2scancode(kbd_layout, keySym);
    7.91 @@ -416,24 +428,28 @@ static void vnc_process_key(rfbBool down
    7.92  	}
    7.93  	if(down) {
    7.94  		if(keySym==XK_Control_L)
    7.95 -			magic|=1;
    7.96 +			ctl_keys|=1;
    7.97  		else if(keySym==XK_Alt_L)
    7.98 -			magic|=2;
    7.99 +			ctl_keys|=2;
   7.100  	} else {
   7.101 -		if((magic&3)==3) {
   7.102 +		if (keySym == XK_Control_L)
   7.103 +			ctl_keys &= ~1;
   7.104 +		else if (keySym == XK_Alt_L)
   7.105 +			ctl_keys &= ~2;
   7.106 +		if((ctl_keys&3)==3) {
   7.107  			switch(keySym) {
   7.108  				case XK_Control_L:
   7.109 -					magic&=~1;
   7.110 +					ctl_keys&=~1;
   7.111  					break;
   7.112  				case XK_Alt_L:
   7.113 -					magic&=~2;
   7.114 +					ctl_keys&=~2;
   7.115  					break;
   7.116  				case XK_m:
   7.117 -					magic=0;
   7.118 +					ctl_keys=0;
   7.119  					start_mouse_calibration();
   7.120  					break;
   7.121  				case XK_1 ... XK_9:
   7.122 -					magic=0;
   7.123 +					ctl_keys=0;
   7.124  					fprintf(stderr,"switch to %d\n",keySym-XK_1);
   7.125  					console_select(keySym - XK_1);
   7.126  					if (is_active_console(vga_console)) {
   7.127 @@ -483,7 +499,8 @@ void vnc_display_init(DisplayState *ds, 
   7.128      char  host[1024];
   7.129      char *p;
   7.130      rfbClientPtr cl;
   7.131 -    
   7.132 +
   7.133 +	summa_ok = 1;
   7.134  	if(!keyboard_layout) {
   7.135  		fprintf(stderr, "No keyboard language specified\n");
   7.136  		exit(1);
   7.137 @@ -514,6 +531,10 @@ void vnc_display_init(DisplayState *ds, 
   7.138  	screen->serverFormat.greenMax = 63;
   7.139  	screen->serverFormat.blueMax = 31;
   7.140  
   7.141 +#ifdef	VNC_EAGER_EVENTS
   7.142 +	screen->handleEventsEagerly = TRUE;
   7.143 +#endif	// VNC_EAGER_EVENTS
   7.144 +
   7.145      if (port != 0) 
   7.146          screen->port = port;
   7.147      else