mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-14 07:20:42 +00:00
Dynamic handling of guest mice, by Lonnie Mendez.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2290 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
6f30fa853b
commit
455204eb1a
2
hw/adb.c
2
hw/adb.c
@ -406,5 +406,5 @@ void adb_mouse_init(ADBBusState *bus)
|
|||||||
d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
|
d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
|
||||||
adb_mouse_reset, s);
|
adb_mouse_reset, s);
|
||||||
adb_mouse_reset(d);
|
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");
|
||||||
}
|
}
|
||||||
|
2
hw/ps2.c
2
hw/ps2.c
@ -560,7 +560,7 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
|
|||||||
s->common.update_arg = update_arg;
|
s->common.update_arg = update_arg;
|
||||||
ps2_reset(&s->common);
|
ps2_reset(&s->common);
|
||||||
register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s);
|
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);
|
qemu_register_reset(ps2_reset, &s->common);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -682,7 +682,7 @@ void slavio_serial_ms_kbd_init(int base, int irq)
|
|||||||
slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
|
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);
|
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_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
|
||||||
qemu_register_reset(slavio_serial_reset, s);
|
qemu_register_reset(slavio_serial_reset, s);
|
||||||
slavio_serial_reset(s);
|
slavio_serial_reset(s);
|
||||||
|
@ -39,6 +39,7 @@ typedef struct USBMouseState {
|
|||||||
int x, y;
|
int x, y;
|
||||||
int kind;
|
int kind;
|
||||||
int mouse_grabbed;
|
int mouse_grabbed;
|
||||||
|
QEMUPutMouseEntry *eh_entry;
|
||||||
} USBMouseState;
|
} USBMouseState;
|
||||||
|
|
||||||
/* mostly the same values as the Bochs USB Mouse device */
|
/* mostly the same values as the Bochs USB Mouse device */
|
||||||
@ -259,7 +260,8 @@ static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len)
|
|||||||
int dx, dy, dz, b, l;
|
int dx, dy, dz, b, l;
|
||||||
|
|
||||||
if (!s->mouse_grabbed) {
|
if (!s->mouse_grabbed) {
|
||||||
qemu_add_mouse_event_handler(usb_mouse_event, s, 0);
|
s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s,
|
||||||
|
0, "QEMU USB Mouse");
|
||||||
s->mouse_grabbed = 1;
|
s->mouse_grabbed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +297,8 @@ static int usb_tablet_poll(USBMouseState *s, uint8_t *buf, int len)
|
|||||||
int dz, b, l;
|
int dz, b, l;
|
||||||
|
|
||||||
if (!s->mouse_grabbed) {
|
if (!s->mouse_grabbed) {
|
||||||
qemu_add_mouse_event_handler(usb_tablet_event, s, 1);
|
s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, s,
|
||||||
|
1, "QEMU USB Tablet");
|
||||||
s->mouse_grabbed = 1;
|
s->mouse_grabbed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,7 +506,7 @@ static void usb_mouse_handle_destroy(USBDevice *dev)
|
|||||||
{
|
{
|
||||||
USBMouseState *s = (USBMouseState *)dev;
|
USBMouseState *s = (USBMouseState *)dev;
|
||||||
|
|
||||||
qemu_add_mouse_event_handler(NULL, NULL, 0);
|
qemu_remove_mouse_event_handler(s->eh_entry);
|
||||||
qemu_free(s);
|
qemu_free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1241,6 +1241,8 @@ static term_cmd_t term_cmds[] = {
|
|||||||
"dx dy [dz]", "send mouse move events" },
|
"dx dy [dz]", "send mouse move events" },
|
||||||
{ "mouse_button", "i", do_mouse_button,
|
{ "mouse_button", "i", do_mouse_button,
|
||||||
"state", "change mouse button state (1=L, 2=M, 4=R)" },
|
"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
|
#ifdef HAS_AUDIO
|
||||||
{ "wavcapture", "si?i?i?", do_wav_capture,
|
{ "wavcapture", "si?i?i?", do_wav_capture,
|
||||||
"path [frequency bits channels]",
|
"path [frequency bits channels]",
|
||||||
@ -1292,6 +1294,8 @@ static term_cmd_t info_cmds[] = {
|
|||||||
"", "show capture information" },
|
"", "show capture information" },
|
||||||
{ "snapshots", "", do_info_snapshots,
|
{ "snapshots", "", do_info_snapshots,
|
||||||
"", "show the currently saved VM snapshots" },
|
"", "show the currently saved VM snapshots" },
|
||||||
|
{ "mice", "", do_info_mice,
|
||||||
|
"", "show which guest mouse is receiving events" },
|
||||||
{ NULL, NULL, },
|
{ NULL, NULL, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -781,6 +781,8 @@ show all USB host devices
|
|||||||
show information about active capturing
|
show information about active capturing
|
||||||
@item info snapshots
|
@item info snapshots
|
||||||
show list of VM snapshots
|
show list of VM snapshots
|
||||||
|
@item info mice
|
||||||
|
show which guest mouse is receiving events
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@item q or quit
|
@item q or quit
|
||||||
@ -795,6 +797,20 @@ Change a removable media.
|
|||||||
@item screendump filename
|
@item screendump filename
|
||||||
Save screen into PPM image @var{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]]]
|
@item wavcapture filename [frequency [bits [channels]]]
|
||||||
Capture audio into @var{filename}. Using sample rate @var{frequency}
|
Capture audio into @var{filename}. Using sample rate @var{frequency}
|
||||||
bits per sample @var{bits} and number of channels @var{channels}.
|
bits per sample @var{bits} and number of channels @var{channels}.
|
||||||
|
7
sdl.c
7
sdl.c
@ -319,6 +319,7 @@ static void sdl_show_cursor(void)
|
|||||||
{
|
{
|
||||||
if (!kbd_mouse_is_absolute()) {
|
if (!kbd_mouse_is_absolute()) {
|
||||||
SDL_ShowCursor(1);
|
SDL_ShowCursor(1);
|
||||||
|
SDL_SetCursor(sdl_cursor_normal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,6 +365,9 @@ static void sdl_send_mouse_event(int dz)
|
|||||||
SDL_GetMouseState(&dx, &dy);
|
SDL_GetMouseState(&dx, &dy);
|
||||||
dx = dx * 0x7FFF / width;
|
dx = dx * 0x7FFF / width;
|
||||||
dy = dy * 0x7FFF / height;
|
dy = dy * 0x7FFF / height;
|
||||||
|
} else if (absolute_enabled) {
|
||||||
|
sdl_show_cursor();
|
||||||
|
absolute_enabled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
kbd_mouse_event(dx, dy, dz, buttons);
|
kbd_mouse_event(dx, dy, dz, buttons);
|
||||||
@ -501,7 +505,8 @@ static void sdl_refresh(DisplayState *ds)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEMOTION:
|
case SDL_MOUSEMOTION:
|
||||||
if (gui_grab || kbd_mouse_is_absolute()) {
|
if (gui_grab || kbd_mouse_is_absolute() ||
|
||||||
|
absolute_enabled) {
|
||||||
sdl_send_mouse_event(0);
|
sdl_send_mouse_event(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
135
vl.c
135
vl.c
@ -463,9 +463,8 @@ void hw_error(const char *fmt, ...)
|
|||||||
|
|
||||||
static QEMUPutKBDEvent *qemu_put_kbd_event;
|
static QEMUPutKBDEvent *qemu_put_kbd_event;
|
||||||
static void *qemu_put_kbd_event_opaque;
|
static void *qemu_put_kbd_event_opaque;
|
||||||
static QEMUPutMouseEvent *qemu_put_mouse_event;
|
static QEMUPutMouseEntry *qemu_put_mouse_event_head;
|
||||||
static void *qemu_put_mouse_event_opaque;
|
static QEMUPutMouseEntry *qemu_put_mouse_event_current;
|
||||||
static int qemu_put_mouse_event_absolute;
|
|
||||||
|
|
||||||
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
|
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
|
||||||
{
|
{
|
||||||
@ -473,11 +472,68 @@ void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
|
|||||||
qemu_put_kbd_event = func;
|
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;
|
QEMUPutMouseEntry *s, *cursor;
|
||||||
qemu_put_mouse_event = func;
|
|
||||||
qemu_put_mouse_event_absolute = absolute;
|
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 == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cursor = qemu_put_mouse_event_head;
|
||||||
|
while (cursor != NULL && cursor != entry) {
|
||||||
|
prev = cursor;
|
||||||
|
cursor = cursor->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor == NULL) // does not exist or list empty
|
||||||
|
return;
|
||||||
|
else if (prev == NULL) { // 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)
|
void kbd_put_keycode(int keycode)
|
||||||
@ -489,15 +545,72 @@ void kbd_put_keycode(int keycode)
|
|||||||
|
|
||||||
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
|
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
|
||||||
{
|
{
|
||||||
if (qemu_put_mouse_event) {
|
QEMUPutMouseEvent *mouse_event;
|
||||||
qemu_put_mouse_event(qemu_put_mouse_event_opaque,
|
void *mouse_event_opaque;
|
||||||
dx, dy, dz, buttons_state);
|
|
||||||
|
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)
|
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("%c Mouse #%d: %s\n",
|
||||||
|
(cursor == qemu_put_mouse_event_current ? '*' : ' '),
|
||||||
|
index, 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 != NULL)
|
||||||
|
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 */
|
/* compute with 96 bit intermediate result: (a*b)/c */
|
||||||
|
18
vl.h
18
vl.h
@ -172,13 +172,29 @@ extern int no_quit;
|
|||||||
typedef void QEMUPutKBDEvent(void *opaque, int keycode);
|
typedef void QEMUPutKBDEvent(void *opaque, int keycode);
|
||||||
typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
|
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;
|
||||||
|
int qemu_put_mouse_event_absolute;
|
||||||
|
char *qemu_put_mouse_event_name;
|
||||||
|
|
||||||
|
/* used internally by qemu for handling mice */
|
||||||
|
struct QEMUPutMouseEntry *next;
|
||||||
|
} QEMUPutMouseEntry;
|
||||||
|
|
||||||
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
|
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_put_keycode(int keycode);
|
||||||
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
|
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
|
||||||
int kbd_mouse_is_absolute(void);
|
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
|
/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
|
||||||
constants) */
|
constants) */
|
||||||
#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
|
#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
|
||||||
|
Loading…
Reference in New Issue
Block a user