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_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
);
146 s
->handler
->event(s
->dev
, src
, evt
);
150 void qemu_input_event_sync(void)
152 QemuInputHandlerState
*s
;
154 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED
)) {
158 trace_input_event_sync();
160 QTAILQ_FOREACH(s
, &handlers
, node
) {
164 if (s
->handler
->sync
) {
165 s
->handler
->sync(s
->dev
);
171 InputEvent
*qemu_input_event_new_key(KeyValue
*key
, bool down
)
173 InputEvent
*evt
= g_new0(InputEvent
, 1);
174 evt
->key
= g_new0(InputKeyEvent
, 1);
175 evt
->kind
= INPUT_EVENT_KIND_KEY
;
177 evt
->key
->down
= down
;
181 void qemu_input_event_send_key(QemuConsole
*src
, KeyValue
*key
, bool down
)
184 evt
= qemu_input_event_new_key(key
, down
);
185 qemu_input_event_send(src
, evt
);
186 qemu_input_event_sync();
187 qapi_free_InputEvent(evt
);
190 void qemu_input_event_send_key_number(QemuConsole
*src
, int num
, bool down
)
192 KeyValue
*key
= g_new0(KeyValue
, 1);
193 key
->kind
= KEY_VALUE_KIND_NUMBER
;
195 qemu_input_event_send_key(src
, key
, down
);
198 void qemu_input_event_send_key_qcode(QemuConsole
*src
, QKeyCode q
, bool down
)
200 KeyValue
*key
= g_new0(KeyValue
, 1);
201 key
->kind
= KEY_VALUE_KIND_QCODE
;
203 qemu_input_event_send_key(src
, key
, down
);
206 InputEvent
*qemu_input_event_new_btn(InputButton btn
, bool down
)
208 InputEvent
*evt
= g_new0(InputEvent
, 1);
209 evt
->btn
= g_new0(InputBtnEvent
, 1);
210 evt
->kind
= INPUT_EVENT_KIND_BTN
;
211 evt
->btn
->button
= btn
;
212 evt
->btn
->down
= down
;
216 void qemu_input_queue_btn(QemuConsole
*src
, InputButton btn
, bool down
)
219 evt
= qemu_input_event_new_btn(btn
, down
);
220 qemu_input_event_send(src
, evt
);
221 qapi_free_InputEvent(evt
);
224 void qemu_input_update_buttons(QemuConsole
*src
, uint32_t *button_map
,
225 uint32_t button_old
, uint32_t button_new
)
230 for (btn
= 0; btn
< INPUT_BUTTON_MAX
; btn
++) {
231 mask
= button_map
[btn
];
232 if ((button_old
& mask
) == (button_new
& mask
)) {
235 qemu_input_queue_btn(src
, btn
, button_new
& mask
);
239 bool qemu_input_is_absolute(void)
241 QemuInputHandlerState
*s
;
243 s
= qemu_input_find_handler(INPUT_EVENT_MASK_REL
| INPUT_EVENT_MASK_ABS
);
244 return (s
!= NULL
) && (s
->handler
->mask
& INPUT_EVENT_MASK_ABS
);
247 int qemu_input_scale_axis(int value
, int size_in
, int size_out
)
252 return (int64_t)value
* (size_out
- 1) / (size_in
- 1);
255 InputEvent
*qemu_input_event_new_move(InputEventKind kind
,
256 InputAxis axis
, int value
)
258 InputEvent
*evt
= g_new0(InputEvent
, 1);
259 InputMoveEvent
*move
= g_new0(InputMoveEvent
, 1);
268 void qemu_input_queue_rel(QemuConsole
*src
, InputAxis axis
, int value
)
271 evt
= qemu_input_event_new_move(INPUT_EVENT_KIND_REL
, axis
, value
);
272 qemu_input_event_send(src
, evt
);
273 qapi_free_InputEvent(evt
);
276 void qemu_input_queue_abs(QemuConsole
*src
, InputAxis axis
, int value
, int size
)
279 int scaled
= qemu_input_scale_axis(value
, size
, INPUT_EVENT_ABS_SIZE
);
280 evt
= qemu_input_event_new_move(INPUT_EVENT_KIND_ABS
, axis
, scaled
);
281 qemu_input_event_send(src
, evt
);
282 qapi_free_InputEvent(evt
);
285 void qemu_input_check_mode_change(void)
287 static int current_is_absolute
;
290 is_absolute
= qemu_input_is_absolute();
292 if (is_absolute
!= current_is_absolute
) {
293 trace_input_mouse_mode(is_absolute
);
294 notifier_list_notify(&mouse_mode_notifiers
, NULL
);
297 current_is_absolute
= is_absolute
;
300 void qemu_add_mouse_mode_change_notifier(Notifier
*notify
)
302 notifier_list_add(&mouse_mode_notifiers
, notify
);
305 void qemu_remove_mouse_mode_change_notifier(Notifier
*notify
)
307 notifier_remove(notify
);
310 MouseInfoList
*qmp_query_mice(Error
**errp
)
312 MouseInfoList
*mice_list
= NULL
;
314 QemuInputHandlerState
*s
;
317 QTAILQ_FOREACH(s
, &handlers
, node
) {
318 if (!(s
->handler
->mask
&
319 (INPUT_EVENT_MASK_REL
| INPUT_EVENT_MASK_ABS
))) {
323 info
= g_new0(MouseInfoList
, 1);
324 info
->value
= g_new0(MouseInfo
, 1);
325 info
->value
->index
= s
->id
;
326 info
->value
->name
= g_strdup(s
->handler
->name
);
327 info
->value
->absolute
= s
->handler
->mask
& INPUT_EVENT_MASK_ABS
;
328 info
->value
->current
= current
;
331 info
->next
= mice_list
;
338 void do_mouse_set(Monitor
*mon
, const QDict
*qdict
)
340 QemuInputHandlerState
*s
;
341 int index
= qdict_get_int(qdict
, "index");
344 QTAILQ_FOREACH(s
, &handlers
, node
) {
345 if (s
->id
== index
) {
347 qemu_input_handler_activate(s
);
353 monitor_printf(mon
, "Mouse at given index not found\n");
356 qemu_input_check_mode_change();