4
* Copyright (c) 2003-2008 Fabrice Bellard
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
* of this software and associated documentation files (the "Software"), to deal
8
* in the Software without restriction, including without limitation the rights
9
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
* copies of the Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
1
#include "sysemu/sysemu.h"
26
#include "monitor/monitor.h"
2
#include "qapi-types.h"
3
#include "qmp-commands.h"
27
6
#include "ui/console.h"
28
#include "qapi/error.h"
29
#include "qmp-commands.h"
30
#include "qapi-types.h"
31
#include "ui/keymaps.h"
33
struct QEMUPutMouseEntry {
34
QEMUPutMouseEvent *qemu_put_mouse_event;
35
void *qemu_put_mouse_event_opaque;
36
int qemu_put_mouse_event_absolute;
37
char *qemu_put_mouse_event_name;
41
/* used internally by qemu for handling mice */
42
QTAILQ_ENTRY(QEMUPutMouseEntry) node;
45
struct QEMUPutKbdEntry {
46
QEMUPutKBDEvent *put_kbd;
48
QTAILQ_ENTRY(QEMUPutKbdEntry) next;
51
struct QEMUPutLEDEntry {
52
QEMUPutLEDEvent *put_led;
54
QTAILQ_ENTRY(QEMUPutLEDEntry) next;
57
static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers =
58
QTAILQ_HEAD_INITIALIZER(led_handlers);
59
static QTAILQ_HEAD(, QEMUPutKbdEntry) kbd_handlers =
60
QTAILQ_HEAD_INITIALIZER(kbd_handlers);
61
static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers =
62
QTAILQ_HEAD_INITIALIZER(mouse_handlers);
8
struct QemuInputHandlerState {
10
QemuInputHandler *handler;
13
QTAILQ_ENTRY(QemuInputHandlerState) node;
15
static QTAILQ_HEAD(, QemuInputHandlerState) handlers =
16
QTAILQ_HEAD_INITIALIZER(handlers);
63
17
static NotifierList mouse_mode_notifiers =
64
18
NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
66
static const int key_defs[] = {
67
[Q_KEY_CODE_SHIFT] = 0x2a,
68
[Q_KEY_CODE_SHIFT_R] = 0x36,
70
[Q_KEY_CODE_ALT] = 0x38,
71
[Q_KEY_CODE_ALT_R] = 0xb8,
72
[Q_KEY_CODE_ALTGR] = 0x64,
73
[Q_KEY_CODE_ALTGR_R] = 0xe4,
74
[Q_KEY_CODE_CTRL] = 0x1d,
75
[Q_KEY_CODE_CTRL_R] = 0x9d,
77
[Q_KEY_CODE_MENU] = 0xdd,
79
[Q_KEY_CODE_ESC] = 0x01,
81
[Q_KEY_CODE_1] = 0x02,
82
[Q_KEY_CODE_2] = 0x03,
83
[Q_KEY_CODE_3] = 0x04,
84
[Q_KEY_CODE_4] = 0x05,
85
[Q_KEY_CODE_5] = 0x06,
86
[Q_KEY_CODE_6] = 0x07,
87
[Q_KEY_CODE_7] = 0x08,
88
[Q_KEY_CODE_8] = 0x09,
89
[Q_KEY_CODE_9] = 0x0a,
90
[Q_KEY_CODE_0] = 0x0b,
91
[Q_KEY_CODE_MINUS] = 0x0c,
92
[Q_KEY_CODE_EQUAL] = 0x0d,
93
[Q_KEY_CODE_BACKSPACE] = 0x0e,
95
[Q_KEY_CODE_TAB] = 0x0f,
96
[Q_KEY_CODE_Q] = 0x10,
97
[Q_KEY_CODE_W] = 0x11,
98
[Q_KEY_CODE_E] = 0x12,
99
[Q_KEY_CODE_R] = 0x13,
100
[Q_KEY_CODE_T] = 0x14,
101
[Q_KEY_CODE_Y] = 0x15,
102
[Q_KEY_CODE_U] = 0x16,
103
[Q_KEY_CODE_I] = 0x17,
104
[Q_KEY_CODE_O] = 0x18,
105
[Q_KEY_CODE_P] = 0x19,
106
[Q_KEY_CODE_BRACKET_LEFT] = 0x1a,
107
[Q_KEY_CODE_BRACKET_RIGHT] = 0x1b,
108
[Q_KEY_CODE_RET] = 0x1c,
110
[Q_KEY_CODE_A] = 0x1e,
111
[Q_KEY_CODE_S] = 0x1f,
112
[Q_KEY_CODE_D] = 0x20,
113
[Q_KEY_CODE_F] = 0x21,
114
[Q_KEY_CODE_G] = 0x22,
115
[Q_KEY_CODE_H] = 0x23,
116
[Q_KEY_CODE_J] = 0x24,
117
[Q_KEY_CODE_K] = 0x25,
118
[Q_KEY_CODE_L] = 0x26,
119
[Q_KEY_CODE_SEMICOLON] = 0x27,
120
[Q_KEY_CODE_APOSTROPHE] = 0x28,
121
[Q_KEY_CODE_GRAVE_ACCENT] = 0x29,
123
[Q_KEY_CODE_BACKSLASH] = 0x2b,
124
[Q_KEY_CODE_Z] = 0x2c,
125
[Q_KEY_CODE_X] = 0x2d,
126
[Q_KEY_CODE_C] = 0x2e,
127
[Q_KEY_CODE_V] = 0x2f,
128
[Q_KEY_CODE_B] = 0x30,
129
[Q_KEY_CODE_N] = 0x31,
130
[Q_KEY_CODE_M] = 0x32,
131
[Q_KEY_CODE_COMMA] = 0x33,
132
[Q_KEY_CODE_DOT] = 0x34,
133
[Q_KEY_CODE_SLASH] = 0x35,
135
[Q_KEY_CODE_ASTERISK] = 0x37,
137
[Q_KEY_CODE_SPC] = 0x39,
138
[Q_KEY_CODE_CAPS_LOCK] = 0x3a,
139
[Q_KEY_CODE_F1] = 0x3b,
140
[Q_KEY_CODE_F2] = 0x3c,
141
[Q_KEY_CODE_F3] = 0x3d,
142
[Q_KEY_CODE_F4] = 0x3e,
143
[Q_KEY_CODE_F5] = 0x3f,
144
[Q_KEY_CODE_F6] = 0x40,
145
[Q_KEY_CODE_F7] = 0x41,
146
[Q_KEY_CODE_F8] = 0x42,
147
[Q_KEY_CODE_F9] = 0x43,
148
[Q_KEY_CODE_F10] = 0x44,
149
[Q_KEY_CODE_NUM_LOCK] = 0x45,
150
[Q_KEY_CODE_SCROLL_LOCK] = 0x46,
152
[Q_KEY_CODE_KP_DIVIDE] = 0xb5,
153
[Q_KEY_CODE_KP_MULTIPLY] = 0x37,
154
[Q_KEY_CODE_KP_SUBTRACT] = 0x4a,
155
[Q_KEY_CODE_KP_ADD] = 0x4e,
156
[Q_KEY_CODE_KP_ENTER] = 0x9c,
157
[Q_KEY_CODE_KP_DECIMAL] = 0x53,
158
[Q_KEY_CODE_SYSRQ] = 0x54,
160
[Q_KEY_CODE_KP_0] = 0x52,
161
[Q_KEY_CODE_KP_1] = 0x4f,
162
[Q_KEY_CODE_KP_2] = 0x50,
163
[Q_KEY_CODE_KP_3] = 0x51,
164
[Q_KEY_CODE_KP_4] = 0x4b,
165
[Q_KEY_CODE_KP_5] = 0x4c,
166
[Q_KEY_CODE_KP_6] = 0x4d,
167
[Q_KEY_CODE_KP_7] = 0x47,
168
[Q_KEY_CODE_KP_8] = 0x48,
169
[Q_KEY_CODE_KP_9] = 0x49,
171
[Q_KEY_CODE_LESS] = 0x56,
173
[Q_KEY_CODE_F11] = 0x57,
174
[Q_KEY_CODE_F12] = 0x58,
176
[Q_KEY_CODE_PRINT] = 0xb7,
178
[Q_KEY_CODE_HOME] = 0xc7,
179
[Q_KEY_CODE_PGUP] = 0xc9,
180
[Q_KEY_CODE_PGDN] = 0xd1,
181
[Q_KEY_CODE_END] = 0xcf,
183
[Q_KEY_CODE_LEFT] = 0xcb,
184
[Q_KEY_CODE_UP] = 0xc8,
185
[Q_KEY_CODE_DOWN] = 0xd0,
186
[Q_KEY_CODE_RIGHT] = 0xcd,
188
[Q_KEY_CODE_INSERT] = 0xd2,
189
[Q_KEY_CODE_DELETE] = 0xd3,
191
#if defined(TARGET_SPARC) && !defined(TARGET_SPARC64)
192
[Q_KEY_CODE_STOP] = 0xf0,
193
[Q_KEY_CODE_AGAIN] = 0xf1,
194
[Q_KEY_CODE_PROPS] = 0xf2,
195
[Q_KEY_CODE_UNDO] = 0xf3,
196
[Q_KEY_CODE_FRONT] = 0xf4,
197
[Q_KEY_CODE_COPY] = 0xf5,
198
[Q_KEY_CODE_OPEN] = 0xf6,
199
[Q_KEY_CODE_PASTE] = 0xf7,
200
[Q_KEY_CODE_FIND] = 0xf8,
201
[Q_KEY_CODE_CUT] = 0xf9,
202
[Q_KEY_CODE_LF] = 0xfa,
203
[Q_KEY_CODE_HELP] = 0xfb,
204
[Q_KEY_CODE_META_L] = 0xfc,
205
[Q_KEY_CODE_META_R] = 0xfd,
206
[Q_KEY_CODE_COMPOSE] = 0xfe,
209
[Q_KEY_CODE_MAX] = 0,
212
int index_from_key(const char *key)
216
for (i = 0; QKeyCode_lookup[i] != NULL; i++) {
217
if (!strcmp(key, QKeyCode_lookup[i])) {
222
/* Return Q_KEY_CODE_MAX if the key is invalid */
226
int index_from_keycode(int code)
230
for (i = 0; i < Q_KEY_CODE_MAX; i++) {
231
if (key_defs[i] == code) {
236
/* Return Q_KEY_CODE_MAX if the code is invalid */
240
static int *keycodes;
241
static int keycodes_size;
242
static QEMUTimer *key_timer;
244
static int keycode_from_keyvalue(const KeyValue *value)
246
if (value->kind == KEY_VALUE_KIND_QCODE) {
247
return key_defs[value->qcode];
249
assert(value->kind == KEY_VALUE_KIND_NUMBER);
250
return value->number;
254
static void free_keycodes(void)
261
static void release_keys(void *opaque)
263
while (keycodes_size > 0) {
264
if (keycodes[--keycodes_size] & SCANCODE_GREY) {
265
kbd_put_keycode(SCANCODE_EMUL0);
267
kbd_put_keycode(keycodes[keycodes_size] | SCANCODE_UP);
273
void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
280
key_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, release_keys, NULL);
283
if (keycodes != NULL) {
284
timer_del(key_timer);
288
if (!has_hold_time) {
292
for (p = keys; p != NULL; p = p->next) {
293
/* key down events */
294
keycode = keycode_from_keyvalue(p->value);
295
if (keycode < 0x01 || keycode > 0xff) {
296
error_setg(errp, "invalid hex keycode 0x%x", keycode);
301
if (keycode & SCANCODE_GREY) {
302
kbd_put_keycode(SCANCODE_EMUL0);
304
kbd_put_keycode(keycode & SCANCODE_KEYCODEMASK);
306
keycodes = g_realloc(keycodes, sizeof(int) * (keycodes_size + 1));
307
keycodes[keycodes_size++] = keycode;
310
/* delayed key up events */
311
timer_mod(key_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
312
muldiv64(get_ticks_per_sec(), hold_time, 1000));
315
QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
317
QEMUPutKbdEntry *entry;
319
entry = g_malloc0(sizeof(QEMUPutKbdEntry));
320
entry->put_kbd = func;
321
entry->opaque = opaque;
322
QTAILQ_INSERT_HEAD(&kbd_handlers, entry, next);
326
void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry)
328
QTAILQ_REMOVE(&kbd_handlers, entry, next);
331
static void check_mode_change(void)
333
static int current_is_absolute, current_has_absolute;
20
QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev,
21
QemuInputHandler *handler)
23
QemuInputHandlerState *s = g_new0(QemuInputHandlerState, 1);
29
QTAILQ_INSERT_TAIL(&handlers, s, node);
31
qemu_input_check_mode_change();
35
void qemu_input_handler_activate(QemuInputHandlerState *s)
37
QTAILQ_REMOVE(&handlers, s, node);
38
QTAILQ_INSERT_HEAD(&handlers, s, node);
39
qemu_input_check_mode_change();
42
void qemu_input_handler_unregister(QemuInputHandlerState *s)
44
QTAILQ_REMOVE(&handlers, s, node);
46
qemu_input_check_mode_change();
49
static QemuInputHandlerState*
50
qemu_input_find_handler(uint32_t mask)
52
QemuInputHandlerState *s;
54
QTAILQ_FOREACH(s, &handlers, node) {
55
if (mask & s->handler->mask) {
62
static void qemu_input_transform_abs_rotate(InputEvent *evt)
64
switch (graphic_rotate) {
66
if (evt->abs->axis == INPUT_AXIS_X) {
67
evt->abs->axis = INPUT_AXIS_Y;
68
} else if (evt->abs->axis == INPUT_AXIS_Y) {
69
evt->abs->axis = INPUT_AXIS_X;
70
evt->abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->value;
74
evt->abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->value;
77
if (evt->abs->axis == INPUT_AXIS_X) {
78
evt->abs->axis = INPUT_AXIS_Y;
79
evt->abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->value;
80
} else if (evt->abs->axis == INPUT_AXIS_Y) {
81
evt->abs->axis = INPUT_AXIS_X;
87
static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)
93
idx = qemu_console_get_index(src);
96
case INPUT_EVENT_KIND_KEY:
97
switch (evt->key->key->kind) {
98
case KEY_VALUE_KIND_NUMBER:
99
trace_input_event_key_number(idx, evt->key->key->number,
102
case KEY_VALUE_KIND_QCODE:
103
name = QKeyCode_lookup[evt->key->key->qcode];
104
trace_input_event_key_qcode(idx, name, evt->key->down);
106
case KEY_VALUE_KIND_MAX:
111
case INPUT_EVENT_KIND_BTN:
112
name = InputButton_lookup[evt->btn->button];
113
trace_input_event_btn(idx, name, evt->btn->down);
115
case INPUT_EVENT_KIND_REL:
116
name = InputAxis_lookup[evt->rel->axis];
117
trace_input_event_rel(idx, name, evt->rel->value);
119
case INPUT_EVENT_KIND_ABS:
120
name = InputAxis_lookup[evt->abs->axis];
121
trace_input_event_abs(idx, name, evt->abs->value);
123
case INPUT_EVENT_KIND_MAX:
129
void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
131
QemuInputHandlerState *s;
133
if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
137
qemu_input_event_trace(src, evt);
140
if (graphic_rotate && (evt->kind == INPUT_EVENT_KIND_ABS)) {
141
qemu_input_transform_abs_rotate(evt);
145
s = qemu_input_find_handler(1 << evt->kind);
149
s->handler->event(s->dev, src, evt);
153
void qemu_input_event_sync(void)
155
QemuInputHandlerState *s;
157
if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
161
trace_input_event_sync();
163
QTAILQ_FOREACH(s, &handlers, node) {
167
if (s->handler->sync) {
168
s->handler->sync(s->dev);
174
InputEvent *qemu_input_event_new_key(KeyValue *key, bool down)
176
InputEvent *evt = g_new0(InputEvent, 1);
177
evt->key = g_new0(InputKeyEvent, 1);
178
evt->kind = INPUT_EVENT_KIND_KEY;
180
evt->key->down = down;
184
void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
187
evt = qemu_input_event_new_key(key, down);
188
qemu_input_event_send(src, evt);
189
qemu_input_event_sync();
190
qapi_free_InputEvent(evt);
193
void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down)
195
KeyValue *key = g_new0(KeyValue, 1);
196
key->kind = KEY_VALUE_KIND_NUMBER;
198
qemu_input_event_send_key(src, key, down);
201
void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down)
203
KeyValue *key = g_new0(KeyValue, 1);
204
key->kind = KEY_VALUE_KIND_QCODE;
206
qemu_input_event_send_key(src, key, down);
209
InputEvent *qemu_input_event_new_btn(InputButton btn, bool down)
211
InputEvent *evt = g_new0(InputEvent, 1);
212
evt->btn = g_new0(InputBtnEvent, 1);
213
evt->kind = INPUT_EVENT_KIND_BTN;
214
evt->btn->button = btn;
215
evt->btn->down = down;
219
void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down)
222
evt = qemu_input_event_new_btn(btn, down);
223
qemu_input_event_send(src, evt);
224
qapi_free_InputEvent(evt);
227
void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map,
228
uint32_t button_old, uint32_t button_new)
233
for (btn = 0; btn < INPUT_BUTTON_MAX; btn++) {
234
mask = button_map[btn];
235
if ((button_old & mask) == (button_new & mask)) {
238
qemu_input_queue_btn(src, btn, button_new & mask);
242
bool qemu_input_is_absolute(void)
244
QemuInputHandlerState *s;
246
s = qemu_input_find_handler(INPUT_EVENT_MASK_REL | INPUT_EVENT_MASK_ABS);
247
return (s != NULL) && (s->handler->mask & INPUT_EVENT_MASK_ABS);
250
int qemu_input_scale_axis(int value, int size_in, int size_out)
255
return (int64_t)value * (size_out - 1) / (size_in - 1);
258
InputEvent *qemu_input_event_new_move(InputEventKind kind,
259
InputAxis axis, int value)
261
InputEvent *evt = g_new0(InputEvent, 1);
262
InputMoveEvent *move = g_new0(InputMoveEvent, 1);
271
void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value)
274
evt = qemu_input_event_new_move(INPUT_EVENT_KIND_REL, axis, value);
275
qemu_input_event_send(src, evt);
276
qapi_free_InputEvent(evt);
279
void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, int size)
282
int scaled = qemu_input_scale_axis(value, size, INPUT_EVENT_ABS_SIZE);
283
evt = qemu_input_event_new_move(INPUT_EVENT_KIND_ABS, axis, scaled);
284
qemu_input_event_send(src, evt);
285
qapi_free_InputEvent(evt);
288
void qemu_input_check_mode_change(void)
290
static int current_is_absolute;
337
is_absolute = kbd_mouse_is_absolute();
338
has_absolute = kbd_mouse_has_absolute();
340
if (is_absolute != current_is_absolute ||
341
has_absolute != current_has_absolute) {
293
is_absolute = qemu_input_is_absolute();
295
if (is_absolute != current_is_absolute) {
296
trace_input_mouse_mode(is_absolute);
342
297
notifier_list_notify(&mouse_mode_notifiers, NULL);
345
300
current_is_absolute = is_absolute;
346
current_has_absolute = has_absolute;
349
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
350
void *opaque, int absolute,
353
QEMUPutMouseEntry *s;
354
static int mouse_index = 0;
356
s = g_malloc0(sizeof(QEMUPutMouseEntry));
358
s->qemu_put_mouse_event = func;
359
s->qemu_put_mouse_event_opaque = opaque;
360
s->qemu_put_mouse_event_absolute = absolute;
361
s->qemu_put_mouse_event_name = g_strdup(name);
362
s->index = mouse_index++;
364
QTAILQ_INSERT_TAIL(&mouse_handlers, s, node);
371
void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry)
373
QTAILQ_REMOVE(&mouse_handlers, entry, node);
374
QTAILQ_INSERT_HEAD(&mouse_handlers, entry, node);
379
void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
381
QTAILQ_REMOVE(&mouse_handlers, entry, node);
383
g_free(entry->qemu_put_mouse_event_name);
389
QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func,
394
s = g_malloc0(sizeof(QEMUPutLEDEntry));
398
QTAILQ_INSERT_TAIL(&led_handlers, s, next);
402
void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
406
QTAILQ_REMOVE(&led_handlers, entry, next);
410
void kbd_put_keycode(int keycode)
412
QEMUPutKbdEntry *entry = QTAILQ_FIRST(&kbd_handlers);
414
if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
418
entry->put_kbd(entry->opaque, keycode);
422
void kbd_put_ledstate(int ledstate)
424
QEMUPutLEDEntry *cursor;
426
QTAILQ_FOREACH(cursor, &led_handlers, next) {
427
cursor->put_led(cursor->opaque, ledstate);
431
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
433
QEMUPutMouseEntry *entry;
434
QEMUPutMouseEvent *mouse_event;
435
void *mouse_event_opaque;
438
if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
441
if (QTAILQ_EMPTY(&mouse_handlers)) {
445
entry = QTAILQ_FIRST(&mouse_handlers);
447
mouse_event = entry->qemu_put_mouse_event;
448
mouse_event_opaque = entry->qemu_put_mouse_event_opaque;
451
if (entry->qemu_put_mouse_event_absolute) {
455
width = graphic_width - 1;
456
height = graphic_height - 1;
459
switch (graphic_rotate) {
461
mouse_event(mouse_event_opaque,
462
dx, dy, dz, buttons_state);
465
mouse_event(mouse_event_opaque,
466
width - dy, dx, dz, buttons_state);
469
mouse_event(mouse_event_opaque,
470
width - dx, height - dy, dz, buttons_state);
473
mouse_event(mouse_event_opaque,
474
dy, height - dx, dz, buttons_state);
480
int kbd_mouse_is_absolute(void)
482
if (QTAILQ_EMPTY(&mouse_handlers)) {
486
return QTAILQ_FIRST(&mouse_handlers)->qemu_put_mouse_event_absolute;
489
int kbd_mouse_has_absolute(void)
491
QEMUPutMouseEntry *entry;
493
QTAILQ_FOREACH(entry, &mouse_handlers, node) {
494
if (entry->qemu_put_mouse_event_absolute) {
303
void qemu_add_mouse_mode_change_notifier(Notifier *notify)
305
notifier_list_add(&mouse_mode_notifiers, notify);
308
void qemu_remove_mouse_mode_change_notifier(Notifier *notify)
310
notifier_remove(notify);
502
313
MouseInfoList *qmp_query_mice(Error **errp)
504
315
MouseInfoList *mice_list = NULL;
505
QEMUPutMouseEntry *cursor;
317
QemuInputHandlerState *s;
506
318
bool current = true;
508
QTAILQ_FOREACH(cursor, &mouse_handlers, node) {
509
MouseInfoList *info = g_malloc0(sizeof(*info));
510
info->value = g_malloc0(sizeof(*info->value));
511
info->value->name = g_strdup(cursor->qemu_put_mouse_event_name);
512
info->value->index = cursor->index;
513
info->value->absolute = !!cursor->qemu_put_mouse_event_absolute;
320
QTAILQ_FOREACH(s, &handlers, node) {
321
if (!(s->handler->mask &
322
(INPUT_EVENT_MASK_REL | INPUT_EVENT_MASK_ABS))) {
326
info = g_new0(MouseInfoList, 1);
327
info->value = g_new0(MouseInfo, 1);
328
info->value->index = s->id;
329
info->value->name = g_strdup(s->handler->name);
330
info->value->absolute = s->handler->mask & INPUT_EVENT_MASK_ABS;
514
331
info->value->current = current;
518
334
info->next = mice_list;
519
335
mice_list = info;