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

[Xen-changelog] Reset Cirrus device model `VRAM' whenever a VGA/SVGA mode switch occurs.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 50989084d4d0bd3ae8005469f129259aa4d74f5c
# Parent  25da74e2f8fbf3664fb793c1fb9cde26a485292a
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
---
 tools/ioemu/hw/pc.c     |    5 +
 tools/ioemu/hw/pckbd.c  |  153 +++++++++++++++++++++++++++++++++++-------------
 tools/ioemu/hw/serial.c |    1 
 tools/ioemu/vl.c        |    3 
 tools/ioemu/vl.h        |   13 ++--
 5 files changed, 127 insertions(+), 48 deletions(-)

diff -r 25da74e2f8fb -r 50989084d4d0 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Wed May 10 16:05:24 2006 +0100
+++ b/tools/ioemu/hw/pc.c       Wed May 10 16:06:55 2006 +0100
@@ -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 25da74e2f8fb -r 50989084d4d0 tools/ioemu/hw/pckbd.c
--- a/tools/ioemu/hw/pckbd.c    Wed May 10 16:05:24 2006 +0100
+++ b/tools/ioemu/hw/pckbd.c    Wed May 10 16:06:55 2006 +0100
@@ -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 25da74e2f8fb -r 50989084d4d0 tools/ioemu/hw/serial.c
--- a/tools/ioemu/hw/serial.c   Wed May 10 16:05:24 2006 +0100
+++ b/tools/ioemu/hw/serial.c   Wed May 10 16:06:55 2006 +0100
@@ -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 25da74e2f8fb -r 50989084d4d0 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Wed May 10 16:05:24 2006 +0100
+++ b/tools/ioemu/vl.c  Wed May 10 16:06:55 2006 +0100
@@ -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 25da74e2f8fb -r 50989084d4d0 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Wed May 10 16:05:24 2006 +0100
+++ b/tools/ioemu/vl.h  Wed May 10 16:06:55 2006 +0100
@@ -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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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