All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lonnie Mendez <lmendez19@austin.rr.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] dynamic handling of guest mice
Date: Sun, 26 Nov 2006 17:29:54 -0600	[thread overview]
Message-ID: <1164583794.19394.10.camel@vaio> (raw)

[-- Attachment #1: Type: text/plain, Size: 343 bytes --]

    lo list.  The attached patch allows qemu to handle several guest
mice.  It solves the problem of removing a usb mouse/tablet removable
mouse device and losing all guest input from the ps/2 or other emulated
mouse device.  It will also allow the user to choose which guest mouse
will receive events from the mouse input source on the host.

[-- Attachment #2: qemu-new-mouse-events.diff --]
[-- Type: text/x-patch, Size: 11147 bytes --]

--- qemu/vl.c	2006-10-31 19:44:16.000000000 -0600
+++ qemu/vl.c	2006-11-26 16:53:56.000000000 -0600
@@ -451,9 +451,8 @@
 
 static QEMUPutKBDEvent *qemu_put_kbd_event;
 static void *qemu_put_kbd_event_opaque;
-static QEMUPutMouseEvent *qemu_put_mouse_event;
-static void *qemu_put_mouse_event_opaque;
-static int qemu_put_mouse_event_absolute;
+static QEMUPutMouseEntry *qemu_put_mouse_event_head;
+static QEMUPutMouseEntry *qemu_put_mouse_event_current;
 
 void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
 {
@@ -461,11 +460,68 @@
     qemu_put_kbd_event = func;
 }
 
-void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute)
+QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
+                                                void *opaque, int absolute,
+                                                const char *name)
 {
-    qemu_put_mouse_event_opaque = opaque;
-    qemu_put_mouse_event = func;
-    qemu_put_mouse_event_absolute = absolute;
+    QEMUPutMouseEntry *s, *cursor;
+    
+    s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
+    if (!s)
+        return NULL;
+    
+    s->qemu_put_mouse_event = func;
+    s->qemu_put_mouse_event_opaque = opaque;
+    s->qemu_put_mouse_event_absolute = absolute;
+    s->qemu_put_mouse_event_name = qemu_strdup(name);
+    s->next = NULL;
+    
+    if (!qemu_put_mouse_event_head) {
+        qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
+        return s;
+    }
+    
+    cursor = qemu_put_mouse_event_head;
+    while (cursor->next != NULL)
+        cursor = cursor->next;
+    
+    cursor->next = s;
+    qemu_put_mouse_event_current = s;
+    
+    return s;
+}
+
+void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
+{
+    QEMUPutMouseEntry *prev = NULL, *cursor;
+    
+    if (!qemu_put_mouse_event_head || !entry)
+        return;
+    
+    cursor = qemu_put_mouse_event_head;
+    while (cursor != NULL && cursor != entry) {
+        prev = cursor;
+        cursor = cursor->next;
+    }
+    
+    if (!cursor) // does not exist or list empty
+        return;
+    else if (!prev) { // entry is head
+        qemu_put_mouse_event_head = cursor->next;
+        if (qemu_put_mouse_event_current == entry)
+            qemu_put_mouse_event_current = cursor->next;
+        qemu_free(entry->qemu_put_mouse_event_name);
+        qemu_free(entry);
+        return;
+    }
+    
+    prev->next = entry->next;
+    
+    if (qemu_put_mouse_event_current == entry)
+        qemu_put_mouse_event_current = prev;
+    
+    qemu_free(entry->qemu_put_mouse_event_name);
+    qemu_free(entry);
 }
 
 void kbd_put_keycode(int keycode)
