2 #include "sysemu/sysemu.h"
3 #include "qapi-types.h"
4 #include "qmp-commands.h"
7 #include "ui/console.h"
9 struct QemuInputHandlerState
{
11 QemuInputHandler
*handler
;
15 QTAILQ_ENTRY(QemuInputHandlerState
) node
;
18 typedef struct QemuInputEventQueue QemuInputEventQueue
;
19 struct QemuInputEventQueue
{
21 QEMU_INPUT_QUEUE_DELAY
= 1,
22 QEMU_INPUT_QUEUE_EVENT
,
23 QEMU_INPUT_QUEUE_SYNC
,
29 QTAILQ_ENTRY(QemuInputEventQueue
) node
;
32 static QTAILQ_HEAD(, QemuInputHandlerState
) handlers
=
33 QTAILQ_HEAD_INITIALIZER(handlers
);
34 static NotifierList mouse_mode_notifiers
=
35 NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers
);
37 static QTAILQ_HEAD(QemuInputEventQueueHead
, QemuInputEventQueue
) kbd_queue
=
38 QTAILQ_HEAD_INITIALIZER(kbd_queue
);
39 static QEMUTimer
*kbd_timer
;
40 static uint32_t kbd_default_delay_ms
= 10;
42 QemuInputHandlerState
*qemu_input_handler_register(DeviceState
*dev
,
43 QemuInputHandler
*handler
)
45 QemuInputHandlerState
*s
= g_new0(QemuInputHandlerState
, 1);
51 QTAILQ_INSERT_TAIL(&handlers
, s
, node
);
53 qemu_input_check_mode_change();
57 void qemu_input_handler_activate(QemuInputHandlerState
*s
)
59 QTAILQ_REMOVE(&handlers
, s
, node
);
60 QTAILQ_INSERT_HEAD(&handlers
, s
, node
);
61 qemu_input_check_mode_change();
64 void qemu_input_handler_deactivate(QemuInputHandlerState
*s
)
66 QTAILQ_REMOVE(&handlers
, s
, node
);
67 QTAILQ_INSERT_TAIL(&handlers
, s
, node
);
68 qemu_input_check_mode_change();
71 void qemu_input_handler_unregister(QemuInputHandlerState
*s
)
73 QTAILQ_REMOVE(&handlers
, s
, node
);
75 qemu_input_check_mode_change();
78 void qemu_input_handler_bind(QemuInputHandlerState
*s
,
79 const char *device_id
, int head
,
85 dev
= qdev_find_recursive(sysbus_get_default(), device_id
);
87 error_set(errp
, QERR_DEVICE_NOT_FOUND
, device_id
);
91 con
= qemu_console_lookup_by_device(dev
, head
);
93 error_setg(errp
, "Device %s is not bound to a QemuConsole", device_id
);
100 static QemuInputHandlerState
*
101 qemu_input_find_handler(uint32_t mask
, QemuConsole
*con
)
103 QemuInputHandlerState
*s
;
105 QTAILQ_FOREACH(s
, &handlers
, node
) {
106 if (s
->con
== NULL
|| s
->con
!= con
) {
109 if (mask
& s
->handler
->mask
) {
114 QTAILQ_FOREACH(s
, &handlers
, node
) {
115 if (s
->con
!= NULL
) {
118 if (mask
& s
->handler
->mask
) {
125 static void qemu_input_transform_abs_rotate(InputEvent
*evt
)
127 switch (graphic_rotate
) {
129 if (evt
->abs
->axis
== INPUT_AXIS_X
) {
130 evt
->abs
->axis
= INPUT_AXIS_Y
;
131 } else if (evt
->abs
->axis
== INPUT_AXIS_Y
) {
132 evt
->abs
->axis
= INPUT_AXIS_X
;
133 evt
->abs
->value
= INPUT_EVENT_ABS_SIZE
- 1 - evt
->abs
->value
;
137 evt
->abs
->value
= INPUT_EVENT_ABS_SIZE
- 1 - evt
->abs
->value
;
140 if (evt
->abs
->axis
== INPUT_AXIS_X
) {
141 evt
->abs
->axis
= INPUT_AXIS_Y
;
142 evt
->abs
->value
= INPUT_EVENT_ABS_SIZE
- 1 - evt
->abs
->value
;
143 } else if (evt
->abs
->axis
== INPUT_AXIS_Y
) {
144 evt
->abs
->axis
= INPUT_AXIS_X
;
150 static void qemu_input_event_trace(QemuConsole
*src
, InputEvent
*evt
)
156 idx
= qemu_console_get_index(src
);
159 case INPUT_EVENT_KIND_KEY
:
160 switch (evt
->key
->key
->kind
) {
161 case KEY_VALUE_KIND_NUMBER
:
162 qcode
= qemu_input_key_number_to_qcode(evt
->key
->key
->number
);
163 name
= QKeyCode_lookup
[qcode
];
164 trace_input_event_key_number(idx
, evt
->key
->key
->number
,
165 name
, evt
->key
->down
);
167 case KEY_VALUE_KIND_QCODE
:
168 name
= QKeyCode_lookup
[evt
->key
->key
->qcode
];
169 trace_input_event_key_qcode(idx
, name
, evt
->key
->down
);
171 case KEY_VALUE_KIND_MAX
:
176 case INPUT_EVENT_KIND_BTN
:
177 name
= InputButton_lookup
[evt
->btn
->button
];
178 trace_input_event_btn(idx
, name
, evt
->btn
->down
);
180 case INPUT_EVENT_KIND_REL
:
181 name
= InputAxis_lookup
[evt
->rel
->axis
];
182 trace_input_event_rel(idx
, name
, evt
->rel
->value
);
184 case INPUT_EVENT_KIND_ABS
:
185 name
= InputAxis_lookup
[evt
->abs
->axis
];
186 trace_input_event_abs(idx
, name
, evt
->abs
->value
);
188 case INPUT_EVENT_KIND_MAX
:
194 static void qemu_input_queue_process(void *opaque
)
196 struct QemuInputEventQueueHead
*queue
= opaque
;
197 QemuInputEventQueue
*item
;
199 g_assert(!QTAILQ_EMPTY(queue
));
200 item
= QTAILQ_FIRST(queue
);
201 g_assert(item
->type
== QEMU_INPUT_QUEUE_DELAY
);
202 QTAILQ_REMOVE(queue
, item
, node
);
205 while (!QTAILQ_EMPTY(queue
)) {
206 item
= QTAILQ_FIRST(queue
);
207 switch (item
->type
) {
208 case QEMU_INPUT_QUEUE_DELAY
:
209 timer_mod(item
->timer
, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL
)
212 case QEMU_INPUT_QUEUE_EVENT
:
213 qemu_input_event_send(item
->src
, item
->evt
);
214 qapi_free_InputEvent(item
->evt
);
216 case QEMU_INPUT_QUEUE_SYNC
:
217 qemu_input_event_sync();
220 QTAILQ_REMOVE(queue
, item
, node
);
225 static void qemu_input_queue_delay(struct QemuInputEventQueueHead
*queue
,
226 QEMUTimer
*timer
, uint32_t delay_ms
)
228 QemuInputEventQueue
*item
= g_new0(QemuInputEventQueue
, 1);
229 bool start_timer
= QTAILQ_EMPTY(queue
);
231 item
->type
= QEMU_INPUT_QUEUE_DELAY
;
232 item
->delay_ms
= delay_ms
;
234 QTAILQ_INSERT_TAIL(queue
, item
, node
);
237 timer_mod(item
->timer
, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL
)
242 static void qemu_input_queue_event(struct QemuInputEventQueueHead
*queue
,
243 QemuConsole
*src
, InputEvent
*evt
)
245 QemuInputEventQueue
*item
= g_new0(QemuInputEventQueue
, 1);
247 item
->type
= QEMU_INPUT_QUEUE_EVENT
;
250 QTAILQ_INSERT_TAIL(queue
, item
, node
);
253 static void qemu_input_queue_sync(struct QemuInputEventQueueHead
*queue
)
255 QemuInputEventQueue
*item
= g_new0(QemuInputEventQueue
, 1);
257 item
->type
= QEMU_INPUT_QUEUE_SYNC
;
258 QTAILQ_INSERT_TAIL(queue
, item
, node
);
261 void qemu_input_event_send(QemuConsole
*src
, InputEvent
*evt
)
263 QemuInputHandlerState
*s
;
265 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED
)) {
269 qemu_input_event_trace(src
, evt
);
272 if (graphic_rotate
&& (evt
->kind
== INPUT_EVENT_KIND_ABS
)) {
273 qemu_input_transform_abs_rotate(evt
);
277 s
= qemu_input_find_handler(1 << evt
->kind
, src
);
281 s
->handler
->event(s
->dev
, src
, evt
);
285 void qemu_input_event_sync(void)
287 QemuInputHandlerState
*s
;
289 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED
)) {
293 trace_input_event_sync();
295 QTAILQ_FOREACH(s
, &handlers
, node
) {
299 if (s
->handler
->sync
) {
300 s
->handler
->sync(s
->dev
);
306 InputEvent
*qemu_input_event_new_key(KeyValue
*key
, bool down
)
308 InputEvent
*evt
= g_new0(InputEvent
, 1);
309 evt
->key
= g_new0(InputKeyEvent
, 1);
310 evt
->kind
= INPUT_EVENT_KIND_KEY
;
312 evt
->key
->down
= down
;
316 void qemu_input_event_send_key(QemuConsole
*src
, KeyValue
*key
, bool down
)
319 evt
= qemu_input_event_new_key(key
, down
);
320 if (QTAILQ_EMPTY(&kbd_queue
)) {
321 qemu_input_event_send(src
, evt
);
322 qemu_input_event_sync();
323 qapi_free_InputEvent(evt
);
325 qemu_input_queue_event(&kbd_queue
, src
, evt
);
326 qemu_input_queue_sync(&kbd_queue
);
330 void qemu_input_event_send_key_number(QemuConsole
*src
, int num
, bool down
)
332 KeyValue
*key
= g_new0(KeyValue
, 1);
333 key
->kind
= KEY_VALUE_KIND_NUMBER
;
335 qemu_input_event_send_key(src
, key
, down
);
338 void qemu_input_event_send_key_qcode(QemuConsole
*src
, QKeyCode q
, bool down
)
340 KeyValue
*key
= g_new0(KeyValue
, 1);
341 key
->kind
= KEY_VALUE_KIND_QCODE
;
343 qemu_input_event_send_key(src
, key
, down
);
346 void qemu_input_event_send_key_delay(uint32_t delay_ms
)
349 kbd_timer
= timer_new_ms(QEMU_CLOCK_VIRTUAL
, qemu_input_queue_process
,
352 qemu_input_queue_delay(&kbd_queue
, kbd_timer
,
353 delay_ms
? delay_ms
: kbd_default_delay_ms
);
356 InputEvent
*qemu_input_event_new_btn(InputButton btn
, bool down
)
358 InputEvent
*evt
= g_new0(InputEvent
, 1);
359 evt
->btn
= g_new0(InputBtnEvent
, 1);
360 evt
->kind
= INPUT_EVENT_KIND_BTN
;
361 evt
->btn
->button
= btn
;
362 evt
->btn
->down
= down
;
366 void qemu_input_queue_btn(QemuConsole
*src
, InputButton btn
, bool down
)
369 evt
= qemu_input_event_new_btn(btn
, down
);
370 qemu_input_event_send(src
, evt
);
371 qapi_free_InputEvent(evt
);
374 void qemu_input_update_buttons(QemuConsole
*src
, uint32_t *button_map
,
375 uint32_t button_old
, uint32_t button_new
)
380 for (btn
= 0; btn
< INPUT_BUTTON_MAX
; btn
++) {
381 mask
= button_map
[btn
];
382 if ((button_old
& mask
) == (button_new
& mask
)) {
385 qemu_input_queue_btn(src
, btn
, button_new
& mask
);
389 bool qemu_input_is_absolute(void)
391 QemuInputHandlerState
*s
;
393 s
= qemu_input_find_handler(INPUT_EVENT_MASK_REL
| INPUT_EVENT_MASK_ABS
,
395 return (s
!= NULL
) && (s
->handler
->mask
& INPUT_EVENT_MASK_ABS
);
398 int qemu_input_scale_axis(int value
, int size_in
, int size_out
)
403 return (int64_t)value
* (size_out
- 1) / (size_in
- 1);
406 InputEvent
*qemu_input_event_new_move(InputEventKind kind
,
407 InputAxis axis
, int value
)
409 InputEvent
*evt
= g_new0(InputEvent
, 1);
410 InputMoveEvent
*move
= g_new0(InputMoveEvent
, 1);
419 void qemu_input_queue_rel(QemuConsole
*src
, InputAxis axis
, int value
)
422 evt
= qemu_input_event_new_move(INPUT_EVENT_KIND_REL
, axis
, value
);
423 qemu_input_event_send(src
, evt
);
424 qapi_free_InputEvent(evt
);
427 void qemu_input_queue_abs(QemuConsole
*src
, InputAxis axis
, int value
, int size
)
430 int scaled
= qemu_input_scale_axis(value
, size
, INPUT_EVENT_ABS_SIZE
);
431 evt
= qemu_input_event_new_move(INPUT_EVENT_KIND_ABS
, axis
, scaled
);
432 qemu_input_event_send(src
, evt
);
433 qapi_free_InputEvent(evt
);
436 void qemu_input_check_mode_change(void)
438 static int current_is_absolute
;
441 is_absolute
= qemu_input_is_absolute();
443 if (is_absolute
!= current_is_absolute
) {
444 trace_input_mouse_mode(is_absolute
);
445 notifier_list_notify(&mouse_mode_notifiers
, NULL
);
448 current_is_absolute
= is_absolute
;
451 void qemu_add_mouse_mode_change_notifier(Notifier
*notify
)
453 notifier_list_add(&mouse_mode_notifiers
, notify
);
456 void qemu_remove_mouse_mode_change_notifier(Notifier
*notify
)
458 notifier_remove(notify
);
461 MouseInfoList
*qmp_query_mice(Error
**errp
)
463 MouseInfoList
*mice_list
= NULL
;
465 QemuInputHandlerState
*s
;
468 QTAILQ_FOREACH(s
, &handlers
, node
) {
469 if (!(s
->handler
->mask
&
470 (INPUT_EVENT_MASK_REL
| INPUT_EVENT_MASK_ABS
))) {
474 info
= g_new0(MouseInfoList
, 1);
475 info
->value
= g_new0(MouseInfo
, 1);
476 info
->value
->index
= s
->id
;
477 info
->value
->name
= g_strdup(s
->handler
->name
);
478 info
->value
->absolute
= s
->handler
->mask
& INPUT_EVENT_MASK_ABS
;
479 info
->value
->current
= current
;
482 info
->next
= mice_list
;
489 void do_mouse_set(Monitor
*mon
, const QDict
*qdict
)
491 QemuInputHandlerState
*s
;
492 int index
= qdict_get_int(qdict
, "index");
495 QTAILQ_FOREACH(s
, &handlers
, node
) {
496 if (s
->id
!= index
) {
499 if (!(s
->handler
->mask
& (INPUT_EVENT_MASK_REL
|
500 INPUT_EVENT_MASK_ABS
))) {
501 error_report("Input device '%s' is not a mouse", s
->handler
->name
);
505 qemu_input_handler_activate(s
);
510 error_report("Mouse at index '%d' not found", index
);
513 qemu_input_check_mode_change();