]> git.proxmox.com Git - mirror_qemu.git/blame - ui/input.c
input: mouse: add helpers functions to core
[mirror_qemu.git] / ui / input.c
CommitLineData
c8b405b6
GH
1#include "sysemu/sysemu.h"
2#include "qapi-types.h"
3#include "ui/input.h"
4
5struct QemuInputHandlerState {
6 DeviceState *dev;
7 QemuInputHandler *handler;
8 int id;
9 int events;
10 QTAILQ_ENTRY(QemuInputHandlerState) node;
11};
12static QTAILQ_HEAD(, QemuInputHandlerState) handlers =
13 QTAILQ_HEAD_INITIALIZER(handlers);
14
15QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev,
16 QemuInputHandler *handler)
17{
18 QemuInputHandlerState *s = g_new0(QemuInputHandlerState, 1);
19 static int id = 1;
20
21 s->dev = dev;
22 s->handler = handler;
23 s->id = id++;
24 QTAILQ_INSERT_TAIL(&handlers, s, node);
25 return s;
26}
27
28void qemu_input_handler_activate(QemuInputHandlerState *s)
29{
30 QTAILQ_REMOVE(&handlers, s, node);
31 QTAILQ_INSERT_HEAD(&handlers, s, node);
32}
33
34void qemu_input_handler_unregister(QemuInputHandlerState *s)
35{
36 QTAILQ_REMOVE(&handlers, s, node);
37 g_free(s);
38}
39
40static QemuInputHandlerState*
41qemu_input_find_handler(uint32_t mask)
42{
43 QemuInputHandlerState *s;
44
45 QTAILQ_FOREACH(s, &handlers, node) {
46 if (mask & s->handler->mask) {
47 return s;
48 }
49 }
50 return NULL;
51}
52
53void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
54{
55 QemuInputHandlerState *s;
56
57 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
58 return;
59 }
60
61 s = qemu_input_find_handler(1 << evt->kind);
62 s->handler->event(s->dev, src, evt);
63 s->events++;
64}
65
66void qemu_input_event_sync(void)
67{
68 QemuInputHandlerState *s;
69
70 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
71 return;
72 }
73
74 QTAILQ_FOREACH(s, &handlers, node) {
75 if (!s->events) {
76 continue;
77 }
78 if (s->handler->sync) {
79 s->handler->sync(s->dev);
80 }
81 s->events = 0;
82 }
83}
65671475
GH
84
85InputEvent *qemu_input_event_new_key(KeyValue *key, bool down)
86{
87 InputEvent *evt = g_new0(InputEvent, 1);
88 evt->key = g_new0(InputKeyEvent, 1);
89 evt->kind = INPUT_EVENT_KIND_KEY;
90 evt->key->key = key;
91 evt->key->down = down;
92 return evt;
93}
94
95void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
96{
97 InputEvent *evt;
98 evt = qemu_input_event_new_key(key, down);
99 qemu_input_event_send(src, evt);
100 qemu_input_event_sync();
101 qapi_free_InputEvent(evt);
102}
103
104void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down)
105{
106 KeyValue *key = g_new0(KeyValue, 1);
107 key->kind = KEY_VALUE_KIND_NUMBER;
108 key->number = num;
109 qemu_input_event_send_key(src, key, down);
110}
111
112void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down)
113{
114 KeyValue *key = g_new0(KeyValue, 1);
115 key->kind = KEY_VALUE_KIND_QCODE;
116 key->qcode = q;
117 qemu_input_event_send_key(src, key, down);
118}
43579403
GH
119
120InputEvent *qemu_input_event_new_btn(InputButton btn, bool down)
121{
122 InputEvent *evt = g_new0(InputEvent, 1);
123 evt->btn = g_new0(InputBtnEvent, 1);
124 evt->kind = INPUT_EVENT_KIND_BTN;
125 evt->btn->button = btn;
126 evt->btn->down = down;
127 return evt;
128}
129
130void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down)
131{
132 InputEvent *evt;
133 evt = qemu_input_event_new_btn(btn, down);
134 qemu_input_event_send(src, evt);
135 qapi_free_InputEvent(evt);
136}
137
138void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map,
139 uint32_t button_old, uint32_t button_new)
140{
141 InputButton btn;
142 uint32_t mask;
143
144 for (btn = 0; btn < INPUT_BUTTON_MAX; btn++) {
145 mask = button_map[btn];
146 if ((button_old & mask) == (button_new & mask)) {
147 continue;
148 }
149 qemu_input_queue_btn(src, btn, button_new & mask);
150 }
151}
152
153int qemu_input_scale_axis(int value, int size_in, int size_out)
154{
155 if (size_in < 2) {
156 return size_out / 2;
157 }
158 return (int64_t)value * (size_out - 1) / (size_in - 1);
159}
160
161InputEvent *qemu_input_event_new_move(InputEventKind kind,
162 InputAxis axis, int value)
163{
164 InputEvent *evt = g_new0(InputEvent, 1);
165 InputMoveEvent *move = g_new0(InputMoveEvent, 1);
166
167 evt->kind = kind;
168 evt->data = move;
169 move->axis = axis;
170 move->value = value;
171 return evt;
172}
173
174void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value)
175{
176 InputEvent *evt;
177 evt = qemu_input_event_new_move(INPUT_EVENT_KIND_REL, axis, value);
178 qemu_input_event_send(src, evt);
179 qapi_free_InputEvent(evt);
180}
181
182void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, int size)
183{
184 InputEvent *evt;
185 int scaled = qemu_input_scale_axis(value, size, INPUT_EVENT_ABS_SIZE);
186 evt = qemu_input_event_new_move(INPUT_EVENT_KIND_ABS, axis, scaled);
187 qemu_input_event_send(src, evt);
188 qapi_free_InputEvent(evt);
189}