* [Qemu-devel] [PATCH] dynamic handling of guest mice
@ 2006-11-26 23:29 Lonnie Mendez
0 siblings, 0 replies; only message in thread
From: Lonnie Mendez @ 2006-11-26 23:29 UTC (permalink / raw)
To: qemu-devel
[-- 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}.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2006-11-26 23:30 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-26 23:29 [Qemu-devel] [PATCH] dynamic handling of guest mice Lonnie Mendez
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).