[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] Fixes for the Summagraphics emulation



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@xxxxxxxxx

PS:  You can get the Windows XP driver at:

        http://www.cad-plan.com/files/download/tw2k.exe

To install this Windows driver:

1)  Run the program in your Windows XP guest.
2)  When the program asks for `model', scroll down and select
      `SummaSketch (MM Compatible)'.
3)  When the program asks for `COM Port' specify
      `com2'.
4)  When the program asks for `Cursor Type' specify
      `4 button cursor/puck'.
5)  The guest will be rebooted and, when it comes back up, the mouse/cursor
    should be working properly under VNC.

Note that these instructions only apply if you are using VNC, the
Summagraphics emulation is disabled if you are using SDL.

-- 
Don Dugger
"Censeo Toto nos in Kansa esse decisse." - D. Gale
Donald.D.Dugger@xxxxxxxxx
Ph: (303)440-1368


diff -r 1e3977e029fd tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Mon May  8 19:21:41 2006 +0100
+++ b/tools/ioemu/hw/pc.c       Tue May  9 10:45:58 2006 -0600
@@ -381,6 +381,7 @@ void pc_init(uint64_t ram_size, int vga_
              const char *kernel_filename, const char *kernel_cmdline,
              const char *initrd_filename)
 {
+    SerialState *sp;
     char buf[1024];
     int ret, linux_boot, initrd_size, i, nb_nics1;
     PCIBus *pci_bus;
@@ -533,7 +534,9 @@ void pc_init(uint64_t ram_size, int vga_
 
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_hds[i]) {
-            serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
+            sp = serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
+            if (i == SUMMA_PORT)
+               summa_init(sp, serial_hds[i]);
         }
     }
 
diff -r 1e3977e029fd tools/ioemu/hw/pckbd.c
--- a/tools/ioemu/hw/pckbd.c    Mon May  8 19:21:41 2006 +0100
+++ b/tools/ioemu/hw/pckbd.c    Tue May  9 10:45:58 2006 -0600
@@ -156,10 +156,23 @@ typedef struct KBDState {
     int mouse_dz;
     uint8_t mouse_buttons;
     CharDriverState *chr;
-    void *cookie;
+    SerialState *serial;
 } KBDState;
 
 KBDState kbd_state;
+
+#define MODE_STREAM_SWITCH     0
+#define MODE_STREAM            1
+#define MODE_REMOTE            2
+#define MODE_POINT             3
+
+#define ORIGIN_LOWER_LEFT      0
+#define ORIGIN_UPPER_LEFT      1
+
+struct SummaState {
+       int report_mode;
+       int origin;
+} SummaState;
 
 int summa_ok;          /* Allow Summagraphics emulation if true */
 
@@ -420,15 +433,19 @@ static int kbd_mouse_send_packet(KBDStat
     switch(s->mouse_type) {
   
     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);
+       if (SummaState.report_mode == MODE_STREAM) {
+           dx1 = s->mouse_x;
+           dy1 = s->mouse_y;
+           if (SummaState.origin == ORIGIN_LOWER_LEFT)
+               dy1 = mouse_maxy - dy1;
+           dx1 = ((dx1 * SUMMA_MAXX) / mouse_maxx) + SUMMA_BORDER;
+           dy1 = ((dy1 * SUMMA_MAXY) / mouse_maxy) + SUMMA_BORDER;
+           ser_queue(s->serial, 0x80 | (s->mouse_buttons & 7));
+           ser_queue(s->serial, dx1 & 0x7f);
+           ser_queue(s->serial, dx1 >> 7);
+           ser_queue(s->serial, dy1 & 0x7f);
+           ser_queue(s->serial, dy1 >> 7);
+       }
        s->mouse_dx = 0; 
        s->mouse_dy = 0;
        s->mouse_dz = 0;
@@ -509,43 +526,101 @@ static void pc_kbd_mouse_event(void *opa
     }
 }
 
