aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/msmouse.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/backends/msmouse.c b/backends/msmouse.c
index 731784ff6c..9ade31b747 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -32,13 +32,35 @@
typedef struct {
CharDriverState *chr;
QEMUPutMouseEntry *entry;
+ uint8_t outbuf[32];
+ int outlen;
} MouseState;
+static void msmouse_chr_accept_input(CharDriverState *chr)
+{
+ MouseState *mouse = chr->opaque;
+ int len;
+
+ len = qemu_chr_be_can_write(chr);
+ if (len > mouse->outlen) {
+ len = mouse->outlen;
+ }
+ if (!len) {
+ return;
+ }
+
+ qemu_chr_be_write(chr, mouse->outbuf, len);
+ mouse->outlen -= len;
+ if (mouse->outlen) {
+ memmove(mouse->outbuf, mouse->outbuf + len, mouse->outlen);
+ }
+}
+
static void msmouse_event(void *opaque,
int dx, int dy, int dz, int buttons_state)
{
CharDriverState *chr = (CharDriverState *)opaque;
-
+ MouseState *mouse = chr->opaque;
unsigned char bytes[4] = { 0x40, 0x00, 0x00, 0x00 };
/* Movement deltas */
@@ -51,10 +73,17 @@ static void msmouse_event(void *opaque,
bytes[0] |= (buttons_state & 0x02 ? 0x10 : 0x00);
bytes[3] |= (buttons_state & 0x04 ? 0x20 : 0x00);
- /* We always send the packet of, so that we do not have to keep track
- of previous state of the middle button. This can potentially confuse
- some very old drivers for two button mice though. */
- qemu_chr_be_write(chr, bytes, 4);
+ if (mouse->outlen <= sizeof(mouse->outbuf) - 4) {
+ /* We always send the packet of, so that we do not have to keep track
+ of previous state of the middle button. This can potentially confuse
+ some very old drivers for two button mice though. */
+ memcpy(mouse->outbuf + mouse->outlen, bytes, 4);
+ mouse->outlen += 4;
+ } else {
+ /* queue full -> drop event */
+ }
+
+ msmouse_chr_accept_input(chr);
}
static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len)
@@ -84,6 +113,7 @@ static CharDriverState *qemu_chr_open_msmouse(const char *id,
chr = qemu_chr_alloc(common, errp);
chr->chr_write = msmouse_chr_write;
chr->chr_close = msmouse_chr_close;
+ chr->chr_accept_input = msmouse_chr_accept_input;
chr->explicit_be_open = true;
mouse = g_new0(MouseState, 1);