root / ui / input.c @ 834574ea
History | View | Annotate | Download (13.3 kB)
1 | 8f0056b7 | Paolo Bonzini | /*
|
---|---|---|---|
2 | 8f0056b7 | Paolo Bonzini | * QEMU System Emulator
|
3 | 8f0056b7 | Paolo Bonzini | *
|
4 | 8f0056b7 | Paolo Bonzini | * Copyright (c) 2003-2008 Fabrice Bellard
|
5 | 8f0056b7 | Paolo Bonzini | *
|
6 | 8f0056b7 | Paolo Bonzini | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 | 8f0056b7 | Paolo Bonzini | * of this software and associated documentation files (the "Software"), to deal
|
8 | 8f0056b7 | Paolo Bonzini | * in the Software without restriction, including without limitation the rights
|
9 | 8f0056b7 | Paolo Bonzini | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 | 8f0056b7 | Paolo Bonzini | * copies of the Software, and to permit persons to whom the Software is
|
11 | 8f0056b7 | Paolo Bonzini | * furnished to do so, subject to the following conditions:
|
12 | 8f0056b7 | Paolo Bonzini | *
|
13 | 8f0056b7 | Paolo Bonzini | * The above copyright notice and this permission notice shall be included in
|
14 | 8f0056b7 | Paolo Bonzini | * all copies or substantial portions of the Software.
|
15 | 8f0056b7 | Paolo Bonzini | *
|
16 | 8f0056b7 | Paolo Bonzini | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 | 8f0056b7 | Paolo Bonzini | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 | 8f0056b7 | Paolo Bonzini | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
19 | 8f0056b7 | Paolo Bonzini | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 | 8f0056b7 | Paolo Bonzini | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 | 8f0056b7 | Paolo Bonzini | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 | 8f0056b7 | Paolo Bonzini | * THE SOFTWARE.
|
23 | 8f0056b7 | Paolo Bonzini | */
|
24 | 8f0056b7 | Paolo Bonzini | |
25 | 9c17d615 | Paolo Bonzini | #include "sysemu/sysemu.h" |
26 | 83c9089e | Paolo Bonzini | #include "monitor/monitor.h" |
27 | 28ecbaee | Paolo Bonzini | #include "ui/console.h" |
28 | 7b1b5d19 | Paolo Bonzini | #include "qapi/error.h" |
29 | e235cec3 | Luiz Capitulino | #include "qmp-commands.h" |
30 | e4c8f004 | Amos Kong | #include "qapi-types.h" |
31 | 8f0056b7 | Paolo Bonzini | |
32 | 8f0056b7 | Paolo Bonzini | static QEMUPutKBDEvent *qemu_put_kbd_event;
|
33 | 8f0056b7 | Paolo Bonzini | static void *qemu_put_kbd_event_opaque; |
34 | 03a23a85 | Gerd Hoffmann | static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers);
|
35 | 6fef28ee | Anthony Liguori | static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers =
|
36 | 6fef28ee | Anthony Liguori | QTAILQ_HEAD_INITIALIZER(mouse_handlers); |
37 | 7e581fb3 | Anthony Liguori | static NotifierList mouse_mode_notifiers =
|
38 | 7e581fb3 | Anthony Liguori | NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers); |
39 | 8f0056b7 | Paolo Bonzini | |
40 | e4c8f004 | Amos Kong | static const int key_defs[] = { |
41 | 1048c88f | Amos Kong | [Q_KEY_CODE_SHIFT] = 0x2a,
|
42 | 1048c88f | Amos Kong | [Q_KEY_CODE_SHIFT_R] = 0x36,
|
43 | 1048c88f | Amos Kong | |
44 | 1048c88f | Amos Kong | [Q_KEY_CODE_ALT] = 0x38,
|
45 | 1048c88f | Amos Kong | [Q_KEY_CODE_ALT_R] = 0xb8,
|
46 | 1048c88f | Amos Kong | [Q_KEY_CODE_ALTGR] = 0x64,
|
47 | 1048c88f | Amos Kong | [Q_KEY_CODE_ALTGR_R] = 0xe4,
|
48 | 1048c88f | Amos Kong | [Q_KEY_CODE_CTRL] = 0x1d,
|
49 | 1048c88f | Amos Kong | [Q_KEY_CODE_CTRL_R] = 0x9d,
|
50 | 1048c88f | Amos Kong | |
51 | 1048c88f | Amos Kong | [Q_KEY_CODE_MENU] = 0xdd,
|
52 | 1048c88f | Amos Kong | |
53 | 1048c88f | Amos Kong | [Q_KEY_CODE_ESC] = 0x01,
|
54 | 1048c88f | Amos Kong | |
55 | 1048c88f | Amos Kong | [Q_KEY_CODE_1] = 0x02,
|
56 | 1048c88f | Amos Kong | [Q_KEY_CODE_2] = 0x03,
|
57 | 1048c88f | Amos Kong | [Q_KEY_CODE_3] = 0x04,
|
58 | 1048c88f | Amos Kong | [Q_KEY_CODE_4] = 0x05,
|
59 | 1048c88f | Amos Kong | [Q_KEY_CODE_5] = 0x06,
|
60 | 1048c88f | Amos Kong | [Q_KEY_CODE_6] = 0x07,
|
61 | 1048c88f | Amos Kong | [Q_KEY_CODE_7] = 0x08,
|
62 | 1048c88f | Amos Kong | [Q_KEY_CODE_8] = 0x09,
|
63 | 1048c88f | Amos Kong | [Q_KEY_CODE_9] = 0x0a,
|
64 | 1048c88f | Amos Kong | [Q_KEY_CODE_0] = 0x0b,
|
65 | 1048c88f | Amos Kong | [Q_KEY_CODE_MINUS] = 0x0c,
|
66 | 1048c88f | Amos Kong | [Q_KEY_CODE_EQUAL] = 0x0d,
|
67 | 1048c88f | Amos Kong | [Q_KEY_CODE_BACKSPACE] = 0x0e,
|
68 | 1048c88f | Amos Kong | |
69 | 1048c88f | Amos Kong | [Q_KEY_CODE_TAB] = 0x0f,
|
70 | 1048c88f | Amos Kong | [Q_KEY_CODE_Q] = 0x10,
|
71 | 1048c88f | Amos Kong | [Q_KEY_CODE_W] = 0x11,
|
72 | 1048c88f | Amos Kong | [Q_KEY_CODE_E] = 0x12,
|
73 | 1048c88f | Amos Kong | [Q_KEY_CODE_R] = 0x13,
|
74 | 1048c88f | Amos Kong | [Q_KEY_CODE_T] = 0x14,
|
75 | 1048c88f | Amos Kong | [Q_KEY_CODE_Y] = 0x15,
|
76 | 1048c88f | Amos Kong | [Q_KEY_CODE_U] = 0x16,
|
77 | 1048c88f | Amos Kong | [Q_KEY_CODE_I] = 0x17,
|
78 | 1048c88f | Amos Kong | [Q_KEY_CODE_O] = 0x18,
|
79 | 1048c88f | Amos Kong | [Q_KEY_CODE_P] = 0x19,
|
80 | 1048c88f | Amos Kong | [Q_KEY_CODE_BRACKET_LEFT] = 0x1a,
|
81 | 1048c88f | Amos Kong | [Q_KEY_CODE_BRACKET_RIGHT] = 0x1b,
|
82 | 1048c88f | Amos Kong | [Q_KEY_CODE_RET] = 0x1c,
|
83 | 1048c88f | Amos Kong | |
84 | 1048c88f | Amos Kong | [Q_KEY_CODE_A] = 0x1e,
|
85 | 1048c88f | Amos Kong | [Q_KEY_CODE_S] = 0x1f,
|
86 | 1048c88f | Amos Kong | [Q_KEY_CODE_D] = 0x20,
|
87 | 1048c88f | Amos Kong | [Q_KEY_CODE_F] = 0x21,
|
88 | 1048c88f | Amos Kong | [Q_KEY_CODE_G] = 0x22,
|
89 | 1048c88f | Amos Kong | [Q_KEY_CODE_H] = 0x23,
|
90 | 1048c88f | Amos Kong | [Q_KEY_CODE_J] = 0x24,
|
91 | 1048c88f | Amos Kong | [Q_KEY_CODE_K] = 0x25,
|
92 | 1048c88f | Amos Kong | [Q_KEY_CODE_L] = 0x26,
|
93 | 1048c88f | Amos Kong | [Q_KEY_CODE_SEMICOLON] = 0x27,
|
94 | 1048c88f | Amos Kong | [Q_KEY_CODE_APOSTROPHE] = 0x28,
|
95 | 1048c88f | Amos Kong | [Q_KEY_CODE_GRAVE_ACCENT] = 0x29,
|
96 | 1048c88f | Amos Kong | |
97 | 1048c88f | Amos Kong | [Q_KEY_CODE_BACKSLASH] = 0x2b,
|
98 | 1048c88f | Amos Kong | [Q_KEY_CODE_Z] = 0x2c,
|
99 | 1048c88f | Amos Kong | [Q_KEY_CODE_X] = 0x2d,
|
100 | 1048c88f | Amos Kong | [Q_KEY_CODE_C] = 0x2e,
|
101 | 1048c88f | Amos Kong | [Q_KEY_CODE_V] = 0x2f,
|
102 | 1048c88f | Amos Kong | [Q_KEY_CODE_B] = 0x30,
|
103 | 1048c88f | Amos Kong | [Q_KEY_CODE_N] = 0x31,
|
104 | 1048c88f | Amos Kong | [Q_KEY_CODE_M] = 0x32,
|
105 | 1048c88f | Amos Kong | [Q_KEY_CODE_COMMA] = 0x33,
|
106 | 1048c88f | Amos Kong | [Q_KEY_CODE_DOT] = 0x34,
|
107 | 1048c88f | Amos Kong | [Q_KEY_CODE_SLASH] = 0x35,
|
108 | 1048c88f | Amos Kong | |
109 | 1048c88f | Amos Kong | [Q_KEY_CODE_ASTERISK] = 0x37,
|
110 | 1048c88f | Amos Kong | |
111 | 1048c88f | Amos Kong | [Q_KEY_CODE_SPC] = 0x39,
|
112 | 1048c88f | Amos Kong | [Q_KEY_CODE_CAPS_LOCK] = 0x3a,
|
113 | 1048c88f | Amos Kong | [Q_KEY_CODE_F1] = 0x3b,
|
114 | 1048c88f | Amos Kong | [Q_KEY_CODE_F2] = 0x3c,
|
115 | 1048c88f | Amos Kong | [Q_KEY_CODE_F3] = 0x3d,
|
116 | 1048c88f | Amos Kong | [Q_KEY_CODE_F4] = 0x3e,
|
117 | 1048c88f | Amos Kong | [Q_KEY_CODE_F5] = 0x3f,
|
118 | 1048c88f | Amos Kong | [Q_KEY_CODE_F6] = 0x40,
|
119 | 1048c88f | Amos Kong | [Q_KEY_CODE_F7] = 0x41,
|
120 | 1048c88f | Amos Kong | [Q_KEY_CODE_F8] = 0x42,
|
121 | 1048c88f | Amos Kong | [Q_KEY_CODE_F9] = 0x43,
|
122 | 1048c88f | Amos Kong | [Q_KEY_CODE_F10] = 0x44,
|
123 | 1048c88f | Amos Kong | [Q_KEY_CODE_NUM_LOCK] = 0x45,
|
124 | 1048c88f | Amos Kong | [Q_KEY_CODE_SCROLL_LOCK] = 0x46,
|
125 | 1048c88f | Amos Kong | |
126 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_DIVIDE] = 0xb5,
|
127 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_MULTIPLY] = 0x37,
|
128 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_SUBTRACT] = 0x4a,
|
129 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_ADD] = 0x4e,
|
130 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_ENTER] = 0x9c,
|
131 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_DECIMAL] = 0x53,
|
132 | 1048c88f | Amos Kong | [Q_KEY_CODE_SYSRQ] = 0x54,
|
133 | 1048c88f | Amos Kong | |
134 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_0] = 0x52,
|
135 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_1] = 0x4f,
|
136 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_2] = 0x50,
|
137 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_3] = 0x51,
|
138 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_4] = 0x4b,
|
139 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_5] = 0x4c,
|
140 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_6] = 0x4d,
|
141 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_7] = 0x47,
|
142 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_8] = 0x48,
|
143 | 1048c88f | Amos Kong | [Q_KEY_CODE_KP_9] = 0x49,
|
144 | 1048c88f | Amos Kong | |
145 | 1048c88f | Amos Kong | [Q_KEY_CODE_LESS] = 0x56,
|
146 | 1048c88f | Amos Kong | |
147 | 1048c88f | Amos Kong | [Q_KEY_CODE_F11] = 0x57,
|
148 | 1048c88f | Amos Kong | [Q_KEY_CODE_F12] = 0x58,
|
149 | 1048c88f | Amos Kong | |
150 | 1048c88f | Amos Kong | [Q_KEY_CODE_PRINT] = 0xb7,
|
151 | 1048c88f | Amos Kong | |
152 | 1048c88f | Amos Kong | [Q_KEY_CODE_HOME] = 0xc7,
|
153 | 1048c88f | Amos Kong | [Q_KEY_CODE_PGUP] = 0xc9,
|
154 | 1048c88f | Amos Kong | [Q_KEY_CODE_PGDN] = 0xd1,
|
155 | 1048c88f | Amos Kong | [Q_KEY_CODE_END] = 0xcf,
|
156 | 1048c88f | Amos Kong | |
157 | 1048c88f | Amos Kong | [Q_KEY_CODE_LEFT] = 0xcb,
|
158 | 1048c88f | Amos Kong | [Q_KEY_CODE_UP] = 0xc8,
|
159 | 1048c88f | Amos Kong | [Q_KEY_CODE_DOWN] = 0xd0,
|
160 | 1048c88f | Amos Kong | [Q_KEY_CODE_RIGHT] = 0xcd,
|
161 | 1048c88f | Amos Kong | |
162 | 1048c88f | Amos Kong | [Q_KEY_CODE_INSERT] = 0xd2,
|
163 | 1048c88f | Amos Kong | [Q_KEY_CODE_DELETE] = 0xd3,
|
164 | 1048c88f | Amos Kong | #ifdef NEED_CPU_H
|
165 | 1048c88f | Amos Kong | #if defined(TARGET_SPARC) && !defined(TARGET_SPARC64)
|
166 | 1048c88f | Amos Kong | [Q_KEY_CODE_STOP] = 0xf0,
|
167 | 1048c88f | Amos Kong | [Q_KEY_CODE_AGAIN] = 0xf1,
|
168 | 1048c88f | Amos Kong | [Q_KEY_CODE_PROPS] = 0xf2,
|
169 | 1048c88f | Amos Kong | [Q_KEY_CODE_UNDO] = 0xf3,
|
170 | 1048c88f | Amos Kong | [Q_KEY_CODE_FRONT] = 0xf4,
|
171 | 1048c88f | Amos Kong | [Q_KEY_CODE_COPY] = 0xf5,
|
172 | 1048c88f | Amos Kong | [Q_KEY_CODE_OPEN] = 0xf6,
|
173 | 1048c88f | Amos Kong | [Q_KEY_CODE_PASTE] = 0xf7,
|
174 | 1048c88f | Amos Kong | [Q_KEY_CODE_FIND] = 0xf8,
|
175 | 1048c88f | Amos Kong | [Q_KEY_CODE_CUT] = 0xf9,
|
176 | 1048c88f | Amos Kong | [Q_KEY_CODE_LF] = 0xfa,
|
177 | 1048c88f | Amos Kong | [Q_KEY_CODE_HELP] = 0xfb,
|
178 | 1048c88f | Amos Kong | [Q_KEY_CODE_META_L] = 0xfc,
|
179 | 1048c88f | Amos Kong | [Q_KEY_CODE_META_R] = 0xfd,
|
180 | 1048c88f | Amos Kong | [Q_KEY_CODE_COMPOSE] = 0xfe,
|
181 | 1048c88f | Amos Kong | #endif
|
182 | 1048c88f | Amos Kong | #endif
|
183 | 1048c88f | Amos Kong | [Q_KEY_CODE_MAX] = 0,
|
184 | 1048c88f | Amos Kong | }; |
185 | 1048c88f | Amos Kong | |
186 | 1048c88f | Amos Kong | int index_from_key(const char *key) |
187 | 1048c88f | Amos Kong | { |
188 | 9d537c90 | Luiz Capitulino | int i;
|
189 | 1048c88f | Amos Kong | |
190 | 1048c88f | Amos Kong | for (i = 0; QKeyCode_lookup[i] != NULL; i++) { |
191 | 1048c88f | Amos Kong | if (!strcmp(key, QKeyCode_lookup[i])) {
|
192 | 1048c88f | Amos Kong | break;
|
193 | 1048c88f | Amos Kong | } |
194 | 1048c88f | Amos Kong | } |
195 | 1048c88f | Amos Kong | |
196 | 1048c88f | Amos Kong | /* Return Q_KEY_CODE_MAX if the key is invalid */
|
197 | 1048c88f | Amos Kong | return i;
|
198 | 1048c88f | Amos Kong | } |
199 | 1048c88f | Amos Kong | |
200 | 1048c88f | Amos Kong | int index_from_keycode(int code) |
201 | 1048c88f | Amos Kong | { |
202 | 1048c88f | Amos Kong | int i;
|
203 | 1048c88f | Amos Kong | |
204 | 1048c88f | Amos Kong | for (i = 0; i < Q_KEY_CODE_MAX; i++) { |
205 | 1048c88f | Amos Kong | if (key_defs[i] == code) {
|
206 | 1048c88f | Amos Kong | break;
|
207 | 1048c88f | Amos Kong | } |
208 | 1048c88f | Amos Kong | } |
209 | 1048c88f | Amos Kong | |
210 | 1048c88f | Amos Kong | /* Return Q_KEY_CODE_MAX if the code is invalid */
|
211 | 1048c88f | Amos Kong | return i;
|
212 | 1048c88f | Amos Kong | } |
213 | 1048c88f | Amos Kong | |
214 | 05a3543d | Luiz Capitulino | static int *keycodes; |
215 | 05a3543d | Luiz Capitulino | static int keycodes_size; |
216 | e4c8f004 | Amos Kong | static QEMUTimer *key_timer;
|
217 | e4c8f004 | Amos Kong | |
218 | 9f328977 | Luiz Capitulino | static int keycode_from_keyvalue(const KeyValue *value) |
219 | 9f328977 | Luiz Capitulino | { |
220 | 9f328977 | Luiz Capitulino | if (value->kind == KEY_VALUE_KIND_QCODE) {
|
221 | 9f328977 | Luiz Capitulino | return key_defs[value->qcode];
|
222 | 9f328977 | Luiz Capitulino | } else {
|
223 | 9f328977 | Luiz Capitulino | assert(value->kind == KEY_VALUE_KIND_NUMBER); |
224 | 9f328977 | Luiz Capitulino | return value->number;
|
225 | 9f328977 | Luiz Capitulino | } |
226 | 9f328977 | Luiz Capitulino | } |
227 | 9f328977 | Luiz Capitulino | |
228 | 9f328977 | Luiz Capitulino | static void free_keycodes(void) |
229 | 9f328977 | Luiz Capitulino | { |
230 | 9f328977 | Luiz Capitulino | g_free(keycodes); |
231 | 9f328977 | Luiz Capitulino | keycodes = NULL;
|
232 | 9f328977 | Luiz Capitulino | keycodes_size = 0;
|
233 | 9f328977 | Luiz Capitulino | } |
234 | 9f328977 | Luiz Capitulino | |
235 | e4c8f004 | Amos Kong | static void release_keys(void *opaque) |
236 | e4c8f004 | Amos Kong | { |
237 | 05a3543d | Luiz Capitulino | int i;
|
238 | e4c8f004 | Amos Kong | |
239 | 05a3543d | Luiz Capitulino | for (i = 0; i < keycodes_size; i++) { |
240 | 05a3543d | Luiz Capitulino | if (keycodes[i] & 0x80) { |
241 | e4c8f004 | Amos Kong | kbd_put_keycode(0xe0);
|
242 | e4c8f004 | Amos Kong | } |
243 | 05a3543d | Luiz Capitulino | kbd_put_keycode(keycodes[i]| 0x80);
|
244 | e4c8f004 | Amos Kong | } |
245 | 05a3543d | Luiz Capitulino | |
246 | 9f328977 | Luiz Capitulino | free_keycodes(); |
247 | e4c8f004 | Amos Kong | } |
248 | e4c8f004 | Amos Kong | |
249 | 9f328977 | Luiz Capitulino | void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time, |
250 | e4c8f004 | Amos Kong | Error **errp) |
251 | e4c8f004 | Amos Kong | { |
252 | e4c8f004 | Amos Kong | int keycode;
|
253 | 9f328977 | Luiz Capitulino | KeyValueList *p; |
254 | e4c8f004 | Amos Kong | |
255 | e4c8f004 | Amos Kong | if (!key_timer) {
|
256 | e4c8f004 | Amos Kong | key_timer = qemu_new_timer_ns(vm_clock, release_keys, NULL);
|
257 | e4c8f004 | Amos Kong | } |
258 | e4c8f004 | Amos Kong | |
259 | e4c8f004 | Amos Kong | if (keycodes != NULL) { |
260 | e4c8f004 | Amos Kong | qemu_del_timer(key_timer); |
261 | e4c8f004 | Amos Kong | release_keys(NULL);
|
262 | e4c8f004 | Amos Kong | } |
263 | 05a3543d | Luiz Capitulino | |
264 | e4c8f004 | Amos Kong | if (!has_hold_time) {
|
265 | e4c8f004 | Amos Kong | hold_time = 100;
|
266 | e4c8f004 | Amos Kong | } |
267 | e4c8f004 | Amos Kong | |
268 | e4c8f004 | Amos Kong | for (p = keys; p != NULL; p = p->next) { |
269 | e4c8f004 | Amos Kong | /* key down events */
|
270 | 9f328977 | Luiz Capitulino | keycode = keycode_from_keyvalue(p->value); |
271 | 9f328977 | Luiz Capitulino | if (keycode < 0x01 || keycode > 0xff) { |
272 | 312fd5f2 | Markus Armbruster | error_setg(errp, "invalid hex keycode 0x%x", keycode);
|
273 | 9f328977 | Luiz Capitulino | free_keycodes(); |
274 | 9f328977 | Luiz Capitulino | return;
|
275 | 9f328977 | Luiz Capitulino | } |
276 | 9f328977 | Luiz Capitulino | |
277 | e4c8f004 | Amos Kong | if (keycode & 0x80) { |
278 | e4c8f004 | Amos Kong | kbd_put_keycode(0xe0);
|
279 | e4c8f004 | Amos Kong | } |
280 | e4c8f004 | Amos Kong | kbd_put_keycode(keycode & 0x7f);
|
281 | 05a3543d | Luiz Capitulino | |
282 | 05a3543d | Luiz Capitulino | keycodes = g_realloc(keycodes, sizeof(int) * (keycodes_size + 1)); |
283 | 05a3543d | Luiz Capitulino | keycodes[keycodes_size++] = keycode; |
284 | e4c8f004 | Amos Kong | } |
285 | e4c8f004 | Amos Kong | |
286 | e4c8f004 | Amos Kong | /* delayed key up events */
|
287 | e4c8f004 | Amos Kong | qemu_mod_timer(key_timer, qemu_get_clock_ns(vm_clock) + |
288 | e4c8f004 | Amos Kong | muldiv64(get_ticks_per_sec(), hold_time, 1000));
|
289 | e4c8f004 | Amos Kong | } |
290 | e4c8f004 | Amos Kong | |
291 | 8f0056b7 | Paolo Bonzini | void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) |
292 | 8f0056b7 | Paolo Bonzini | { |
293 | 8f0056b7 | Paolo Bonzini | qemu_put_kbd_event_opaque = opaque; |
294 | 8f0056b7 | Paolo Bonzini | qemu_put_kbd_event = func; |
295 | 8f0056b7 | Paolo Bonzini | } |
296 | 8f0056b7 | Paolo Bonzini | |
297 | 46aaebff | Jes Sorensen | void qemu_remove_kbd_event_handler(void) |
298 | 46aaebff | Jes Sorensen | { |
299 | 46aaebff | Jes Sorensen | qemu_put_kbd_event_opaque = NULL;
|
300 | 46aaebff | Jes Sorensen | qemu_put_kbd_event = NULL;
|
301 | 46aaebff | Jes Sorensen | } |
302 | 46aaebff | Jes Sorensen | |
303 | 7e581fb3 | Anthony Liguori | static void check_mode_change(void) |
304 | 7e581fb3 | Anthony Liguori | { |
305 | 7e581fb3 | Anthony Liguori | static int current_is_absolute, current_has_absolute; |
306 | 7e581fb3 | Anthony Liguori | int is_absolute;
|
307 | 7e581fb3 | Anthony Liguori | int has_absolute;
|
308 | 7e581fb3 | Anthony Liguori | |
309 | 7e581fb3 | Anthony Liguori | is_absolute = kbd_mouse_is_absolute(); |
310 | 7e581fb3 | Anthony Liguori | has_absolute = kbd_mouse_has_absolute(); |
311 | 7e581fb3 | Anthony Liguori | |
312 | 7e581fb3 | Anthony Liguori | if (is_absolute != current_is_absolute ||
|
313 | 7e581fb3 | Anthony Liguori | has_absolute != current_has_absolute) { |
314 | 9e8dd451 | Jan Kiszka | notifier_list_notify(&mouse_mode_notifiers, NULL);
|
315 | 7e581fb3 | Anthony Liguori | } |
316 | 7e581fb3 | Anthony Liguori | |
317 | 7e581fb3 | Anthony Liguori | current_is_absolute = is_absolute; |
318 | 7e581fb3 | Anthony Liguori | current_has_absolute = has_absolute; |
319 | 7e581fb3 | Anthony Liguori | } |
320 | 7e581fb3 | Anthony Liguori | |
321 | 8f0056b7 | Paolo Bonzini | QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, |
322 | 8f0056b7 | Paolo Bonzini | void *opaque, int absolute, |
323 | 8f0056b7 | Paolo Bonzini | const char *name) |
324 | 8f0056b7 | Paolo Bonzini | { |
325 | 6fef28ee | Anthony Liguori | QEMUPutMouseEntry *s; |
326 | 6fef28ee | Anthony Liguori | static int mouse_index = 0; |
327 | 8f0056b7 | Paolo Bonzini | |
328 | 7267c094 | Anthony Liguori | s = g_malloc0(sizeof(QEMUPutMouseEntry));
|
329 | 8f0056b7 | Paolo Bonzini | |
330 | 8f0056b7 | Paolo Bonzini | s->qemu_put_mouse_event = func; |
331 | 8f0056b7 | Paolo Bonzini | s->qemu_put_mouse_event_opaque = opaque; |
332 | 8f0056b7 | Paolo Bonzini | s->qemu_put_mouse_event_absolute = absolute; |
333 | 7267c094 | Anthony Liguori | s->qemu_put_mouse_event_name = g_strdup(name); |
334 | 6fef28ee | Anthony Liguori | s->index = mouse_index++; |
335 | 8f0056b7 | Paolo Bonzini | |
336 | 6fef28ee | Anthony Liguori | QTAILQ_INSERT_TAIL(&mouse_handlers, s, node); |
337 | 8f0056b7 | Paolo Bonzini | |
338 | 7e581fb3 | Anthony Liguori | check_mode_change(); |
339 | 7e581fb3 | Anthony Liguori | |
340 | 8f0056b7 | Paolo Bonzini | return s;
|
341 | 8f0056b7 | Paolo Bonzini | } |
342 | 8f0056b7 | Paolo Bonzini | |
343 | 6fef28ee | Anthony Liguori | void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry)
|
344 | 8f0056b7 | Paolo Bonzini | { |
345 | 6fef28ee | Anthony Liguori | QTAILQ_REMOVE(&mouse_handlers, entry, node); |
346 | 6fef28ee | Anthony Liguori | QTAILQ_INSERT_HEAD(&mouse_handlers, entry, node); |
347 | 8f0056b7 | Paolo Bonzini | |
348 | 6fef28ee | Anthony Liguori | check_mode_change(); |
349 | 6fef28ee | Anthony Liguori | } |
350 | 8f0056b7 | Paolo Bonzini | |
351 | 6fef28ee | Anthony Liguori | void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
|
352 | 6fef28ee | Anthony Liguori | { |
353 | 6fef28ee | Anthony Liguori | QTAILQ_REMOVE(&mouse_handlers, entry, node); |
354 | 8f0056b7 | Paolo Bonzini | |
355 | 7267c094 | Anthony Liguori | g_free(entry->qemu_put_mouse_event_name); |
356 | 7267c094 | Anthony Liguori | g_free(entry); |
357 | 7e581fb3 | Anthony Liguori | |
358 | 7e581fb3 | Anthony Liguori | check_mode_change(); |
359 | 8f0056b7 | Paolo Bonzini | } |
360 | 8f0056b7 | Paolo Bonzini | |
361 | 03a23a85 | Gerd Hoffmann | QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func, |
362 | 03a23a85 | Gerd Hoffmann | void *opaque)
|
363 | 03a23a85 | Gerd Hoffmann | { |
364 | 03a23a85 | Gerd Hoffmann | QEMUPutLEDEntry *s; |
365 | 03a23a85 | Gerd Hoffmann | |
366 | 7267c094 | Anthony Liguori | s = g_malloc0(sizeof(QEMUPutLEDEntry));
|
367 | 03a23a85 | Gerd Hoffmann | |
368 | 03a23a85 | Gerd Hoffmann | s->put_led = func; |
369 | 03a23a85 | Gerd Hoffmann | s->opaque = opaque; |
370 | 03a23a85 | Gerd Hoffmann | QTAILQ_INSERT_TAIL(&led_handlers, s, next); |
371 | 03a23a85 | Gerd Hoffmann | return s;
|
372 | 03a23a85 | Gerd Hoffmann | } |
373 | 03a23a85 | Gerd Hoffmann | |
374 | 03a23a85 | Gerd Hoffmann | void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
|
375 | 03a23a85 | Gerd Hoffmann | { |
376 | 03a23a85 | Gerd Hoffmann | if (entry == NULL) |
377 | 03a23a85 | Gerd Hoffmann | return;
|
378 | 03a23a85 | Gerd Hoffmann | QTAILQ_REMOVE(&led_handlers, entry, next); |
379 | 7267c094 | Anthony Liguori | g_free(entry); |
380 | 03a23a85 | Gerd Hoffmann | } |
381 | 03a23a85 | Gerd Hoffmann | |
382 | 8f0056b7 | Paolo Bonzini | void kbd_put_keycode(int keycode) |
383 | 8f0056b7 | Paolo Bonzini | { |
384 | ad02b96a | Luiz Capitulino | if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
|
385 | 99c7f878 | Gerd Hoffmann | return;
|
386 | 99c7f878 | Gerd Hoffmann | } |
387 | 8f0056b7 | Paolo Bonzini | if (qemu_put_kbd_event) {
|
388 | 8f0056b7 | Paolo Bonzini | qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode); |
389 | 8f0056b7 | Paolo Bonzini | } |
390 | 8f0056b7 | Paolo Bonzini | } |
391 | 8f0056b7 | Paolo Bonzini | |
392 | 03a23a85 | Gerd Hoffmann | void kbd_put_ledstate(int ledstate) |
393 | 03a23a85 | Gerd Hoffmann | { |
394 | 03a23a85 | Gerd Hoffmann | QEMUPutLEDEntry *cursor; |
395 | 03a23a85 | Gerd Hoffmann | |
396 | 03a23a85 | Gerd Hoffmann | QTAILQ_FOREACH(cursor, &led_handlers, next) { |
397 | 03a23a85 | Gerd Hoffmann | cursor->put_led(cursor->opaque, ledstate); |
398 | 03a23a85 | Gerd Hoffmann | } |
399 | 03a23a85 | Gerd Hoffmann | } |
400 | 03a23a85 | Gerd Hoffmann | |
401 | 8f0056b7 | Paolo Bonzini | void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) |
402 | 8f0056b7 | Paolo Bonzini | { |
403 | 6fef28ee | Anthony Liguori | QEMUPutMouseEntry *entry; |
404 | 8f0056b7 | Paolo Bonzini | QEMUPutMouseEvent *mouse_event; |
405 | 8f0056b7 | Paolo Bonzini | void *mouse_event_opaque;
|
406 | 9312805d | Vasily Khoruzhick | int width, height;
|
407 | 8f0056b7 | Paolo Bonzini | |
408 | ad02b96a | Luiz Capitulino | if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
|
409 | 99c7f878 | Gerd Hoffmann | return;
|
410 | 99c7f878 | Gerd Hoffmann | } |
411 | 6fef28ee | Anthony Liguori | if (QTAILQ_EMPTY(&mouse_handlers)) {
|
412 | 8f0056b7 | Paolo Bonzini | return;
|
413 | 8f0056b7 | Paolo Bonzini | } |
414 | 8f0056b7 | Paolo Bonzini | |
415 | 6fef28ee | Anthony Liguori | entry = QTAILQ_FIRST(&mouse_handlers); |
416 | 6fef28ee | Anthony Liguori | |
417 | 6fef28ee | Anthony Liguori | mouse_event = entry->qemu_put_mouse_event; |
418 | 6fef28ee | Anthony Liguori | mouse_event_opaque = entry->qemu_put_mouse_event_opaque; |
419 | 8f0056b7 | Paolo Bonzini | |
420 | 8f0056b7 | Paolo Bonzini | if (mouse_event) {
|
421 | 9312805d | Vasily Khoruzhick | if (entry->qemu_put_mouse_event_absolute) {
|
422 | 9312805d | Vasily Khoruzhick | width = 0x7fff;
|
423 | 9312805d | Vasily Khoruzhick | height = 0x7fff;
|
424 | 97697373 | Brad Hards | } else {
|
425 | 9312805d | Vasily Khoruzhick | width = graphic_width - 1;
|
426 | 9312805d | Vasily Khoruzhick | height = graphic_height - 1;
|
427 | 9312805d | Vasily Khoruzhick | } |
428 | 9312805d | Vasily Khoruzhick | |
429 | 9312805d | Vasily Khoruzhick | switch (graphic_rotate) {
|
430 | 9312805d | Vasily Khoruzhick | case 0: |
431 | 9312805d | Vasily Khoruzhick | mouse_event(mouse_event_opaque, |
432 | 9312805d | Vasily Khoruzhick | dx, dy, dz, buttons_state); |
433 | 9312805d | Vasily Khoruzhick | break;
|
434 | 9312805d | Vasily Khoruzhick | case 90: |
435 | 9312805d | Vasily Khoruzhick | mouse_event(mouse_event_opaque, |
436 | 9312805d | Vasily Khoruzhick | width - dy, dx, dz, buttons_state); |
437 | 9312805d | Vasily Khoruzhick | break;
|
438 | 9312805d | Vasily Khoruzhick | case 180: |
439 | 9312805d | Vasily Khoruzhick | mouse_event(mouse_event_opaque, |
440 | 9312805d | Vasily Khoruzhick | width - dx, height - dy, dz, buttons_state); |
441 | 9312805d | Vasily Khoruzhick | break;
|
442 | 9312805d | Vasily Khoruzhick | case 270: |
443 | 9312805d | Vasily Khoruzhick | mouse_event(mouse_event_opaque, |
444 | 9312805d | Vasily Khoruzhick | dy, height - dx, dz, buttons_state); |
445 | 9312805d | Vasily Khoruzhick | break;
|
446 | 97697373 | Brad Hards | } |
447 | 8f0056b7 | Paolo Bonzini | } |
448 | 8f0056b7 | Paolo Bonzini | } |
449 | 8f0056b7 | Paolo Bonzini | |
450 | 8f0056b7 | Paolo Bonzini | int kbd_mouse_is_absolute(void) |
451 | 8f0056b7 | Paolo Bonzini | { |
452 | 6fef28ee | Anthony Liguori | if (QTAILQ_EMPTY(&mouse_handlers)) {
|
453 | 8f0056b7 | Paolo Bonzini | return 0; |
454 | 6fef28ee | Anthony Liguori | } |
455 | 8f0056b7 | Paolo Bonzini | |
456 | 6fef28ee | Anthony Liguori | return QTAILQ_FIRST(&mouse_handlers)->qemu_put_mouse_event_absolute;
|
457 | 8f0056b7 | Paolo Bonzini | } |
458 | 8f0056b7 | Paolo Bonzini | |
459 | eb2e259d | Anthony Liguori | int kbd_mouse_has_absolute(void) |
460 | eb2e259d | Anthony Liguori | { |
461 | eb2e259d | Anthony Liguori | QEMUPutMouseEntry *entry; |
462 | eb2e259d | Anthony Liguori | |
463 | eb2e259d | Anthony Liguori | QTAILQ_FOREACH(entry, &mouse_handlers, node) { |
464 | eb2e259d | Anthony Liguori | if (entry->qemu_put_mouse_event_absolute) {
|
465 | eb2e259d | Anthony Liguori | return 1; |
466 | eb2e259d | Anthony Liguori | } |
467 | eb2e259d | Anthony Liguori | } |
468 | eb2e259d | Anthony Liguori | |
469 | eb2e259d | Anthony Liguori | return 0; |
470 | eb2e259d | Anthony Liguori | } |
471 | eb2e259d | Anthony Liguori | |
472 | e235cec3 | Luiz Capitulino | MouseInfoList *qmp_query_mice(Error **errp) |
473 | 8f0056b7 | Paolo Bonzini | { |
474 | e235cec3 | Luiz Capitulino | MouseInfoList *mice_list = NULL;
|
475 | 8f0056b7 | Paolo Bonzini | QEMUPutMouseEntry *cursor; |
476 | e235cec3 | Luiz Capitulino | bool current = true; |
477 | 8f0056b7 | Paolo Bonzini | |
478 | e235cec3 | Luiz Capitulino | QTAILQ_FOREACH(cursor, &mouse_handlers, node) { |
479 | e235cec3 | Luiz Capitulino | MouseInfoList *info = g_malloc0(sizeof(*info));
|
480 | e235cec3 | Luiz Capitulino | info->value = g_malloc0(sizeof(*info->value));
|
481 | e235cec3 | Luiz Capitulino | info->value->name = g_strdup(cursor->qemu_put_mouse_event_name); |
482 | e235cec3 | Luiz Capitulino | info->value->index = cursor->index; |
483 | e235cec3 | Luiz Capitulino | info->value->absolute = !!cursor->qemu_put_mouse_event_absolute; |
484 | e235cec3 | Luiz Capitulino | info->value->current = current; |
485 | 8f0056b7 | Paolo Bonzini | |
486 | e235cec3 | Luiz Capitulino | current = false;
|
487 | 6fef28ee | Anthony Liguori | |
488 | e235cec3 | Luiz Capitulino | info->next = mice_list; |
489 | e235cec3 | Luiz Capitulino | mice_list = info; |
490 | 8f0056b7 | Paolo Bonzini | } |
491 | 8f0056b7 | Paolo Bonzini | |
492 | e235cec3 | Luiz Capitulino | return mice_list;
|
493 | 8f0056b7 | Paolo Bonzini | } |
494 | 8f0056b7 | Paolo Bonzini | |
495 | 8f0056b7 | Paolo Bonzini | void do_mouse_set(Monitor *mon, const QDict *qdict) |
496 | 8f0056b7 | Paolo Bonzini | { |
497 | 8f0056b7 | Paolo Bonzini | QEMUPutMouseEntry *cursor; |
498 | 8f0056b7 | Paolo Bonzini | int index = qdict_get_int(qdict, "index"); |
499 | 6fef28ee | Anthony Liguori | int found = 0; |
500 | 8f0056b7 | Paolo Bonzini | |
501 | 6fef28ee | Anthony Liguori | if (QTAILQ_EMPTY(&mouse_handlers)) {
|
502 | 8f0056b7 | Paolo Bonzini | monitor_printf(mon, "No mouse devices connected\n");
|
503 | 8f0056b7 | Paolo Bonzini | return;
|
504 | 8f0056b7 | Paolo Bonzini | } |
505 | 8f0056b7 | Paolo Bonzini | |
506 | 6fef28ee | Anthony Liguori | QTAILQ_FOREACH(cursor, &mouse_handlers, node) { |
507 | 6fef28ee | Anthony Liguori | if (cursor->index == index) {
|
508 | 6fef28ee | Anthony Liguori | found = 1;
|
509 | 6fef28ee | Anthony Liguori | qemu_activate_mouse_event_handler(cursor); |
510 | 6fef28ee | Anthony Liguori | break;
|
511 | 6fef28ee | Anthony Liguori | } |
512 | 8f0056b7 | Paolo Bonzini | } |
513 | 8f0056b7 | Paolo Bonzini | |
514 | 6fef28ee | Anthony Liguori | if (!found) {
|
515 | 8f0056b7 | Paolo Bonzini | monitor_printf(mon, "Mouse at given index not found\n");
|
516 | 6fef28ee | Anthony Liguori | } |
517 | 7e581fb3 | Anthony Liguori | |
518 | 7e581fb3 | Anthony Liguori | check_mode_change(); |
519 | 7e581fb3 | Anthony Liguori | } |
520 | 7e581fb3 | Anthony Liguori | |
521 | 7e581fb3 | Anthony Liguori | void qemu_add_mouse_mode_change_notifier(Notifier *notify)
|
522 | 7e581fb3 | Anthony Liguori | { |
523 | 7e581fb3 | Anthony Liguori | notifier_list_add(&mouse_mode_notifiers, notify); |
524 | 7e581fb3 | Anthony Liguori | } |
525 | 7e581fb3 | Anthony Liguori | |
526 | 7e581fb3 | Anthony Liguori | void qemu_remove_mouse_mode_change_notifier(Notifier *notify)
|
527 | 7e581fb3 | Anthony Liguori | { |
528 | 31552529 | Paolo Bonzini | notifier_remove(notify); |
529 | 8f0056b7 | Paolo Bonzini | } |