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 trace_input_event_key_number(idx
, evt
->key
->key
->number
,
109 case KEY_VALUE_KIND_QCODE
:
110 name
= QKeyCode_lookup
[evt
->key
->key
->qcode
];
111 trace_input_event_key_qcode(idx
, name
, evt
->key
->down
);
113 case KEY_VALUE_KIND_MAX
:
118 case INPUT_EVENT_KIND_BTN
:
119 name
= InputButton_lookup
[evt
->btn
->button
];
120 trace_input_event_btn(idx
, name
, evt
->btn
->down
);
122 case INPUT_EVENT_KIND_REL
:
123 name
= InputAxis_lookup
[evt
->rel
->axis
];
124 trace_input_event_rel(idx
, name
, evt
->rel
->value
);
126 case INPUT_EVENT_KIND_ABS
:
127 name
= InputAxis_lookup
[evt
->abs
->axis
];
128 trace_input_event_abs(idx
, name
, evt
->abs
->value
);
130 case INPUT_EVENT_KIND_MAX
:
136 void qemu_input_event_send(QemuConsole
*src
, InputEvent
*evt
)
138 QemuInputHandlerState
*s
;
140 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED
)) {
144 qemu_input_event_trace(src
, evt
);
147 if (graphic_rotate
&& (evt
->kind
== INPUT_EVENT_KIND_ABS
)) {
148 qemu_input_transform_abs_rotate(evt
);
152 s
= qemu_input_find_handler(1 << evt
->kind
);
156 s
->handler
->event(s
->dev
, src
, evt
);
160 void qemu_input_event_sync(void)
162 QemuInputHandlerState
*s
;
164 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED
)) {
168 trace_input_event_sync();
170 QTAILQ_FOREACH(s
, &handlers
, node
) {
174 if (s
->handler
->sync
) {
175 s
->handler
->sync(s
->dev
);
181 InputEvent
*qemu_input_event_new_key(KeyValue
*key
, bool down
)
183 InputEvent
*evt
= g_new0(InputEvent
, 1);
184 evt
->key
= g_new0(InputKeyEvent
, 1);
185 evt
->kind
= INPUT_EVENT_KIND_KEY
;
187 evt
->key
->down
= down
;
191 void qemu_input_event_send_key(QemuConsole
*src
, KeyValue
*key
, bool down
)
194 evt
= qemu_input_event_new_key(key
, down
);
195 qemu_input_event_send(src
, evt
);
196 qemu_input_event_sync();
197 qapi_free_InputEvent(evt
);
200 void qemu_input_event_send_key_number(QemuConsole
*src
, int num
, bool down
)
202 KeyValue
*key
= g_new0(KeyValue
, 1);
203 key
->kind
= KEY_VALUE_KIND_NUMBER
;
205 qemu_input_event_send_key(src
, key
, down
);
208 void qemu_input_event_send_key_qcode(QemuConsole
*src
, QKeyCode q
, bool down
)
210 KeyValue
*key
= g_new0(KeyValue
, 1);
211 key
->kind
= KEY_VALUE_KIND_QCODE
;
213 qemu_input_event_send_key(src
, key
, down
);
216 InputEvent
*qemu_input_event_new_btn(InputButton btn
, bool down
)
218 InputEvent
*evt
= g_new0(InputEvent
, 1);
219 evt
->btn
= g_new0(InputBtnEvent
, 1);
220 evt
->kind
= INPUT_EVENT_KIND_BTN
;
221 evt
->btn
->button
= btn
;
222 evt
->btn
->down
= down
;
226 void qemu_input_queue_btn(QemuConsole
*src
, InputButton btn
, bool down
)
229 evt
= qemu_input_event_new_btn(btn
, down
);
230 qemu_input_event_send(src
, evt
);
231 qapi_free_InputEvent(evt
);
234 void qemu_input_update_buttons(QemuConsole
*src
, uint32_t *button_map
,
235 uint32_t button_old
, uint32_t button_new
)
240 for (btn
= 0; btn
< INPUT_BUTTON_MAX
; btn
++) {
241 mask
= button_map
[btn
];
242 if ((button_old
& mask
) == (button_new
& mask
)) {
245 qemu_input_queue_btn(src
, btn
, button_new
& mask
);
249 bool qemu_input_is_absolute(void)
251 QemuInputHandlerState
*s
;
253 s
= qemu_input_find_handler(INPUT_EVENT_MASK_REL
| INPUT_EVENT_MASK_ABS
);
254 return (s
!= NULL
) && (s
->handler
->mask
& INPUT_EVENT_MASK_ABS
);
257 int qemu_input_scale_axis(int value
, int size_in
, int size_out
)
262 return (int64_t)value
* (size_out
- 1) / (size_in
- 1);
265 InputEvent
*qemu_input_event_new_move(InputEventKind kind
,
266 InputAxis axis
, int value
)
268 InputEvent
*evt
= g_new0(InputEvent
, 1);
269 InputMoveEvent
*move
= g_new0(InputMoveEvent
, 1);
278 void qemu_input_queue_rel(QemuConsole
*src
, InputAxis axis
, int value
)
281 evt
= qemu_input_event_new_move(INPUT_EVENT_KIND_REL
, axis
, value
);
282 qemu_input_event_send(src
, evt
);
283 qapi_free_InputEvent(evt
);
286 void qemu_input_queue_abs(QemuConsole
*src
, InputAxis axis
, int value
, int size
)
289 int scaled
= qemu_input_scale_axis(value
, size
, INPUT_EVENT_ABS_SIZE
);
290 evt
= qemu_input_event_new_move(INPUT_EVENT_KIND_ABS
, axis
, scaled
);
291 qemu_input_event_send(src
, evt
);
292 qapi_free_InputEvent(evt
);
295 void qemu_input_check_mode_change(void)
297 static int current_is_absolute
;
300 is_absolute
= qemu_input_is_absolute();
302 if (is_absolute
!= current_is_absolute
) {
303 trace_input_mouse_mode(is_absolute
);
304 notifier_list_notify(&mouse_mode_notifiers
, NULL
);
307 current_is_absolute
= is_absolute
;
310 void qemu_add_mouse_mode_change_notifier(Notifier
*notify
)
312 notifier_list_add(&mouse_mode_notifiers
, notify
);
315 void qemu_remove_mouse_mode_change_notifier(Notifier
*notify
)
317 notifier_remove(notify
);
320 MouseInfoList
*qmp_query_mice(Error
**errp
)
322 MouseInfoList
*mice_list
= NULL
;
324 QemuInputHandlerState
*s
;
327 QTAILQ_FOREACH(s
, &handlers
, node
) {
328 if (!(s
->handler
->mask
&
329 (INPUT_EVENT_MASK_REL
| INPUT_EVENT_MASK_ABS
))) {
333 info
= g_new0(MouseInfoList
, 1);
334 info
->value
= g_new0(MouseInfo
, 1);
335 info
->value
->index
= s
->id
;
336 info
->value
->name
= g_strdup(s
->handler
->name
);
337 info
->value
->absolute
= s
->handler
->mask
& INPUT_EVENT_MASK_ABS
;
338 info
->value
->current
= current
;
341 info
->next
= mice_list
;
348 void do_mouse_set(Monitor
*mon
, const QDict
*qdict
)
350 QemuInputHandlerState
*s
;
351 int index
= qdict_get_int(qdict
, "index");
354 QTAILQ_FOREACH(s
, &handlers
, node
) {
355 if (s
->id
!= index
) {
358 if (!(s
->handler
->mask
& (INPUT_EVENT_MASK_REL
|
359 INPUT_EVENT_MASK_ABS
))) {
360 error_report("Input device '%s' is not a mouse", s
->handler
->name
);
364 qemu_input_handler_activate(s
);
369 error_report("Mouse at index '%d' not found", index
);
372 qemu_input_check_mode_change();