# 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
|