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
);
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
;
293 is_absolute
= qemu_input_is_absolute();
295 if (is_absolute
!= current_is_absolute
) {
296 trace_input_mouse_mode(is_absolute
);
297 notifier_list_notify(&mouse_mode_notifiers
, NULL
);
300 current_is_absolute
= is_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
);
313 MouseInfoList
*qmp_query_mice(Error
**errp
)
315 MouseInfoList
*mice_list
= NULL
;
317 QemuInputHandlerState
*s
;
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
;
331 info
->value
->current
= current
;
334 info
->next
= mice_list
;
341 void do_mouse_set(Monitor
*mon
, const QDict
*qdict
)
343 QemuInputHandlerState
*s
;
344 int index
= qdict_get_int(qdict
, "index");
347 QTAILQ_FOREACH(s
, &handlers
, node
) {
348 if (s
->id
!= index
) {
351 if (!(s
->handler
->mask
& (INPUT_EVENT_MASK_REL
|
352 INPUT_EVENT_MASK_ABS
))) {
353 error_report("Input device '%s' is not a mouse", s
->handler
->name
);
357 qemu_input_handler_activate(s
);
362 error_report("Mouse at index '%d' not found", index
);
365 qemu_input_check_mode_change();