ia64/xen-unstable

changeset 10035:50989084d4d0

This patch enhances the Summagraphics emulation by adding 2 features:

1) Move the tablet to the second serial port. This way the tablet will
not interfere with people who want to use a serial console on the guest.

2) Enhance the Summagraphics emulation so that the Windows XP driver
works. Turns out the Windows driver was using capabilities the X driver
didn't care about and it wouldn't recognize the tablet without these
capabilities.

Signed-off-by: donald.d.dugger@intel.com
author kaf24@firebug.cl.cam.ac.uk
date Wed May 10 16:06:55 2006 +0100 (2006-05-10)
parents 25da74e2f8fb
children 4b4d16fe0b05
files tools/ioemu/hw/pc.c tools/ioemu/hw/pckbd.c tools/ioemu/hw/serial.c tools/ioemu/vl.c tools/ioemu/vl.h
line diff
     1.1 --- a/tools/ioemu/hw/pc.c	Wed May 10 16:05:24 2006 +0100
     1.2 +++ b/tools/ioemu/hw/pc.c	Wed May 10 16:06:55 2006 +0100
     1.3 @@ -381,6 +381,7 @@ void pc_init(uint64_t ram_size, int vga_
     1.4               const char *kernel_filename, const char *kernel_cmdline,
     1.5               const char *initrd_filename)
     1.6  {
     1.7 +    SerialState *sp;
     1.8      char buf[1024];
     1.9      int ret, linux_boot, initrd_size, i, nb_nics1;
    1.10      PCIBus *pci_bus;
    1.11 @@ -533,7 +534,9 @@ void pc_init(uint64_t ram_size, int vga_
    1.12  
    1.13      for(i = 0; i < MAX_SERIAL_PORTS; i++) {
    1.14          if (serial_hds[i]) {
    1.15 -            serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
    1.16 +            sp = serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
    1.17 +            if (i == SUMMA_PORT)
    1.18 +		summa_init(sp, serial_hds[i]);
    1.19          }
    1.20      }
    1.21  
     2.1 --- a/tools/ioemu/hw/pckbd.c	Wed May 10 16:05:24 2006 +0100
     2.2 +++ b/tools/ioemu/hw/pckbd.c	Wed May 10 16:06:55 2006 +0100
     2.3 @@ -156,11 +156,24 @@ typedef struct KBDState {
     2.4      int mouse_dz;
     2.5      uint8_t mouse_buttons;
     2.6      CharDriverState *chr;
     2.7 -    void *cookie;
     2.8 +    SerialState *serial;
     2.9  } KBDState;
    2.10  
    2.11  KBDState kbd_state;
    2.12  
    2.13 +#define MODE_STREAM_SWITCH	0
    2.14 +#define MODE_STREAM		1
    2.15 +#define MODE_REMOTE		2
    2.16 +#define MODE_POINT		3
    2.17 +
    2.18 +#define ORIGIN_LOWER_LEFT	0
    2.19 +#define ORIGIN_UPPER_LEFT	1
    2.20 +
    2.21 +struct SummaState {
    2.22 +	int report_mode;
    2.23 +	int origin;
    2.24 +} SummaState;
    2.25 +
    2.26  int summa_ok;		/* Allow Summagraphics emulation if true */
    2.27  
    2.28  /* update irq and KBD_STAT_[MOUSE_]OBF */
    2.29 @@ -420,15 +433,19 @@ static int kbd_mouse_send_packet(KBDStat
    2.30      switch(s->mouse_type) {
    2.31    
    2.32      case TABLET:        /* Summagraphics pen tablet */
    2.33 -	dx1 = s->mouse_x;
    2.34 -	dy1 = s->mouse_y;
    2.35 -	dx1 = ((dx1 * SUMMA_MAXX) / mouse_maxx) + SUMMA_BORDER;
    2.36 -	dy1 = ((dy1 * SUMMA_MAXY) / mouse_maxy) + SUMMA_BORDER;
    2.37 -	ser_queue(s->cookie, 0x80 | (s->mouse_buttons & 7));
    2.38 -	ser_queue(s->cookie, dx1 & 0x7f);
    2.39 -	ser_queue(s->cookie, dx1 >> 7);
    2.40 -	ser_queue(s->cookie, dy1 & 0x7f);
    2.41 -	ser_queue(s->cookie, dy1 >> 7);
    2.42 +	if (SummaState.report_mode == MODE_STREAM) {
    2.43 +	    dx1 = s->mouse_x;
    2.44 +	    dy1 = s->mouse_y;
    2.45 +	    if (SummaState.origin == ORIGIN_LOWER_LEFT)
    2.46 +		dy1 = mouse_maxy - dy1;
    2.47 +	    dx1 = ((dx1 * SUMMA_MAXX) / mouse_maxx) + SUMMA_BORDER;
    2.48 +	    dy1 = ((dy1 * SUMMA_MAXY) / mouse_maxy) + SUMMA_BORDER;
    2.49 +	    ser_queue(s->serial, 0x80 | (s->mouse_buttons & 7));
    2.50 +	    ser_queue(s->serial, dx1 & 0x7f);
    2.51 +	    ser_queue(s->serial, dx1 >> 7);
    2.52 +	    ser_queue(s->serial, dy1 & 0x7f);
    2.53 +	    ser_queue(s->serial, dy1 >> 7);
    2.54 +	}
    2.55  	s->mouse_dx = 0; 
    2.56  	s->mouse_dy = 0;
    2.57  	s->mouse_dz = 0;
    2.58 @@ -509,43 +526,101 @@ static void pc_kbd_mouse_event(void *opa
    2.59      }
    2.60  }
    2.61  
    2.62 -static void summa(KBDState *s, int val)
    2.63 +static void summa(KBDState *s, uint8_t val)
    2.64  {
    2.65 -    static int summa = 0;
    2.66 +    static int zflg = 0;
    2.67  
    2.68 -    if (s->mouse_type == TABLET) {
    2.69 +    if (zflg) {
    2.70 +	zflg = 0;
    2.71  	switch (val) {
    2.72  
    2.73 -	case '?':	/* read firmware ID */
    2.74 -	    ser_queue(s->cookie, '0');
    2.75 +	case 'b':	/* binary report mode */
    2.76  	    break;
    2.77  
    2.78 -	case 'a':	/* read config */
    2.79 -	    /*
    2.80 -	     *  Config looks like a movement packet but, because of scaling
    2.81 -	     *    issues we can't use `kbd_send_packet' to do this.
    2.82 -	     */
    2.83 -	    ser_queue(s->cookie, 0);
    2.84 -	    ser_queue(s->cookie, (SUMMA_MAXX & 0x7f));
    2.85 -	    ser_queue(s->cookie, (SUMMA_MAXX >> 7));
    2.86 -	    ser_queue(s->cookie, (SUMMA_MAXY & 0x7f));
    2.87 -	    ser_queue(s->cookie, (SUMMA_MAXY >> 7));
    2.88 -	    break;
    2.89 -
    2.90 -	default:	/* ignore all others */
    2.91 +	case 't':	/* stylus type - we do 4 button cursor */
    2.92 +	    ser_queue(s->serial, 'C');
    2.93 +	    ser_queue(s->serial, 'S');
    2.94 +	    ser_queue(s->serial, 'R');
    2.95 +	    ser_queue(s->serial, '4');
    2.96 +	    ser_queue(s->serial, '\r');
    2.97  	    break;
    2.98  
    2.99  	}
   2.100  	return;
   2.101      }
   2.102 -    if (val == 'B') {
   2.103 -	summa++;
   2.104 -	return;
   2.105 -    } else if (summa && val == 'z') {
   2.106 +    zflg = 0;
   2.107 +
   2.108 +    switch (val) {
   2.109 +
   2.110 +    case 'B':	/* point mode */
   2.111 +	/* This is supposed to be `set to point mode' but the Linux driver
   2.112 +	 *   is broken and incorrectly sends a reset command (somebody
   2.113 +	 *   needs to learn that the address 0 does not necessarily contain
   2.114 +	 *   a zero).  This is the first valid command that Linux sends
   2.115 +	 *   out so we'll treat it as a reset
   2.116 +	 */
   2.117 +    case '\0':	/* reset */
   2.118  	s->mouse_type = TABLET;
   2.119 -	return;
   2.120 +	s->mouse_status |= MOUSE_STATUS_ENABLED;
   2.121 +	SummaState.origin = ORIGIN_LOWER_LEFT;
   2.122 +	SummaState.report_mode = (val == 'B') ? MODE_POINT : MODE_STREAM_SWITCH;
   2.123 +	break;
   2.124 +
   2.125 +    case 'z':	/* start of 2 byte command */
   2.126 +	zflg++;
   2.127 +	break;
   2.128 +
   2.129 +    case 'x':	/* code check */
   2.130 +	/*
   2.131 +	 *  Return checksum
   2.132 +	 */
   2.133 +	ser_queue(s->serial, '.');
   2.134 +	ser_queue(s->serial, '#');
   2.135 +	ser_queue(s->serial, '1');
   2.136 +	ser_queue(s->serial, '2');
   2.137 +	ser_queue(s->serial, '3');
   2.138 +	ser_queue(s->serial, '4');
   2.139 +	break;
   2.140 +
   2.141 +    case '?':	/* read firmware ID */
   2.142 +	ser_queue(s->serial, '0');
   2.143 +	break;
   2.144 +
   2.145 +    case 'a':	/* read config */
   2.146 +	/*
   2.147 +	 *  Config looks like a movement packet but, because of scaling
   2.148 +	 *    issues we can't use `kbd_send_packet' to do this.
   2.149 +	 */
   2.150 +	ser_queue(s->serial, 0x94);
   2.151 +	ser_queue(s->serial, (SUMMA_MAXX & 0x7f));
   2.152 +	ser_queue(s->serial, (SUMMA_MAXX >> 7));
   2.153 +	ser_queue(s->serial, (SUMMA_MAXY & 0x7f));
   2.154 +	ser_queue(s->serial, (SUMMA_MAXY >> 7));
   2.155 +	break;
   2.156 +
   2.157 +    case 'b':	/* origin at upper left */
   2.158 +	SummaState.origin = ORIGIN_UPPER_LEFT;
   2.159 +	break;
   2.160 +
   2.161 +    case 'c':	/* origin at lower left */
   2.162 +	SummaState.origin = ORIGIN_LOWER_LEFT;
   2.163 +	break;
   2.164 +
   2.165 +    case '@':	/* stream mode */
   2.166 +	SummaState.report_mode = MODE_STREAM;
   2.167 +	break;
   2.168 +
   2.169 +    case 'D':	/* remote request mode */
   2.170 +	SummaState.report_mode = MODE_REMOTE;
   2.171 +	break;
   2.172 +
   2.173 +    case 'P':	/* trigger, e.g. send report now */
   2.174 +    case 'R':	/* report rate = max/2 */
   2.175 +    default:	/* ignore all others */
   2.176 +	break;
   2.177 +
   2.178      }
   2.179 -    summa = 0;
   2.180 +
   2.181      return;
   2.182  }
   2.183  
   2.184 @@ -560,13 +635,13 @@ int summa_write(CharDriverState *chr, co
   2.185      return len;
   2.186  }
   2.187  
   2.188 -void summa_init(void *cookie, CharDriverState *chr)
   2.189 +void summa_init(SerialState *serial, CharDriverState *chr)
   2.190  {
   2.191  
   2.192      if (summa_ok == 0)
   2.193  	return;
   2.194      kbd_state.chr = chr;
   2.195 -    kbd_state.cookie = (void *)cookie;
   2.196 +    kbd_state.serial = serial;
   2.197      chr->chr_write = summa_write;
   2.198      chr->opaque = (void *)&kbd_state;
   2.199      return;
     3.1 --- a/tools/ioemu/hw/serial.c	Wed May 10 16:05:24 2006 +0100
     3.2 +++ b/tools/ioemu/hw/serial.c	Wed May 10 16:06:55 2006 +0100
     3.3 @@ -310,7 +310,6 @@ SerialState *serial_init(int base, int i
     3.4      register_ioport_write(base, 8, 1, serial_ioport_write, s);
     3.5      register_ioport_read(base, 8, 1, serial_ioport_read, s);
     3.6      s->chr = chr;
     3.7 -    summa_init(s, chr);
     3.8      qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
     3.9      qemu_chr_add_event_handler(chr, serial_event);
    3.10      return s;
     4.1 --- a/tools/ioemu/vl.c	Wed May 10 16:05:24 2006 +0100
     4.2 +++ b/tools/ioemu/vl.c	Wed May 10 16:06:55 2006 +0100
     4.3 @@ -2707,7 +2707,8 @@ int main(int argc, char **argv)
     4.4      pstrcpy(monitor_device, sizeof(monitor_device), "vc");
     4.5  
     4.6      pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
     4.7 -    for(i = 1; i < MAX_SERIAL_PORTS; i++)
     4.8 +    pstrcpy(serial_devices[1], sizeof(serial_devices[1]), "null");
     4.9 +    for(i = 2; i < MAX_SERIAL_PORTS; i++)
    4.10          serial_devices[i][0] = '\0';
    4.11      serial_device_index = 0;
    4.12  
     5.1 --- a/tools/ioemu/vl.h	Wed May 10 16:05:24 2006 +0100
     5.2 +++ b/tools/ioemu/vl.h	Wed May 10 16:06:55 2006 +0100
     5.3 @@ -223,6 +223,7 @@ void console_select(unsigned int index);
     5.4  /* serial ports */
     5.5  
     5.6  #define MAX_SERIAL_PORTS 4
     5.7 +#define SUMMA_PORT	1
     5.8  
     5.9  extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
    5.10  
    5.11 @@ -618,12 +619,6 @@ void kbd_init(void);
    5.12  extern const char* keyboard_layout;
    5.13  extern int repeat_key;
    5.14  
    5.15 -/* Mice */
    5.16 -
    5.17 -void summa_init(void *cookie, CharDriverState *chr);
    5.18 -
    5.19 -extern int summa_ok;
    5.20 -
    5.21  /* mc146818rtc.c */
    5.22  
    5.23  typedef struct RTCState RTCState;
    5.24 @@ -638,6 +633,12 @@ typedef struct SerialState SerialState;
    5.25  SerialState *serial_init(int base, int irq, CharDriverState *chr);
    5.26  void ser_queue(SerialState *s, unsigned char c);
    5.27  
    5.28 +/* Mice */
    5.29 +
    5.30 +void summa_init(SerialState *serial, CharDriverState *chr);
    5.31 +
    5.32 +extern int summa_ok;
    5.33 +
    5.34  /* i8259.c */
    5.35  
    5.36  void pic_set_irq(int irq, int level);