]>
Commit | Line | Data |
---|---|---|
c8b405b6 GH |
1 | #include "sysemu/sysemu.h" |
2 | #include "qapi-types.h" | |
3 | #include "ui/input.h" | |
4 | ||
5 | struct QemuInputHandlerState { | |
6 | DeviceState *dev; | |
7 | QemuInputHandler *handler; | |
8 | int id; | |
9 | int events; | |
10 | QTAILQ_ENTRY(QemuInputHandlerState) node; | |
11 | }; | |
12 | static QTAILQ_HEAD(, QemuInputHandlerState) handlers = | |
13 | QTAILQ_HEAD_INITIALIZER(handlers); | |
14 | ||
15 | QemuInputHandlerState *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 | ||
28 | void qemu_input_handler_activate(QemuInputHandlerState *s) | |
29 | { | |
30 | QTAILQ_REMOVE(&handlers, s, node); | |
31 | QTAILQ_INSERT_HEAD(&handlers, s, node); | |
32 | } | |
33 | ||
34 | void qemu_input_handler_unregister(QemuInputHandlerState *s) | |
35 | { | |
36 | QTAILQ_REMOVE(&handlers, s, node); | |
37 | g_free(s); | |
38 | } | |
39 | ||
40 | static QemuInputHandlerState* | |
41 | qemu_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 | ||
53 | void 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 | ||
66 | void 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 | |
85 | InputEvent *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 | ||
95 | void 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 | ||
104 | void 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 | ||
112 | void 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 | |
120 | InputEvent *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 | ||
130 | void 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 | ||
138 | void 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 | ||
153 | int 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 | ||
161 | InputEvent *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 | ||
174 | void 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 | ||
182 | void 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 | } |