Donald D. Dugger
2006-Mar-15 21:56 UTC
[Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation
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> -- Don Dugger "Censeo Toto nos in Kansa esse decisse." - D. Gale Donald.D.Dugger@intel.com Ph: (303)440-1368 diff -r c445d4a0dd76 tools/ioemu/hw/pckbd.c --- a/tools/ioemu/hw/pckbd.c Tue Mar 14 19:33:45 2006 +0100 +++ b/tools/ioemu/hw/pckbd.c Wed Mar 15 12:37:45 2006 -0700 @@ -29,9 +29,6 @@ /* debug PC keyboard : only mouse */ //#define DEBUG_MOUSE -/* enable synapatic touchpad device model */ -//#define SYNAPTIC - /* Keyboard Controller Commands */ #define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ #define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ @@ -114,18 +111,27 @@ #define KBD_QUEUE_SIZE 256 +/* + * Summagraphics tablet defines + */ +#define SUMMA_BORDER 100 +#define SUMMA_MAXX (16000 - 1) +#define SUMMA_MAXY (16000 - 1) + typedef struct { uint8_t aux[KBD_QUEUE_SIZE]; uint8_t data[KBD_QUEUE_SIZE]; int rptr, wptr, count; } KBDQueue; -#ifdef SYNAPTIC -typedef struct { - int absolute; - int high; -} TouchPad; -#endif +/* + * Mouse types + */ +#define PS2 0 +#define IMPS2 3 +#define IMEX 4 +#define PAD 10 +#define TABLET 11 typedef struct KBDState { KBDQueue queue; @@ -143,16 +149,19 @@ typedef struct KBDState { uint8_t mouse_wrap; uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */ uint8_t mouse_detect_state; + int mouse_x; /* absolute coordinates (for mousepad) */ + int mouse_y; int mouse_dx; /* current values, needed for ''poll'' mode */ int mouse_dy; int mouse_dz; uint8_t mouse_buttons; -#ifdef SYNAPTIC - TouchPad touchpad; -#endif + CharDriverState *chr; + void *cookie; } KBDState; KBDState kbd_state; + +int summa_ok; /* Allow Summagraphics emulation if true */ /* update irq and KBD_STAT_[MOUSE_]OBF */ /* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be @@ -398,7 +407,9 @@ static void kbd_write_keyboard(KBDState } } -static void kbd_mouse_send_packet(KBDState *s) +extern int mouse_maxx, mouse_maxy; + +static int kbd_mouse_send_packet(KBDState *s) { unsigned int b; int dx1, dy1, dz1; @@ -406,95 +417,73 @@ static void kbd_mouse_send_packet(KBDSta dx1 = s->mouse_dx; dy1 = s->mouse_dy; dz1 = s->mouse_dz; -#ifdef SYNAPTIC - if (s->touchpad.absolute) - { - int dz2, dleftnright, dg, df; - if (dx1 > 6143) - dx1 = 6143; - else if (dx1 < 0) - dx1 = 0; - if (dy1 > 6143) - dy1 = 6143; - else if (dy1 < 0) - dy1 = 0; - dz2 = 80; /* normal finger pressure */ - dg = 0; /* guesture not supported */ - df = 0; /* finger not supported */ - dleftnright = (s->mouse_buttons & 0x07); - /* - X: 13 bits --return absolute x ord - Y: 13 bits --return absolute y ord - Z: 8 bits --return constant 80 since we don''t know how hard the user - is pressing on the mouse button ;) 80 is the default for pen - pressure, as touchpads cant sense what pressure a pen makes. - W: 4 bits --return 0, we don''t support finger width (should we?) - left: 1 bit --is left button pressed - right: 1 bit --is right button pressed - guesture: 1 bit --we dont support, return 0 - finger: 1 bit --ditto - total: 42 bits in 6 bytes - note that Synaptics drivers ignore the finger and guesture bits and - consider them redundant - */ - /* - note: the packet setup is different when Wmode = 1, but - this doesn''t apply since we don''t support Wmode capability - format of packet is as follows: - */ - // 1 0 finger reserved 0 gesture right left - kbd_queue(s, (0x80 | (df ? 0x20 : 0) | (dg ? 0x04 : 0) | dleftnright), 1); - kbd_queue(s, ((dy1 & 0xF) * 256) + (dx1 & 0xF), 1); - kbd_queue(s, 80, 1); //byte 3 - // 1 1 y-12 x-12 0 gesture right left - kbd_queue(s, (0xC0 | ((dy1 & 1000) ? 0x20 : 0) | ((dx1 & 1000) ? 0x10 : 0) | (dg ? 0x04 : 0) | dleftnright), 1); - kbd_queue(s, dx1 & 0xFF, 1); - kbd_queue(s, dy1 & 0xFF, 1); - return; - } -#endif - /* XXX: increase range to 8 bits ? */ - if (dx1 > 127) - dx1 = 127; - else if (dx1 < -127) - dx1 = -127; - if (dy1 > 127) - dy1 = 127; - else if (dy1 < -127) - dy1 = -127; - b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07); - kbd_queue(s, b, 1); - kbd_queue(s, dx1 & 0xff, 1); - kbd_queue(s, dy1 & 0xff, 1); - /* extra byte for IMPS/2 or IMEX */ switch(s->mouse_type) { - default: - break; - case 3: - if (dz1 > 127) - dz1 = 127; - else if (dz1 < -127) - dz1 = -127; - kbd_queue(s, dz1 & 0xff, 1); - break; - case 4: - if (dz1 > 7) - dz1 = 7; - else if (dz1 < -7) - dz1 = -7; - b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); - kbd_queue(s, b, 1); - break; - } - - /* update deltas */ - s->mouse_dx -= dx1; - s->mouse_dy -= dy1; - s->mouse_dz -= dz1; + + case TABLET: /* Summagraphics pen tablet */ + dx1 = s->mouse_x; + dy1 = s->mouse_y; + dx1 = ((dx1 * SUMMA_MAXX) / mouse_maxx) + SUMMA_BORDER; + dy1 = ((dy1 * SUMMA_MAXY) / mouse_maxy) + SUMMA_BORDER; + ser_queue(s->cookie, 0x80 | (s->mouse_buttons & 7)); + ser_queue(s->cookie, dx1 & 0x7f); + ser_queue(s->cookie, dx1 >> 7); + ser_queue(s->cookie, dy1 & 0x7f); + ser_queue(s->cookie, dy1 >> 7); + s->mouse_dx = 0; + s->mouse_dy = 0; + s->mouse_dz = 0; + return 0; + + default: /* PS/2 style mice */ + /* XXX: increase range to 8 bits ? */ + if (dx1 > 127) + dx1 = 127; + else if (dx1 < -127) + dx1 = -127; + if (dy1 > 127) + dy1 = 127; + else if (dy1 < -127) + dy1 = -127; + b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07); + kbd_queue(s, b, 1); + kbd_queue(s, dx1 & 0xff, 1); + kbd_queue(s, dy1 & 0xff, 1); + /* extra byte for IMPS/2 or IMEX */ + switch(s->mouse_type) { + + default: + break; + + case IMPS2: + if (dz1 > 127) + dz1 = 127; + else if (dz1 < -127) + dz1 = -127; + kbd_queue(s, dz1 & 0xff, 1); + break; + + case IMEX: + if (dz1 > 7) + dz1 = 7; + else if (dz1 < -7) + dz1 = -7; + b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); + kbd_queue(s, b, 1); + break; + } + + /* update deltas */ + s->mouse_dx -= dx1; + s->mouse_dy -= dy1; + s->mouse_dz -= dz1; + return s->mouse_dx || s->mouse_dy || s->mouse_dz; + + } } static void pc_kbd_mouse_event(void *opaque, - int dx, int dy, int dz, int buttons_state) + int dx, int dy, int dz, int buttons_state, + int x, int y) { KBDState *s = opaque; @@ -502,6 +491,8 @@ static void pc_kbd_mouse_event(void *opa if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) return; + s->mouse_x = x; + s->mouse_y = y; s->mouse_dx += dx; s->mouse_dy -= dy; s->mouse_dz += dz; @@ -513,23 +504,76 @@ static void pc_kbd_mouse_event(void *opa if (!(s->mouse_status & MOUSE_STATUS_REMOTE) && (s->queue.count < (KBD_QUEUE_SIZE - 16))) { - for(;;) { - /* if not remote, send event. Multiple events are sent if - too big deltas */ - kbd_mouse_send_packet(s); - if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0) - break; - } - } + while (kbd_mouse_send_packet(s)) + ; + } +} + +static void summa(KBDState *s, int val) +{ + static int summa = 0; + + if (s->mouse_type == TABLET) { + switch (val) { + + case ''?'': /* read firmware ID */ + ser_queue(s->cookie, ''0''); + break; + + case ''a'': /* read config */ + /* + * Config looks like a movement packet but, because of scaling + * issues we can''t use `kbd_send_packet'' to do this. + */ + ser_queue(s->cookie, 0); + ser_queue(s->cookie, (SUMMA_MAXX & 0x7f)); + ser_queue(s->cookie, (SUMMA_MAXX >> 7)); + ser_queue(s->cookie, (SUMMA_MAXY & 0x7f)); + ser_queue(s->cookie, (SUMMA_MAXY >> 7)); + break; + + default: /* ignore all others */ + break; + + } + return; + } + if (val == ''B'') { + summa++; + return; + } else if (summa && val == ''z'') { + s->mouse_type = TABLET; + return; + } + summa = 0; + return; +} + +int summa_write(CharDriverState *chr, const uint8_t *buf, int len) +{ + KBDState *s = (KBDState *)chr->opaque; + int n; + + n = len; + while (n-- > 0) + summa(s, *buf++); + return len; +} + +void summa_init(void *cookie, CharDriverState *chr) +{ + + if (summa_ok == 0) + return; + kbd_state.chr = chr; + kbd_state.cookie = (void *)cookie; + chr->chr_write = summa_write; + chr->opaque = (void *)&kbd_state; + return; } static void kbd_write_mouse(KBDState *s, int val) { -#ifdef SYNAPTIC -/* variables needed to store synaptics command info */ -static int rr = 0, ss = 0, tt = 0, uu = 0, res_count = 0, last_com = 0; -int spare; -#endif #ifdef DEBUG_MOUSE printf("kbd: write mouse 0x%02x\n", val); #endif @@ -547,9 +591,6 @@ int spare; return; } } -#ifdef SYNAPTIC - last_com = val; -#endif switch(val) { case AUX_SET_SCALE11: s->mouse_status &= ~MOUSE_STATUS_SCALE21; @@ -581,121 +622,6 @@ int spare; kbd_queue(s, AUX_ACK, 1); break; case AUX_GET_SCALE: -#ifdef SYNAPTIC - if (res_count == 4) - { - /* time for the special stuff */ - kbd_queue(s, AUX_ACK, 1); - /* below is how we get the real synaptic command */ - val = (rr*64) + (ss*16) + (tt*4) + uu; - switch(val) - { - /* id touchpad */ - case 0x00: - /* info Minor */ - kbd_queue(s, 0x00, 1); - /* special verification byte */ - kbd_queue(s, 0x47, 1); - /* info Major * 0x10 + Info ModelCode*/ - kbd_queue(s, 4 * 0x10 + 0, 1); - break; - /* read touchpad modes */ - case 0x01: - /* special verification byte */ - kbd_queue(s, 0x3B, 1); - /* mode */ - /* - bit 7 - absolute or relative position - bit 6 - 0 for 40 packets/sec, 1 for 80 pack/sec - bit 3 - 1 for sleep mode, 0 for normal - bit 2 - 1 to detect tap/drag, 0 to disable - bit 1 - packet size, only valid for serial protocol - bit 0 - 0 for normal packets, 1 for enhanced packets - (absolute mode packets which have finger width) - */ - if (s->touchpad.absolute && s->touchpad.high) - { - spare = 0xC0; - } - else if (s->touchpad.absolute) - { - spare = 0x80; - } - else if (s->touchpad.high) - { - spare = 0x40; - } - else - { - spare = 0x00; - } - kbd_queue(s, spare, 1); - /* special verification byte */ - kbd_queue(s, 0x47, 1); - break; - /* read touchpad capabilites */ - case 0x02: - /* extended capability first 8 bits */ - kbd_queue(s, 0x00, 1); - /* special verification byte */ - kbd_queue(s, 0x47, 1); - /* extended capability last 8 bits */ - kbd_queue(s, 0x00, 1); - /* basicly, we don''t have any capabilites ;0 */ - break; - /* read model id */ - case 0x03: - /* - bit 23 = 0 (1 for upsidedownpad) - bit 22 = 0 (1 for 90 degree rotated pad) - bits 21-16 = 1 (standard model) - bits 15-9 = ??? (reserved for synaptics use) - bit 7 = 1 - bit 6 = 0 (1 for sensing pens) - bit 5 = 1 - bits 3-0 = 1 (rectangular geometery) - */ - kbd_queue(s, 0xFC, 1); - kbd_queue(s, 0x00, 1); - kbd_queue(s, 0xF5, 1); //F7 for sensing pens - break; - /* read serial number prefix */ - case 0x06: - /* strange how they have this query even though - no touchpad actually has serial numbers */ - /* return serial prefix of 0 if we dont have one */ - kbd_queue(s, 0x00, 1); - kbd_queue(s, 0x00, 1); - kbd_queue(s, 0x00, 1); - break; - /* read serial number suffix */ - case 0x07: - /* undefined if we dont have a valid serial prefix */ - kbd_queue(s, 0x00, 1); - kbd_queue(s, 0x00, 1); - kbd_queue(s, 0x00, 1); - break; - /* read resolutions */ - case 0x08: - /* going to go with infoSensor = 1 (Standard model) here */ - /* absolute X in abolute units per mm */ - kbd_queue(s, 85, 1); - /* undefined but first bit 7 will be set to 1... - hell I''m going to set them all to 1 */ - kbd_queue(s, 0xFF, 1); - /* absolute Y in abolute units per mm */ - kbd_queue(s, 94, 1); - break; - default: - /* invalid commands return undefined data */ - kbd_queue(s, 0x00, 1); - kbd_queue(s, 0x00, 1); - kbd_queue(s, 0x00, 1); - break; - } - } - else -#endif { /* not a special command, just do the regular stuff */ kbd_queue(s, AUX_ACK, 1); @@ -720,18 +646,12 @@ int spare; s->mouse_sample_rate = 100; s->mouse_resolution = 2; s->mouse_status = 0; -#ifdef SYNAPTIC - s->touchpad.absolute = 0; -#endif kbd_queue(s, AUX_ACK, 1); break; case AUX_RESET: s->mouse_sample_rate = 100; s->mouse_resolution = 2; s->mouse_status = 0; -#ifdef SYNAPTIC - s->touchpad.absolute = 0; -#endif kbd_queue(s, AUX_ACK, 1); kbd_queue(s, 0xaa, 1); kbd_queue(s, s->mouse_type, 1); @@ -741,15 +661,6 @@ int spare; } break; case AUX_SET_SAMPLE: -#ifdef SYNAPTIC - if (res_count == 4 && val == 0x14) - { - /* time for the special stuff */ - /* below is how we get the real synaptic command */ - val = (rr*64) + (ss*16) + (tt*4) + uu; - /* TODO: set the mode byte */ - } else -#endif s->mouse_sample_rate = val; #if 0 /* detect IMPS/2 or IMEX */ @@ -769,12 +680,12 @@ int spare; break; case 2: if (val == 80) - s->mouse_type = 3; /* IMPS/2 */ + s->mouse_type = IMPS2; /* IMPS/2 */ s->mouse_detect_state = 0; break; case 3: if (val == 80) - s->mouse_type = 4; /* IMEX */ + s->mouse_type = IMEX; /* IMEX */ s->mouse_detect_state = 0; break; } @@ -783,36 +694,6 @@ int spare; s->mouse_write_cmd = -1; break; case AUX_SET_RES: -#ifdef SYNAPTIC - if (last_com != AUX_SET_RES) - { - /* if its not 4 in a row, its not a command */ - /* FIXME: if we are set 8 of these in a row, or 12, or 16, - or etc ... or 4^n commands, then the nth''d mode byte sent might - still work. not sure if this is how things are suppose to be - or not. */ - res_count = 0; - } - res_count++; - if (res_count > 4) res_count = 4; - switch(res_count) - /* we need to save the val in the right spots to get the - real command later */ - { - case 1: - break; - rr = val; - case 2: - ss = val; - break; - case 3: - tt = val; - break; - case 4: - uu = val; - break; - } -#endif s->mouse_resolution = val; kbd_queue(s, AUX_ACK, 1); s->mouse_write_cmd = -1; @@ -881,23 +762,19 @@ static void kbd_save(QEMUFile* f, void* qemu_put_8s(f, &s->write_cmd); qemu_put_8s(f, &s->status); qemu_put_8s(f, &s->mode); - qemu_put_be32s(f, &s->kbd_write_cmd); - qemu_put_be32s(f, &s->scan_enabled); - qemu_put_be32s(f, &s->mouse_write_cmd); + qemu_put_be32s(f, (uint32_t *)&s->kbd_write_cmd); + qemu_put_be32s(f, (uint32_t *)&s->scan_enabled); + qemu_put_be32s(f, (uint32_t *)&s->mouse_write_cmd); qemu_put_8s(f, &s->mouse_status); qemu_put_8s(f, &s->mouse_resolution); qemu_put_8s(f, &s->mouse_sample_rate); qemu_put_8s(f, &s->mouse_wrap); qemu_put_8s(f, &s->mouse_type); qemu_put_8s(f, &s->mouse_detect_state); - qemu_put_be32s(f, &s->mouse_dx); - qemu_put_be32s(f, &s->mouse_dy); - qemu_put_be32s(f, &s->mouse_dz); + qemu_put_be32s(f, (uint32_t *)&s->mouse_dx); + qemu_put_be32s(f, (uint32_t *)&s->mouse_dy); + qemu_put_be32s(f, (uint32_t *)&s->mouse_dz); qemu_put_8s(f, &s->mouse_buttons); -#ifdef SYNAPTIC - qemu_put_be32s(f, &s->touchpad.absolute); - qemu_put_be32s(f, &s->touchpad.high); -#endif } static int kbd_load(QEMUFile* f, void* opaque, int version_id) @@ -909,23 +786,19 @@ static int kbd_load(QEMUFile* f, void* o qemu_get_8s(f, &s->write_cmd); qemu_get_8s(f, &s->status); qemu_get_8s(f, &s->mode); - qemu_get_be32s(f, &s->kbd_write_cmd); - qemu_get_be32s(f, &s->scan_enabled); - qemu_get_be32s(f, &s->mouse_write_cmd); + qemu_get_be32s(f, (uint32_t *)&s->kbd_write_cmd); + qemu_get_be32s(f, (uint32_t *)&s->scan_enabled); + qemu_get_be32s(f, (uint32_t *)&s->mouse_write_cmd); qemu_get_8s(f, &s->mouse_status); qemu_get_8s(f, &s->mouse_resolution); qemu_get_8s(f, &s->mouse_sample_rate); qemu_get_8s(f, &s->mouse_wrap); qemu_get_8s(f, &s->mouse_type); qemu_get_8s(f, &s->mouse_detect_state); - qemu_get_be32s(f, &s->mouse_dx); - qemu_get_be32s(f, &s->mouse_dy); - qemu_get_be32s(f, &s->mouse_dz); + qemu_get_be32s(f, (uint32_t *)&s->mouse_dx); + qemu_get_be32s(f, (uint32_t *)&s->mouse_dy); + qemu_get_be32s(f, (uint32_t *)&s->mouse_dz); qemu_get_8s(f, &s->mouse_buttons); -#ifdef SYNAPTIC - qemu_get_be32s(f, &s->touchpad.absolute); - qemu_get_be32s(f, &s->touchpad.high); -#endif return 0; } @@ -933,6 +806,7 @@ void kbd_init(void) { KBDState *s = &kbd_state; + s->mouse_type = PS2; kbd_reset(s); register_savevm("pckbd", 0, 2, kbd_save, kbd_load, s); register_ioport_read(0x60, 1, 1, kbd_read_data, s); diff -r fcc833cbaf82 tools/ioemu/hw/serial.c --- a/tools/ioemu/hw/serial.c Mon Feb 13 17:41:23 2006 +0100 +++ b/tools/ioemu/hw/serial.c Wed Mar 1 15:15:42 2006 -0700 @@ -70,6 +70,11 @@ #define UART_LSR_OE 0x02 /* Overrun error indicator */ #define UART_LSR_DR 0x01 /* Receiver data ready */ +/* + * Size of ring buffer for characters to send to host + */ +#define MAXCHRS 256 + struct SerialState { uint8_t divider; uint8_t rbr; /* receive register */ @@ -84,11 +89,22 @@ struct SerialState { it can be reset while reading iir */ int thr_ipending; int irq; + struct cbuf { + uint8_t buf[MAXCHRS]; + int in; + int out; + } cbuf; CharDriverState *chr; }; static void serial_update_irq(SerialState *s) { + if ((s->lsr & UART_LSR_DR) == 0 && s->cbuf.in != s->cbuf.out) { + s->rbr = s->cbuf.buf[s->cbuf.out++]; + if (s->cbuf.out >= MAXCHRS) + s->cbuf.out = 0; + s->lsr |= UART_LSR_DR; + } if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) { s->iir = UART_IIR_RDI; } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) { @@ -220,6 +236,22 @@ static uint32_t serial_ioport_read(void return ret; } +void ser_queue(SerialState *s, unsigned char c) +{ + int n; + + n = s->cbuf.in - s->cbuf.out; + if (n < 0) + n += MAXCHRS; + if (n < (MAXCHRS - 1)) { + s->cbuf.buf[s->cbuf.in++] = c; + if (s->cbuf.in >= MAXCHRS) + s->cbuf.in = 0; + serial_update_irq(s); + } + return; +} + static int serial_can_receive(SerialState *s) { return !(s->lsr & UART_LSR_DR); @@ -227,6 +259,9 @@ static int serial_can_receive(SerialStat static void serial_receive_byte(SerialState *s, int ch) { +#ifdef DEBUG_SERIAL + printf("serial: serial_receive_byte: ch=0x%02x\n", ch); +#endif // DEBUG_SERIAL s->rbr = ch; s->lsr |= UART_LSR_DR; serial_update_irq(s); @@ -266,6 +301,8 @@ SerialState *serial_init(int base, int i s = qemu_mallocz(sizeof(SerialState)); if (!s) return NULL; + s->cbuf.in = 0; + s->cbuf.out = 0; s->irq = irq; s->lsr = UART_LSR_TEMT | UART_LSR_THRE; s->iir = UART_IIR_NO_INT; @@ -273,6 +310,7 @@ SerialState *serial_init(int base, int i register_ioport_write(base, 8, 1, serial_ioport_write, s); register_ioport_read(base, 8, 1, serial_ioport_read, s); s->chr = chr; + summa_init(s, chr); qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s); qemu_chr_add_event_handler(chr, serial_event); return s; diff -r fcc833cbaf82 tools/ioemu/sdl.c --- a/tools/ioemu/sdl.c Mon Feb 13 17:41:23 2006 +0100 +++ b/tools/ioemu/sdl.c Wed Mar 1 15:15:42 2006 -0700 @@ -405,7 +405,7 @@ static void sdl_send_mouse_event(void) if (state & SDL_BUTTON(SDL_BUTTON_WHEELDOWN)) dz++; #endif - kbd_mouse_event(dx, dy, dz, buttons); + kbd_mouse_event(dx, dy, dz, buttons, 0, 0); } static void toggle_full_screen(DisplayState *ds) diff -r fcc833cbaf82 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Mon Feb 13 17:41:23 2006 +0100 +++ b/tools/ioemu/vl.c Wed Mar 1 15:15:42 2006 -0700 @@ -464,11 +464,11 @@ void kbd_put_keycode(int keycode) } } -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y) { if (qemu_put_mouse_event) { qemu_put_mouse_event(qemu_put_mouse_event_opaque, - dx, dy, dz, buttons_state); + dx, dy, dz, buttons_state, x, y); } } diff -r c445d4a0dd76 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Tue Mar 14 19:33:45 2006 +0100 +++ b/tools/ioemu/vl.h Wed Mar 15 12:38:16 2006 -0700 @@ -139,13 +139,13 @@ extern int graphic_depth; #define MOUSE_EVENT_MBUTTON 0x04 typedef void QEMUPutKBDEvent(void *opaque, int keycode); -typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state); +typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state, int x, int y); void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque); void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque); void kbd_put_keycode(int keycode); -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state); +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y); /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx constants) */ @@ -618,6 +618,12 @@ extern const char* keyboard_layout; extern const char* keyboard_layout; extern int repeat_key; +/* Mice */ + +void summa_init(void *cookie, CharDriverState *chr); + +extern int summa_ok; + /* mc146818rtc.c */ typedef struct RTCState RTCState; @@ -630,6 +636,7 @@ void rtc_set_date(RTCState *s, const str typedef struct SerialState SerialState; SerialState *serial_init(int base, int irq, CharDriverState *chr); +void ser_queue(SerialState *s, unsigned char c); /* i8259.c */ diff -r c445d4a0dd76 tools/ioemu/vnc.c --- a/tools/ioemu/vnc.c Tue Mar 14 19:33:45 2006 +0100 +++ b/tools/ioemu/vnc.c Wed Mar 15 12:37:31 2006 -0700 @@ -46,8 +46,9 @@ #endif static rfbScreenInfoPtr screen; -static DisplayState* ds_sdl=0; -static void* kbd_layout=0; // TODO: move into rfbClient +static DisplayState* ds_sdl; +static void* kbd_layout; // TODO: move into rfbClient +static int ctl_keys; // Ctrl+Alt starts calibration /* mouse stuff */ @@ -123,12 +124,16 @@ static rectangle_t last_update, before_u 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 initial_x,int initial_y) { - mouse_x=new_mouse_x=initial_x; - mouse_y=new_mouse_y=initial_y; +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; } @@ -137,6 +142,15 @@ 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 (ctl_keys == 3) { + mouse_x = new_mouse_x; + mouse_y = new_mouse_y; + return; + } counter++; if(!mouse_magic->calibration && counter>=2) { counter=0; return; } @@ -153,7 +167,7 @@ static void mouse_refresh() { } } //fprintf(stderr,"sending mouse event %d,%d\n",dx,dy); - kbd_mouse_event(dx,dy,dz,new_mouse_buttons); + kbd_mouse_event(dx,dy,dz,new_mouse_buttons,new_mouse_x,new_mouse_y); mouse_x+=dx; mouse_y+=dy; @@ -237,7 +251,7 @@ static void mouse_calibration_refresh() if(calibration_step==0) { x=0; y=1; - kbd_mouse_event(0,-1,0,0); + kbd_mouse_event(0,-1,0,0,x,y); calibration_step++; } else if(calibration_step==1) { // find out the initial position of the cursor @@ -269,7 +283,7 @@ static void mouse_calibration_refresh() } else { y++; move_calibrate: - kbd_mouse_event(-x,-y,0,0); + kbd_mouse_event(-x,-y,0,0,x,y); before_update=last_update; } } else if(calibration_step==3) { @@ -375,12 +389,11 @@ static void vnc_resize(DisplayState *ds, fprintf(stderr,"Warning: mouse calibration interrupted by video mode change\n"); stop_mouse_calibration(); } - init_mouse(w/2,h/2); + init_mouse(w,h); } static void vnc_process_key(rfbBool down, rfbKeySym keySym, rfbClientPtr cl) { - static int magic=0; // Ctrl+Alt starts calibration if(is_active_console(vga_console)) { WORD keycode=keysym2scancode(kbd_layout, keySym); @@ -416,24 +429,28 @@ static void vnc_process_key(rfbBool down } if(down) { if(keySym==XK_Control_L) - magic|=1; + ctl_keys|=1; else if(keySym==XK_Alt_L) - magic|=2; + ctl_keys|=2; } else { - if((magic&3)==3) { + if (keySym == XK_Control_L) + ctl_keys &= ~1; + else if (keySym == XK_Alt_L) + ctl_keys &= ~2; + if((ctl_keys&3)==3) { switch(keySym) { case XK_Control_L: - magic&=~1; + ctl_keys&=~1; break; case XK_Alt_L: - magic&=~2; + ctl_keys&=~2; break; case XK_m: - magic=0; + ctl_keys=0; start_mouse_calibration(); break; case XK_1 ... XK_9: - magic=0; + ctl_keys=0; fprintf(stderr,"switch to %d\n",keySym-XK_1); console_select(keySym - XK_1); if (is_active_console(vga_console)) { @@ -483,7 +500,8 @@ void vnc_display_init(DisplayState *ds, char host[1024]; char *p; rfbClientPtr cl; - + + summa_ok = 1; if(!keyboard_layout) { fprintf(stderr, "No keyboard language specified\n"); exit(1); @@ -513,6 +531,10 @@ void vnc_display_init(DisplayState *ds, screen->serverFormat.redMax = 31; screen->serverFormat.greenMax = 63; screen->serverFormat.blueMax = 31; + +#ifdef VNC_EAGER_EVENTS + screen->handleEventsEagerly = TRUE; +#endif // VNC_EAGER_EVENTS if (port != 0) screen->port = port; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Anthony Liguori
2006-Mar-15 22:52 UTC
Re: [Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation
Does this work under Windows? I had implemented emulation for the Wacom tablet in Qemu. It worked fine for Linux guests, but not for Windows. I eventually found the necessary specs to implement Windows support but simply haven''t gotten around to it. I also was looking at synaptic emulation since it provides an extended PS/2 protocol (I hate burning a serial port). Having to manually configure a guest is a pain too. Regards, Anthony Liguori Donald D. Dugger wrote:> 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> > >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2006-Mar-15 23:05 UTC
Re: [Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation
On 15 Mar 2006, at 21:56, Donald D. Dugger wrote:> 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.This patch is very big, especially since the modified qemu files appear to already contain support for touchpads. Why is so much code moved around? Although we do want this support, we really don''t want to continue our slide away from qemu mainline at an increasing pace! :-) Can I apply patches 2 and 3 independent of this one (sounds like patch 2 depends on 3 to avoid causing excessive CPU overhead, but neither has dependence on this patch)? -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Dugger, Donald D
2006-Mar-15 23:07 UTC
RE: [Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation
Anthony- Yes, this version works on Windows. My first effort ran over the PS/2 port and the Windows driver only works over serial, that''s why this version works over the serial port, everybody''s happy now. I guess I''m not too bothered by burnin the serial port, it''s easy enough to add a second one if there''s a call for it. -- Don Dugger "Censeo Toto nos in Kansa esse decisse." - D. Gale Donald.D.Dugger@intel.com Ph: (303)440-1368>-----Original Message----- >From: Anthony Liguori [mailto:aliguori@us.ibm.com] >Sent: Wednesday, March 15, 2006 3:52 PM >To: Dugger, Donald D >Cc: xen-devel@lists.xensource.com >Subject: Re: [Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation > >Does this work under Windows? > >I had implemented emulation for the Wacom tablet in Qemu. It worked >fine for Linux guests, but not for Windows. I eventually found the >necessary specs to implement Windows support but simply haven''t gotten >around to it. > >I also was looking at synaptic emulation since it provides an extended >PS/2 protocol (I hate burning a serial port). Having to manually >configure a guest is a pain too. > >Regards, > >Anthony Liguori > >Donald D. Dugger wrote: >> 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> >> >> >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Anthony Liguori
2006-Mar-15 23:22 UTC
Re: [Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation
Keir Fraser wrote:> > On 15 Mar 2006, at 21:56, Donald D. Dugger wrote: > >> 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. > > This patch is very big, especially since the modified qemu files > appear to already contain support for touchpads. Why is so much code > moved around? Although we do want this support, we really don''t want > to continue our slide away from qemu mainline at an increasing pace! :-)There''s definitely interesting in touchpad support within qemu. You should also submit this to qemu-devel. Regards, Anthony Liguori> Can I apply patches 2 and 3 independent of this one (sounds like patch > 2 depends on 3 to avoid causing excessive CPU overhead, but neither > has dependence on this patch)? > > -- Keir > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Dugger, Donald D
2006-Mar-15 23:22 UTC
RE: [Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation
Keir- Yes, the 3 patches are independent so you can apply them as you wish. I''m not sure what your concern is about the touchpad patch. There was code to emulate a touchpad in the code but it was all wrong and didn''t work, I basically had to re-do all of the touchpad code to get this to work. I''m talking to Johannes Schindelin about getting touchpad emulation put into straight `qemu'' so, eventually, we won''t need any special code in the Xen version but that won''t happen for a while and this patch gets us working until then. -- Don Dugger "Censeo Toto nos in Kansa esse decisse." - D. Gale Donald.D.Dugger@intel.com Ph: (303)440-1368>-----Original Message----- >From: Keir Fraser [mailto:Keir.Fraser@cl.cam.ac.uk] >Sent: Wednesday, March 15, 2006 4:05 PM >To: Dugger, Donald D >Cc: xen-devel@lists.xensource.com >Subject: Re: [Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation > > >On 15 Mar 2006, at 21:56, Donald D. Dugger wrote: > >> 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. > >This patch is very big, especially since the modified qemu >files appear >to already contain support for touchpads. Why is so much code moved >around? Although we do want this support, we really don''t want to >continue our slide away from qemu mainline at an increasing pace! :-) > >Can I apply patches 2 and 3 independent of this one (sounds like patch >2 depends on 3 to avoid causing excessive CPU overhead, but >neither has >dependence on this patch)? > > -- Keir >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2006-Mar-15 23:55 UTC
Re: [Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation
On 15 Mar 2006, at 23:22, Dugger, Donald D wrote:> Yes, the 3 patches are independent so you can apply them as you wish. > > I''m not sure what your concern is about the touchpad patch. There was > code to emulate a touchpad in the code but it was all wrong and didn''t > work, I basically had to re-do all of the touchpad code to get this to > work.Why is it not possible to translate from absolute coordinates provided by VNC into deltas required for PS/2 mouse emulation? Do you end up with accumulating absolute error? -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Anthony Liguori
2006-Mar-16 01:26 UTC
Re: [Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation
Keir Fraser wrote:> > On 15 Mar 2006, at 23:22, Dugger, Donald D wrote: > >> Yes, the 3 patches are independent so you can apply them as you wish. >> >> I''m not sure what your concern is about the touchpad patch. There was >> code to emulate a touchpad in the code but it was all wrong and didn''t >> work, I basically had to re-do all of the touchpad code to get this to >> work. > > Why is it not possible to translate from absolute coordinates provided > by VNC into deltas required for PS/2 mouse emulation? Do you end up > with accumulating absolute error?There are two issues, the first is acceleration. Most guests scale relative coordinates by some factor which is usually configuration so you can control the "speed" of the mouse. The second is that you have no idea where the mouse starts out at or when it gets warped so even if you knew the acceleration you would always be at a fixed offset from the absolute cursor. Since coordinates are only passed when the mouse is within the bounding box of the VNC window, you end up with unreachable portions of the screen depending on you''re offset. Regards, Anthony Liguori> -- Keir > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Dugger, Donald D
2006-Mar-16 01:36 UTC
RE: [Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation
Keir- Multiple problems: 1) As you suspected, roundoff errors add up and cause problems. 2) Cursor position. The cursor is what''s actually moved by the mouse and there''s no way to know where the cursor starts. When you start X, and at other times, the cursor is warped to the center of the screen and there''s no way for `qemu-dm'' to know that this happened. 3) Mouse accelleration. This is the real problem, different cursor handlers, think `gpm'' and X, provide different mouse accellerations so that there''s no way to know how far the cursor actually moves based upon the pointer movement. I''ve not found a way to overcome all of these issues and, given that the Summagraphics devices almost exactly matches what the VNC mouse is providing, doing Summagraphics emulation is the simplest, most natural solution for VNC. -- Don Dugger "Censeo Toto nos in Kansa esse decisse." - D. Gale Donald.D.Dugger@intel.com Ph: (303)440-1368>-----Original Message----- >From: Keir Fraser [mailto:Keir.Fraser@cl.cam.ac.uk] >Sent: Wednesday, March 15, 2006 4:56 PM >To: Dugger, Donald D >Cc: xen-devel@lists.xensource.com >Subject: Re: [Xen-devel] [PATCH 1/3] Add Summagraphics Tablet emulation > > >On 15 Mar 2006, at 23:22, Dugger, Donald D wrote: > >> Yes, the 3 patches are independent so you can apply them as you wish. >> >> I''m not sure what your concern is about the touchpad patch. >There was >> code to emulate a touchpad in the code but it was all wrong >and didn''t >> work, I basically had to re-do all of the touchpad code to >get this to >> work. > >Why is it not possible to translate from absolute coordinates provided >by VNC into deltas required for PS/2 mouse emulation? Do you end up >with accumulating absolute error? > > -- Keir >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel