1 #include "sysemu/sysemu.h"
2 #include "qapi-types.h"
3 #include "qmp-commands.h"
6 #include "ui/console.h"
8 struct QemuInputHandlerState
{
10 QemuInputHandler
*handler
;
13 QTAILQ_ENTRY(QemuInputHandlerState
) node
;
15 static QTAILQ_HEAD(, QemuInputHandlerState
) handlers
=
16 QTAILQ_HEAD_INITIALIZER(handlers
);
17 static NotifierList mouse_mode_notifiers
=
18 NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers
);
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_deactivate(QemuInputHandlerState
*s
)
44 QTAILQ_REMOVE(&handlers
, s
, node
);
45 QTAILQ_INSERT_TAIL(&handlers
, s
, node
);
46 qemu_input_check_mode_change();
49 void qemu_input_handler_unregister(QemuInputHandlerState
*s
)
51 QTAILQ_REMOVE(&handlers
, s
, node
);
53 qemu_input_check_mode_change();
56 static QemuInputHandlerState
*
57 qemu_input_find_handler(uint32_t mask
)
59 QemuInputHandlerState
*s
;
61 QTAILQ_FOREACH(s
, &handlers
, node
) {
62 if (mask
& s
->handler
->mask
) {
69 static void qemu_input_transform_abs_rotate(InputEvent
*evt
)
71 switch (graphic_rotate
) {
73 if (evt
->abs
->axis
== INPUT_AXIS_X
) {
74 evt
->abs
->axis
= INPUT_AXIS_Y
;
75 } else if (evt
->abs
->axis
== INPUT_AXIS_Y
) {
76 evt
->abs
->axis
= INPUT_AXIS_X
;
77 evt
->abs
->value
= INPUT_EVENT_ABS_SIZE
- 1 - evt
->abs
->value
;
81 evt
->abs
->value
= INPUT_EVENT_ABS_SIZE
- 1 - evt
->abs
->value
;
84 if (evt
->abs
->axis
== INPUT_AXIS_X
) {
85 evt
->abs
->axis
= INPUT_AXIS_Y
;
86 evt
->abs
->value
= INPUT_EVENT_ABS_SIZE
- 1 - evt
->abs
->value
;
87 } else if (evt
->abs
->axis
== INPUT_AXIS_Y
) {
88 evt
->abs
->axis
= INPUT_AXIS_X
;
94 static void qemu_input_event_trace(QemuConsole
*src
, InputEvent
*evt
)
100 idx
= qemu_console_get_index(src
);
103 case INPUT_EVENT_KIND_KEY
:
104 switch (evt
->key
->key
->kind
) {
105 case KEY_VALUE_KIND_NUMBER
:
106 qcode
= qemu_input_key_number_to_qcode(evt
->key
->key
->number
);
107 name
= QKeyCode_lookup
[qcode
];
108 trace_input_event_key_number(idx
, evt
->key
->key
->number
,
109 name
, evt
->key
->down
);
111 case KEY_VALUE_KIND_QCODE
:
112 name
= QKeyCode_lookup
[evt
->key
->key
->qcode
];
113 trace_input_event_key_qcode(idx
, name
, evt
->key
->down
);
115 case KEY_VALUE_KIND_MAX
:
120 case INPUT_EVENT_KIND_BTN
:
121 name
= InputButton_lookup
[evt
->btn
->button
];
122 trace_input_event_btn(idx
, name
, evt
->btn
->down
);
124 case INPUT_EVENT_KIND_REL
:
125 name
= InputAxis_lookup
[evt
->rel
->axis
];
126 trace_input_event_rel(idx
, name
, evt
->rel
->value
);
128 case INPUT_EVENT_KIND_ABS
:
129 name
= InputAxis_lookup
[evt
->abs
->axis
];
130 trace_input_event_abs(idx
, name
, evt
->abs
->value
);
132 case INPUT_EVENT_KIND_MAX
:
138 void qemu_input_event_send(QemuConsole
*src
, InputEvent
*evt
)
140 QemuInputHandlerState
*s
;
142 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED
)) {
146 qemu_input_event_trace(src
, evt
);
149 if (graphic_rotate
&& (evt
->kind
== INPUT_EVENT_KIND_ABS
)) {
150 qemu_input_transform_abs_rotate(evt
);
154 s
= qemu_input_find_handler(1 << evt
->kind
);
158 s
->handler
->event(s
->dev
, src
, evt
);
162 void qemu_input_event_sync(void)
164 QemuInputHandlerState
*s
;
166 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED
)) {
170 trace_input_event_sync();
172 QTAILQ_FOREACH(s
, &handlers
, node
) {
176 if (s
->handler
->sync
) {
177 s
->handler
->sync(s
->dev
);
183 InputEvent
*qemu_input_event_new_key(KeyValue
*key
, bool down
)
185 InputEvent
*evt
= g_new0(InputEvent
, 1);
186 evt
->key
= g_new0(InputKeyEvent
, 1);
187 evt
->kind
= INPUT_EVENT_KIND_KEY
;
189 evt
->key
->down
= down
;
193 void qemu_input_event_send_key(QemuConsole
*src
, KeyValue
*key
, bool down
)
196 evt
= qemu_input_event_new_key(key
, down
);
197 qemu_input_event_send(src
, evt
);
198 qemu_input_event_sync();
199 qapi_free_InputEvent(evt
);
202 void qemu_input_event_send_key_number(QemuConsole
*src
, int num
, bool down
)
204 KeyValue
*key
= g_new0(KeyValue
, 1);
205 key
->kind
= KEY_VALUE_KIND_NUMBER
;
207 qemu_input_event_send_key(src
, key
, down
);
210 void qemu_input_event_send_key_qcode(QemuConsole
*src
, QKeyCode q
, bool down
)
212 KeyValue
*key
= g_new0(KeyValue
, 1);
213 key
->kind
= KEY_VALUE_KIND_QCODE
;
215 qemu_input_event_send_key(src
, key
, down
);
218 InputEvent
*qemu_input_event_new_btn(InputButton btn
, bool down
)
220 InputEvent
*evt
= g_new0(InputEvent
, 1);
221 evt
->btn
= g_new0(InputBtnEvent
, 1);
222 evt
->kind
= INPUT_EVENT_KIND_BTN
;
223 evt
->btn
->button
= btn
;
224 evt
->btn
->down
= down
;
228 void qemu_input_queue_btn(QemuConsole
*src
, InputButton btn
, bool down
)
231 evt
= qemu_input_event_new_btn(btn
, down
);
232 qemu_input_event_send(src
, evt
);
233 qapi_free_InputEvent(evt
);
236 void qemu_input_update_buttons(QemuConsole
*src
, uint32_t *button_map
,
237 uint32_t button_old
, uint32_t button_new
)
242 for (btn
= 0; btn
< INPUT_BUTTON_MAX
; btn
++) {
243 mask
= button_map
[btn
];
244 if ((button_old
& mask
) == (button_new
& mask
)) {
247 qemu_input_queue_btn(src
, btn
, button_new
& mask
);
251 bool qemu_input_is_absolute(void)
253 QemuInputHandlerState
*s
;
255 s
= qemu_input_find_handler(INPUT_EVENT_MASK_REL
| INPUT_EVENT_MASK_ABS
);
256 return (s
!= NULL
) && (s
->handler
->mask
& INPUT_EVENT_MASK_ABS
);
259 int qemu_input_scale_axis(int value
, int size_in
, int size_out
)
264 return (int64_t)value
* (size_out
- 1) / (size_in
- 1);
267 InputEvent
*qemu_input_event_new_move(InputEventKind kind
,
268 InputAxis axis
, int value
)
270 InputEvent
*evt
= g_new0(InputEvent
, 1);
271 InputMoveEvent
*move
= g_new0(InputMoveEvent
, 1);
280 void qemu_input_queue_rel(QemuConsole
*src
, InputAxis axis
, int value
)
283 evt
= qemu_input_event_new_move(INPUT_EVENT_KIND_REL
, axis
, value
);
284 qemu_input_event_send(src
, evt
);
285 qapi_free_InputEvent(evt
);
288 void qemu_input_queue_abs(QemuConsole
*src
, InputAxis axis
, int value
, int size
)
291 int scaled
= qemu_input_scale_axis(value
, size
, INPUT_EVENT_ABS_SIZE
);
292 evt
= qemu_input_event_new_move(INPUT_EVENT_KIND_ABS
, axis
, scaled
);
293 qemu_input_event_send(src
, evt
);
294 qapi_free_InputEvent(evt
);
297 void qemu_input_check_mode_change(void)
299 static int current_is_absolute
;
302 is_absolute
= qemu_input_is_absolute();
304 if (is_absolute
!= current_is_absolute
) {
305 trace_input_mouse_mode(is_absolute
);
306 notifier_list_notify(&mouse_mode_notifiers
, NULL
);
309 current_is_absolute
= is_absolute
;
312 void qemu_add_mouse_mode_change_notifier(Notifier
*notify
)
314 notifier_list_add(&mouse_mode_notifiers
, notify
);
317 void qemu_remove_mouse_mode_change_notifier(Notifier
*notify
)
319 notifier_remove(notify
);
322 MouseInfoList
*qmp_query_mice(Error
**errp
)
324 MouseInfoList
*mice_list
= NULL
;
326 QemuInputHandlerState
*s
;
329 QTAILQ_FOREACH(s
, &handlers
, node
) {
330 if (!(s
->handler
->mask
&
331 (INPUT_EVENT_MASK_REL
| INPUT_EVENT_MASK_ABS
))) {
335 info
= g_new0(MouseInfoList
, 1);
336 info
->value
= g_new0(MouseInfo
, 1);
337 info
->value
->index
= s
->id
;
338 info
->value
->name
= g_strdup(s
->handler
->name
);
339 info
->value
->absolute
= s
->handler
->mask
& INPUT_EVENT_MASK_ABS
;
340 info
->value
->current
= current
;
343 info
->next
= mice_list
;
350 void do_mouse_set(Monitor
*mon
, const QDict
*qdict
)
352 QemuInputHandlerState
*s
;
353 int index
= qdict_get_int(qdict
, "index");
356 QTAILQ_FOREACH(s
, &handlers
, node
) {
357 if (s
->id
!= index
) {
360 if (!(s
->handler
->mask
& (INPUT_EVENT_MASK_REL
|
361 INPUT_EVENT_MASK_ABS
))) {
362 error_report("Input device '%s' is not a mouse", s
->handler
->name
);
366 qemu_input_handler_activate(s
);
371 error_report("Mouse at index '%d' not found", index
);
374 qemu_input_check_mode_change();