@@ -477,15 +533,72 @@
 
 void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
 {
-    if (qemu_put_mouse_event) {
-        qemu_put_mouse_event(qemu_put_mouse_event_opaque, 
-                             dx, dy, dz, buttons_state);
+    QEMUPutMouseEvent *mouse_event;
+    void *mouse_event_opaque;
+    
+    if (!qemu_put_mouse_event_current) {
+        return;
+    }
+    
+    mouse_event =
+        qemu_put_mouse_event_current->qemu_put_mouse_event;
+    mouse_event_opaque =
+        qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
+    
+    if (mouse_event) {
+        mouse_event(mouse_event_opaque, dx, dy, dz, buttons_state);
     }
 }
 
 int kbd_mouse_is_absolute(void)
 {
-    return qemu_put_mouse_event_absolute;
+    if (!qemu_put_mouse_event_current)
+        return 0;
+    
+    return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
+}
+
+void do_info_mice(void)
+{
+    QEMUPutMouseEntry *cursor;
+    int index = 0;
+    
+    if (!qemu_put_mouse_event_head) {
+        term_printf("No mouse devices connected\n");
+        return;
+    }
+    
+    term_printf("Mouse devices available:\n");
+    cursor = qemu_put_mouse_event_head;
+    while (cursor != NULL) {
+        term_printf("(%d)  %c%s\n", index,
+                    (cursor == qemu_put_mouse_event_current ? '*' : ' '),
+                    cursor->qemu_put_mouse_event_name);
+        index++;
+        cursor = cursor->next;
+    }
+}
+
+void do_mouse_set(int index)
+{
+    QEMUPutMouseEntry *cursor;
+    int i = 0;
+    
+    if (!qemu_put_mouse_event_head) {
+        term_printf("No mouse devices connected\n");
+        return;
+    }
+    
+    cursor = qemu_put_mouse_event_head;
+    while (cursor != NULL && index != i) {
+        i++;
+        cursor = cursor->next;
+    }
+    
+    if (cursor)
+        qemu_put_mouse_event_current = cursor;
+    else
+        term_printf("Mouse at given index not found\n");
 }
 
 /* compute with 96 bit intermediate result: (a*b)/c */
--- qemu/vl.h	2006-09-24 13:49:43.000000000 -0500
+++ qemu/vl.h	2006-11-26 04:38:53.000000000 -0600
@@ -171,13 +171,29 @@
 typedef void QEMUPutKBDEvent(void *opaque, int keycode);
 typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
 
+typedef struct QEMUPutMouseEntry {
+    QEMUPutMouseEvent *qemu_put_mouse_event;
+    void *qemu_put_mouse_event_opaque;
+    char *qemu_put_mouse_event_name;
+    int qemu_put_mouse_event_absolute;
+    
+    /* used internally by qemu for handling mice */
+    struct QEMUPutMouseEntry *next;
+} QEMUPutMouseEntry;
+
 void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
-void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute);
+QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
+                                                void *opaque, int absolute,
+                                                const char *name);
+void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry);
 
 void kbd_put_keycode(int keycode);
 void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
 int kbd_mouse_is_absolute(void);
 
+void do_info_mice(void);
+void do_mouse_set(int index);
+
 /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
    constants) */
 #define QEMU_KEY_ESC1(c) ((c) | 0xe100)
--- qemu/sdl.c	2006-08-19 09:27:30.000000000 -0500
+++ qemu/sdl.c	2006-11-26 17:02:10.000000000 -0600
@@ -319,6 +319,7 @@
 {
     if (!kbd_mouse_is_absolute()) {
         SDL_ShowCursor(1);
+        SDL_SetCursor(sdl_cursor_normal);
     }
 }
 
@@ -364,6 +365,9 @@
 	SDL_GetMouseState(&dx, &dy);
 	dx = dx * 0x7FFF / width;
 	dy = dy * 0x7FFF / height;
+    } else if (absolute_enabled) {
+	sdl_show_cursor();
+	absolute_enabled = 0;
     }
 
     kbd_mouse_event(dx, dy, dz, buttons);
@@ -499,7 +503,8 @@
             qemu_system_shutdown_request();
             break;
         case SDL_MOUSEMOTION:
-            if (gui_grab || kbd_mouse_is_absolute()) {
+            if (gui_grab || kbd_mouse_is_absolute() ||
+                absolute_enabled) {
                 sdl_send_mouse_event(0);
             }
             break;
--- qemu/hw/usb-hid.c	2006-08-11 20:04:27.000000000 -0500
+++ qemu/hw/usb-hid.c	2006-11-26 17:04:29.000000000 -0600
@@ -39,6 +39,7 @@
     int x, y;
     int kind;
     int mouse_grabbed;
+    QEMUPutMouseEntry *eh;
 } USBMouseState;
 
 /* mostly the same values as the Bochs USB Mouse device */
@@ -259,7 +260,7 @@
     int dx, dy, dz, b, l;
 
     if (!s->mouse_grabbed) {
-	qemu_add_mouse_event_handler(usb_mouse_event, s, 0);
+	s->eh = qemu_add_mouse_event_handler(usb_mouse_event, s, 0, "QEMU USB Mouse");
 	s->mouse_grabbed = 1;
     }
     