-static void summa(KBDState *s, int val)
-{
-    static int summa = 0;
-
-    if (s->mouse_type == TABLET) {
+static void summa(KBDState *s, uint8_t val)
+{
+    static int zflg = 0;
+
+    if (zflg) {
+       zflg = 0;
        switch (val) {
 
-       case '?':       /* read firmware ID */
-           ser_queue(s->cookie, '0');
+       case 'b':       /* binary report mode */
            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 */
+       case 't':       /* stylus type - we do 4 button cursor */
+           ser_queue(s->serial, 'C');
+           ser_queue(s->serial, 'S');
+           ser_queue(s->serial, 'R');
+           ser_queue(s->serial, '4');
+           ser_queue(s->serial, '\r');
            break;
 
        }
        return;
     }
-    if (val == 'B') {
-       summa++;
-       return;
-    } else if (summa && val == 'z') {
+    zflg = 0;
+
+    switch (val) {
+
+    case 'B':  /* point mode */
+       /* This is supposed to be `set to point mode' but the Linux driver
+        *   is broken and incorrectly sends a reset command (somebody
+        *   needs to learn that the address 0 does not necessarily contain
+        *   a zero).  This is the first valid command that Linux sends
+        *   out so we'll treat it as a reset
+        */
+    case '\0': /* reset */
        s->mouse_type = TABLET;
-       return;
-    }
-    summa = 0;
+       s->mouse_status |= MOUSE_STATUS_ENABLED;
+       SummaState.origin = ORIGIN_LOWER_LEFT;
+       SummaState.report_mode = (val == 'B') ? MODE_POINT : MODE_STREAM_SWITCH;
+       break;
+
+    case 'z':  /* start of 2 byte command */
+       zflg++;
+       break;
+
+    case 'x':  /* code check */
+       /*
+        *  Return checksum
+        */
+       ser_queue(s->serial, '.');
+       ser_queue(s->serial, '#');
+       ser_queue(s->serial, '1');
+       ser_queue(s->serial, '2');
+       ser_queue(s->serial, '3');
+       ser_queue(s->serial, '4');
+       break;
+
+    case '?':  /* read firmware ID */
+       ser_queue(s->serial, '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->serial, 0x94);
+       ser_queue(s->serial, (SUMMA_MAXX & 0x7f));
+       ser_queue(s->serial, (SUMMA_MAXX >> 7));
+       ser_queue(s->serial, (SUMMA_MAXY & 0x7f));
+       ser_queue(s->serial, (SUMMA_MAXY >> 7));
+       break;
+
+    case 'b':  /* origin at upper left */
+       SummaState.origin = ORIGIN_UPPER_LEFT;
+       break;
+
+    case 'c':  /* origin at lower left */
+       SummaState.origin = ORIGIN_LOWER_LEFT;
+       break;
+
+    case '@':  /* stream mode */
+       SummaState.report_mode = MODE_STREAM;
+       break;
+
+    case 'D':  /* remote request mode */
+       SummaState.report_mode = MODE_REMOTE;
+       break;
+
+    case 'P':  /* trigger, e.g. send report now */
+    case 'R':  /* report rate = max/2 */
+    default:   /* ignore all others */
+       break;
+
+    }
+
     return;
 }
 
@@ -560,13 +635,13 @@ int summa_write(CharDriverState *chr, co
     return len;
 }
 
-void summa_init(void *cookie, CharDriverState *chr)
+void summa_init(SerialState *serial, CharDriverState *chr)
 {
 
     if (summa_ok == 0)
        return;
     kbd_state.chr = chr;
-    kbd_state.cookie = (void *)cookie;
+    kbd_state.serial = serial;
     chr->chr_write = summa_write;
     chr->opaque = (void *)&kbd_state;
     return;
diff -r 1e3977e029fd tools/ioemu/hw/serial.c
--- a/tools/ioemu/hw/serial.c   Mon May  8 19:21:41 2006 +0100
+++ b/tools/ioemu/hw/serial.c   Tue May  9 10:45:58 2006 -0600
@@ -310,7 +310,6 @@ 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 1e3977e029fd tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Mon May  8 19:21:41 2006 +0100
+++ b/tools/ioemu/vl.c  Tue May  9 10:45:58 2006 -0600
@@ -2707,7 +2707,8 @@ int main(int argc, char **argv)
     pstrcpy(monitor_device, sizeof(monitor_device), "vc");
 
     pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
-    for(i = 1; i < MAX_SERIAL_PORTS; i++)
+    pstrcpy(serial_devices[1], sizeof(serial_devices[1]), "null");
+    for(i = 2; i < MAX_SERIAL_PORTS; i++)
         serial_devices[i][0] = '\0';
     serial_device_index = 0;
 
diff -r 1e3977e029fd tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Mon May  8 19:21:41 2006 +0100
+++ b/tools/ioemu/vl.h  Tue May  9 10:45:58 2006 -0600
@@ -223,6 +223,7 @@ void console_select(unsigned int index);
 /* serial ports */
 
 #define MAX_SERIAL_PORTS 4
+#define SUMMA_PORT     1
 
 extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 
@@ -618,12 +619,6 @@ 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;
@@ -637,6 +632,12 @@ typedef struct SerialState SerialState;
 typedef struct SerialState SerialState;
 SerialState *serial_init(int base, int irq, CharDriverState *chr);
 void ser_queue(SerialState *s, unsigned char c);
+
+/* Mice */
+
+void summa_init(SerialState *serial, CharDriverState *chr);
+
+extern int summa_ok;
 
 /* i8259.c */
 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.