@@ -295,7 +296,7 @@
     int dz, b, l;
 
     if (!s->mouse_grabbed) {
-	qemu_add_mouse_event_handler(usb_tablet_event, s, 1);
+	s->eh = qemu_add_mouse_event_handler(usb_tablet_event, s, 1, "QEMU USB Tablet");
 	s->mouse_grabbed = 1;
     }
     
@@ -503,7 +504,7 @@
 {
     USBMouseState *s = (USBMouseState *)dev;
 
-    qemu_add_mouse_event_handler(NULL, NULL, 0);
+    qemu_remove_mouse_event_handler(s->eh);
     qemu_free(s);
 }
 
--- qemu/hw/adb.c	2006-04-12 16:59:55.000000000 -0500
+++ qemu/hw/adb.c	2006-11-26 04:12:23.000000000 -0600
@@ -406,5 +406,5 @@
     d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
                             adb_mouse_reset, s);
     adb_mouse_reset(d);
-    qemu_add_mouse_event_handler(adb_mouse_event, d, 0);
+    qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
 }
--- qemu/hw/ps2.c	2006-04-12 16:09:07.000000000 -0500
+++ qemu/hw/ps2.c	2006-11-26 04:03:41.000000000 -0600
@@ -560,7 +560,7 @@
     s->common.update_arg = update_arg;
     ps2_reset(&s->common);
     register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s);
-    qemu_add_mouse_event_handler(ps2_mouse_event, s, 0);
+    qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
     qemu_register_reset(ps2_reset, &s->common);
     return s;
 }
--- qemu/hw/slavio_serial.c	2006-09-09 07:17:15.000000000 -0500
+++ qemu/hw/slavio_serial.c	2006-11-26 04:14:24.000000000 -0600
@@ -682,7 +682,7 @@
     slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
     cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
 
-    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0);
+    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
     qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
     qemu_register_reset(slavio_serial_reset, s);
     slavio_serial_reset(s);
--- qemu/monitor.c	2006-09-25 16:33:49.000000000 -0500
+++ qemu/monitor.c	2006-11-26 16:10:23.000000000 -0600
@@ -1184,6 +1184,8 @@
       "dx dy [dz]", "send mouse move events" },
     { "mouse_button", "i", do_mouse_button, 
       "state", "change mouse button state (1=L, 2=M, 4=R)" },
+    { "mouse_set", "i", do_mouse_set,
+      "index", "set which mouse device receives events" },
 #ifdef HAS_AUDIO
     { "wavcapture", "si?i?i?", do_wav_capture,
       "path [frequency bits channels]",
@@ -1233,6 +1235,8 @@
       "", "show capture information" },
     { "snapshots", "", do_info_snapshots,
       "", "show the currently saved VM snapshots" },
+    { "mice", "", do_info_mice,
+      "", "show which guest mouse is receiving events" },
     { NULL, NULL, },
 };
 
--- qemu/qemu-doc.texi	2006-10-21 19:18:54.000000000 -0500
+++ qemu/qemu-doc.texi	2006-11-26 16:31:58.000000000 -0600
@@ -757,6 +757,8 @@
 show information about active capturing
 @item info snapshots
 show list of VM snapshots
+@item info mice
+show which guest mouse is receiving events
 @end table
 
 @item q or quit
@@ -771,6 +773,20 @@
 @item screendump filename
 Save screen into PPM image @var{filename}.
 
+@item mouse_move dx dy [dz]
+Move the active mouse to the specified coordinates @var{dx} @var{dy}
+with optional scroll axis @var{dz}.
+
+@item mouse_button val
+Change the active mouse button state @var{val} (1=L, 2=M, 4=R).
+
+@item mouse_set index
+Set which mouse device receives events at given @var{index}, index
+can be obtained with
+@example
+info mice
+@end example
+
 @item wavcapture filename [frequency [bits [channels]]]
 Capture audio into @var{filename}. Using sample rate @var{frequency}
 bits per sample @var{bits} and number of channels @var{channels}.

                 reply	other threads:[~2006-11-26 23:30 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1164583794.19394.10.camel@vaio \
    --to=lmendez19@austin.rr.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.