2 * QEMU PS/2 keyboard/mouse emulation
4 * Copyright (c) 2003 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 #include "qemu/osdep.h"
27 #include "hw/input/ps2.h"
28 #include "ui/console.h"
30 #include "sysemu/sysemu.h"
34 /* debug PC keyboard */
37 /* debug PC keyboard : only mouse */
40 /* Keyboard Commands */
41 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
42 #define KBD_CMD_ECHO 0xEE
43 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
44 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
45 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
46 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
47 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
48 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
49 #define KBD_CMD_RESET 0xFF /* Reset */
51 /* Keyboard Replies */
52 #define KBD_REPLY_POR 0xAA /* Power on reset */
53 #define KBD_REPLY_ID 0xAB /* Keyboard ID */
54 #define KBD_REPLY_ACK 0xFA /* Command ACK */
55 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
58 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
59 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
60 #define AUX_SET_RES 0xE8 /* Set resolution */
61 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
62 #define AUX_SET_STREAM 0xEA /* Set stream mode */
63 #define AUX_POLL 0xEB /* Poll */
64 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
65 #define AUX_SET_WRAP 0xEE /* Set wrap mode */
66 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
67 #define AUX_GET_TYPE 0xF2 /* Get type */
68 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
69 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
70 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
71 #define AUX_SET_DEFAULT 0xF6
72 #define AUX_RESET 0xFF /* Reset aux device */
73 #define AUX_ACK 0xFA /* Command byte ACK. */
75 #define MOUSE_STATUS_REMOTE 0x40
76 #define MOUSE_STATUS_ENABLED 0x20
77 #define MOUSE_STATUS_SCALE21 0x10
79 #define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */
81 /* Bits for 'modifiers' field in PS2KbdState */
82 #define MOD_CTRL_L (1 << 0)
83 #define MOD_SHIFT_L (1 << 1)
84 #define MOD_ALT_L (1 << 2)
85 #define MOD_CTRL_R (1 << 3)
86 #define MOD_SHIFT_R (1 << 4)
87 #define MOD_ALT_R (1 << 5)
90 /* Keep the data array 256 bytes long, which compatibility
91 with older qemu versions. */
93 int rptr
, wptr
, count
;
99 void (*update_irq
)(void *, int);
107 int scancode_set
; /* 1=XT, 2=AT, 3=PS/2 */
110 unsigned int modifiers
; /* bitmask of MOD_* constants above */
115 uint8_t mouse_status
;
116 uint8_t mouse_resolution
;
117 uint8_t mouse_sample_rate
;
119 uint8_t mouse_type
; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
120 uint8_t mouse_detect_state
;
121 int mouse_dx
; /* current values, needed for 'poll' mode */
124 uint8_t mouse_buttons
;
127 /* Table to convert from QEMU codes to scancodes. */
128 static const uint16_t qcode_to_keycode_set1
[Q_KEY_CODE__MAX
] = {
129 [0 ... Q_KEY_CODE__MAX
- 1] = 0,
131 [Q_KEY_CODE_A
] = 0x1e,
132 [Q_KEY_CODE_B
] = 0x30,
133 [Q_KEY_CODE_C
] = 0x2e,
134 [Q_KEY_CODE_D
] = 0x20,
135 [Q_KEY_CODE_E
] = 0x12,
136 [Q_KEY_CODE_F
] = 0x21,
137 [Q_KEY_CODE_G
] = 0x22,
138 [Q_KEY_CODE_H
] = 0x23,
139 [Q_KEY_CODE_I
] = 0x17,
140 [Q_KEY_CODE_J
] = 0x24,
141 [Q_KEY_CODE_K
] = 0x25,
142 [Q_KEY_CODE_L
] = 0x26,
143 [Q_KEY_CODE_M
] = 0x32,
144 [Q_KEY_CODE_N
] = 0x31,
145 [Q_KEY_CODE_O
] = 0x18,
146 [Q_KEY_CODE_P
] = 0x19,
147 [Q_KEY_CODE_Q
] = 0x10,
148 [Q_KEY_CODE_R
] = 0x13,
149 [Q_KEY_CODE_S
] = 0x1f,
150 [Q_KEY_CODE_T
] = 0x14,
151 [Q_KEY_CODE_U
] = 0x16,
152 [Q_KEY_CODE_V
] = 0x2f,
153 [Q_KEY_CODE_W
] = 0x11,
154 [Q_KEY_CODE_X
] = 0x2d,
155 [Q_KEY_CODE_Y
] = 0x15,
156 [Q_KEY_CODE_Z
] = 0x2c,
157 [Q_KEY_CODE_0
] = 0x0b,
158 [Q_KEY_CODE_1
] = 0x02,
159 [Q_KEY_CODE_2
] = 0x03,
160 [Q_KEY_CODE_3
] = 0x04,
161 [Q_KEY_CODE_4
] = 0x05,
162 [Q_KEY_CODE_5
] = 0x06,
163 [Q_KEY_CODE_6
] = 0x07,
164 [Q_KEY_CODE_7
] = 0x08,
165 [Q_KEY_CODE_8
] = 0x09,
166 [Q_KEY_CODE_9
] = 0x0a,
167 [Q_KEY_CODE_GRAVE_ACCENT
] = 0x29,
168 [Q_KEY_CODE_MINUS
] = 0x0c,
169 [Q_KEY_CODE_EQUAL
] = 0x0d,
170 [Q_KEY_CODE_BACKSLASH
] = 0x2b,
171 [Q_KEY_CODE_BACKSPACE
] = 0x0e,
172 [Q_KEY_CODE_SPC
] = 0x39,
173 [Q_KEY_CODE_TAB
] = 0x0f,
174 [Q_KEY_CODE_CAPS_LOCK
] = 0x3a,
175 [Q_KEY_CODE_SHIFT
] = 0x2a,
176 [Q_KEY_CODE_CTRL
] = 0x1d,
177 [Q_KEY_CODE_META_L
] = 0xe05b,
178 [Q_KEY_CODE_ALT
] = 0x38,
179 [Q_KEY_CODE_SHIFT_R
] = 0x36,
180 [Q_KEY_CODE_CTRL_R
] = 0xe01d,
181 [Q_KEY_CODE_META_R
] = 0xe05c,
182 [Q_KEY_CODE_ALT_R
] = 0xe038,
183 [Q_KEY_CODE_MENU
] = 0xe05d,
184 [Q_KEY_CODE_RET
] = 0x1c,
185 [Q_KEY_CODE_ESC
] = 0x01,
186 [Q_KEY_CODE_F1
] = 0x3b,
187 [Q_KEY_CODE_F2
] = 0x3c,
188 [Q_KEY_CODE_F3
] = 0x3d,
189 [Q_KEY_CODE_F4
] = 0x3e,
190 [Q_KEY_CODE_F5
] = 0x3f,
191 [Q_KEY_CODE_F6
] = 0x40,
192 [Q_KEY_CODE_F7
] = 0x41,
193 [Q_KEY_CODE_F8
] = 0x42,
194 [Q_KEY_CODE_F9
] = 0x43,
195 [Q_KEY_CODE_F10
] = 0x44,
196 [Q_KEY_CODE_F11
] = 0x57,
197 [Q_KEY_CODE_F12
] = 0x58,
198 /* special handling for Q_KEY_CODE_PRINT */
199 [Q_KEY_CODE_SCROLL_LOCK
] = 0x46,
200 /* special handling for Q_KEY_CODE_PAUSE */
201 [Q_KEY_CODE_BRACKET_LEFT
] = 0x1a,
202 [Q_KEY_CODE_INSERT
] = 0xe052,
203 [Q_KEY_CODE_HOME
] = 0xe047,
204 [Q_KEY_CODE_PGUP
] = 0xe049,
205 [Q_KEY_CODE_DELETE
] = 0xe053,
206 [Q_KEY_CODE_END
] = 0xe04f,
207 [Q_KEY_CODE_PGDN
] = 0xe051,
208 [Q_KEY_CODE_UP
] = 0xe048,
209 [Q_KEY_CODE_LEFT
] = 0xe04b,
210 [Q_KEY_CODE_DOWN
] = 0xe050,
211 [Q_KEY_CODE_RIGHT
] = 0xe04d,
212 [Q_KEY_CODE_NUM_LOCK
] = 0x45,
213 [Q_KEY_CODE_KP_DIVIDE
] = 0xe035,
214 [Q_KEY_CODE_KP_MULTIPLY
] = 0x37,
215 [Q_KEY_CODE_KP_SUBTRACT
] = 0x4a,
216 [Q_KEY_CODE_KP_ADD
] = 0x4e,
217 [Q_KEY_CODE_KP_ENTER
] = 0xe01c,
218 [Q_KEY_CODE_KP_DECIMAL
] = 0x53,
219 [Q_KEY_CODE_KP_0
] = 0x52,
220 [Q_KEY_CODE_KP_1
] = 0x4f,
221 [Q_KEY_CODE_KP_2
] = 0x50,
222 [Q_KEY_CODE_KP_3
] = 0x51,
223 [Q_KEY_CODE_KP_4
] = 0x4b,
224 [Q_KEY_CODE_KP_5
] = 0x4c,
225 [Q_KEY_CODE_KP_6
] = 0x4d,
226 [Q_KEY_CODE_KP_7
] = 0x47,
227 [Q_KEY_CODE_KP_8
] = 0x48,
228 [Q_KEY_CODE_KP_9
] = 0x49,
229 [Q_KEY_CODE_BRACKET_RIGHT
] = 0x1b,
230 [Q_KEY_CODE_SEMICOLON
] = 0x27,
231 [Q_KEY_CODE_APOSTROPHE
] = 0x28,
232 [Q_KEY_CODE_COMMA
] = 0x33,
233 [Q_KEY_CODE_DOT
] = 0x34,
234 [Q_KEY_CODE_SLASH
] = 0x35,
236 [Q_KEY_CODE_POWER
] = 0x0e5e,
237 [Q_KEY_CODE_SLEEP
] = 0x0e5f,
238 [Q_KEY_CODE_WAKE
] = 0x0e63,
240 [Q_KEY_CODE_AUDIONEXT
] = 0xe019,
241 [Q_KEY_CODE_AUDIOPREV
] = 0xe010,
242 [Q_KEY_CODE_AUDIOSTOP
] = 0xe024,
243 [Q_KEY_CODE_AUDIOPLAY
] = 0xe022,
244 [Q_KEY_CODE_AUDIOMUTE
] = 0xe020,
245 [Q_KEY_CODE_VOLUMEUP
] = 0xe030,
246 [Q_KEY_CODE_VOLUMEDOWN
] = 0xe02e,
247 [Q_KEY_CODE_MEDIASELECT
] = 0xe06d,
248 [Q_KEY_CODE_MAIL
] = 0xe06c,
249 [Q_KEY_CODE_CALCULATOR
] = 0xe021,
250 [Q_KEY_CODE_COMPUTER
] = 0xe06b,
251 [Q_KEY_CODE_FIND
] = 0xe065,
252 [Q_KEY_CODE_AC_HOME
] = 0xe032,
253 [Q_KEY_CODE_AC_BACK
] = 0xe06a,
254 [Q_KEY_CODE_AC_FORWARD
] = 0xe069,
255 [Q_KEY_CODE_STOP
] = 0xe068,
256 [Q_KEY_CODE_AC_REFRESH
] = 0xe067,
257 [Q_KEY_CODE_AC_BOOKMARKS
] = 0xe066,
259 [Q_KEY_CODE_ASTERISK
] = 0x37,
260 [Q_KEY_CODE_LESS
] = 0x56,
261 [Q_KEY_CODE_RO
] = 0x73,
262 [Q_KEY_CODE_HIRAGANA
] = 0x70,
263 [Q_KEY_CODE_HENKAN
] = 0x79,
264 [Q_KEY_CODE_YEN
] = 0x7d,
265 [Q_KEY_CODE_KP_COMMA
] = 0x7e,
268 static const uint16_t qcode_to_keycode_set2
[Q_KEY_CODE__MAX
] = {
269 [0 ... Q_KEY_CODE__MAX
- 1] = 0,
271 [Q_KEY_CODE_A
] = 0x1c,
272 [Q_KEY_CODE_B
] = 0x32,
273 [Q_KEY_CODE_C
] = 0x21,
274 [Q_KEY_CODE_D
] = 0x23,
275 [Q_KEY_CODE_E
] = 0x24,
276 [Q_KEY_CODE_F
] = 0x2b,
277 [Q_KEY_CODE_G
] = 0x34,
278 [Q_KEY_CODE_H
] = 0x33,
279 [Q_KEY_CODE_I
] = 0x43,
280 [Q_KEY_CODE_J
] = 0x3b,
281 [Q_KEY_CODE_K
] = 0x42,
282 [Q_KEY_CODE_L
] = 0x4b,
283 [Q_KEY_CODE_M
] = 0x3a,
284 [Q_KEY_CODE_N
] = 0x31,
285 [Q_KEY_CODE_O
] = 0x44,
286 [Q_KEY_CODE_P
] = 0x4d,
287 [Q_KEY_CODE_Q
] = 0x15,
288 [Q_KEY_CODE_R
] = 0x2d,
289 [Q_KEY_CODE_S
] = 0x1b,
290 [Q_KEY_CODE_T
] = 0x2c,
291 [Q_KEY_CODE_U
] = 0x3c,
292 [Q_KEY_CODE_V
] = 0x2a,
293 [Q_KEY_CODE_W
] = 0x1d,
294 [Q_KEY_CODE_X
] = 0x22,
295 [Q_KEY_CODE_Y
] = 0x35,
296 [Q_KEY_CODE_Z
] = 0x1a,
297 [Q_KEY_CODE_0
] = 0x45,
298 [Q_KEY_CODE_1
] = 0x16,
299 [Q_KEY_CODE_2
] = 0x1e,
300 [Q_KEY_CODE_3
] = 0x26,
301 [Q_KEY_CODE_4
] = 0x25,
302 [Q_KEY_CODE_5
] = 0x2e,
303 [Q_KEY_CODE_6
] = 0x36,
304 [Q_KEY_CODE_7
] = 0x3d,
305 [Q_KEY_CODE_8
] = 0x3e,
306 [Q_KEY_CODE_9
] = 0x46,
307 [Q_KEY_CODE_GRAVE_ACCENT
] = 0x0e,
308 [Q_KEY_CODE_MINUS
] = 0x4e,
309 [Q_KEY_CODE_EQUAL
] = 0x55,
310 [Q_KEY_CODE_BACKSLASH
] = 0x5d,
311 [Q_KEY_CODE_BACKSPACE
] = 0x66,
312 [Q_KEY_CODE_SPC
] = 0x29,
313 [Q_KEY_CODE_TAB
] = 0x0d,
314 [Q_KEY_CODE_CAPS_LOCK
] = 0x58,
315 [Q_KEY_CODE_SHIFT
] = 0x12,
316 [Q_KEY_CODE_CTRL
] = 0x14,
317 [Q_KEY_CODE_META_L
] = 0xe01f,
318 [Q_KEY_CODE_ALT
] = 0x11,
319 [Q_KEY_CODE_SHIFT_R
] = 0x59,
320 [Q_KEY_CODE_CTRL_R
] = 0xe014,
321 [Q_KEY_CODE_META_R
] = 0xe027,
322 [Q_KEY_CODE_ALT_R
] = 0xe011,
323 [Q_KEY_CODE_MENU
] = 0xe02f,
324 [Q_KEY_CODE_RET
] = 0x5a,
325 [Q_KEY_CODE_ESC
] = 0x76,
326 [Q_KEY_CODE_F1
] = 0x05,
327 [Q_KEY_CODE_F2
] = 0x06,
328 [Q_KEY_CODE_F3
] = 0x04,
329 [Q_KEY_CODE_F4
] = 0x0c,
330 [Q_KEY_CODE_F5
] = 0x03,
331 [Q_KEY_CODE_F6
] = 0x0b,
332 [Q_KEY_CODE_F7
] = 0x83,
333 [Q_KEY_CODE_F8
] = 0x0a,
334 [Q_KEY_CODE_F9
] = 0x01,
335 [Q_KEY_CODE_F10
] = 0x09,
336 [Q_KEY_CODE_F11
] = 0x78,
337 [Q_KEY_CODE_F12
] = 0x07,
338 /* special handling for Q_KEY_CODE_PRINT */
339 [Q_KEY_CODE_SCROLL_LOCK
] = 0x7e,
340 /* special handling for Q_KEY_CODE_PAUSE */
341 [Q_KEY_CODE_BRACKET_LEFT
] = 0x54,
342 [Q_KEY_CODE_INSERT
] = 0xe070,
343 [Q_KEY_CODE_HOME
] = 0xe06c,
344 [Q_KEY_CODE_PGUP
] = 0xe07d,
345 [Q_KEY_CODE_DELETE
] = 0xe071,
346 [Q_KEY_CODE_END
] = 0xe069,
347 [Q_KEY_CODE_PGDN
] = 0xe07a,
348 [Q_KEY_CODE_UP
] = 0xe075,
349 [Q_KEY_CODE_LEFT
] = 0xe06b,
350 [Q_KEY_CODE_DOWN
] = 0xe072,
351 [Q_KEY_CODE_RIGHT
] = 0xe074,
352 [Q_KEY_CODE_NUM_LOCK
] = 0x77,
353 [Q_KEY_CODE_KP_DIVIDE
] = 0xe04a,
354 [Q_KEY_CODE_KP_MULTIPLY
] = 0x7c,
355 [Q_KEY_CODE_KP_SUBTRACT
] = 0x7b,
356 [Q_KEY_CODE_KP_ADD
] = 0x79,
357 [Q_KEY_CODE_KP_ENTER
] = 0xe05a,
358 [Q_KEY_CODE_KP_DECIMAL
] = 0x71,
359 [Q_KEY_CODE_KP_0
] = 0x70,
360 [Q_KEY_CODE_KP_1
] = 0x69,
361 [Q_KEY_CODE_KP_2
] = 0x72,
362 [Q_KEY_CODE_KP_3
] = 0x7a,
363 [Q_KEY_CODE_KP_4
] = 0x6b,
364 [Q_KEY_CODE_KP_5
] = 0x73,
365 [Q_KEY_CODE_KP_6
] = 0x74,
366 [Q_KEY_CODE_KP_7
] = 0x6c,
367 [Q_KEY_CODE_KP_8
] = 0x75,
368 [Q_KEY_CODE_KP_9
] = 0x7d,
369 [Q_KEY_CODE_BRACKET_RIGHT
] = 0x5b,
370 [Q_KEY_CODE_SEMICOLON
] = 0x4c,
371 [Q_KEY_CODE_APOSTROPHE
] = 0x52,
372 [Q_KEY_CODE_COMMA
] = 0x41,
373 [Q_KEY_CODE_DOT
] = 0x49,
374 [Q_KEY_CODE_SLASH
] = 0x4a,
376 [Q_KEY_CODE_POWER
] = 0x0e37,
377 [Q_KEY_CODE_SLEEP
] = 0x0e3f,
378 [Q_KEY_CODE_WAKE
] = 0x0e5e,
380 [Q_KEY_CODE_AUDIONEXT
] = 0xe04d,
381 [Q_KEY_CODE_AUDIOPREV
] = 0xe015,
382 [Q_KEY_CODE_AUDIOSTOP
] = 0xe03b,
383 [Q_KEY_CODE_AUDIOPLAY
] = 0xe034,
384 [Q_KEY_CODE_AUDIOMUTE
] = 0xe023,
385 [Q_KEY_CODE_VOLUMEUP
] = 0xe032,
386 [Q_KEY_CODE_VOLUMEDOWN
] = 0xe021,
387 [Q_KEY_CODE_MEDIASELECT
] = 0xe050,
388 [Q_KEY_CODE_MAIL
] = 0xe048,
389 [Q_KEY_CODE_CALCULATOR
] = 0xe02b,
390 [Q_KEY_CODE_COMPUTER
] = 0xe040,
391 [Q_KEY_CODE_FIND
] = 0xe010,
392 [Q_KEY_CODE_AC_HOME
] = 0xe03a,
393 [Q_KEY_CODE_AC_BACK
] = 0xe038,
394 [Q_KEY_CODE_AC_FORWARD
] = 0xe030,
395 [Q_KEY_CODE_STOP
] = 0xe028,
396 [Q_KEY_CODE_AC_REFRESH
] = 0xe020,
397 [Q_KEY_CODE_AC_BOOKMARKS
] = 0xe018,
399 [Q_KEY_CODE_ASTERISK
] = 0x7c,
400 [Q_KEY_CODE_LESS
] = 0x61,
401 [Q_KEY_CODE_SYSRQ
] = 0x7f,
402 [Q_KEY_CODE_RO
] = 0x51,
403 [Q_KEY_CODE_HIRAGANA
] = 0x13,
404 [Q_KEY_CODE_HENKAN
] = 0x64,
405 [Q_KEY_CODE_YEN
] = 0x6a,
406 [Q_KEY_CODE_KP_COMMA
] = 0x6d,
409 static const uint16_t qcode_to_keycode_set3
[Q_KEY_CODE__MAX
] = {
410 [0 ... Q_KEY_CODE__MAX
- 1] = 0,
412 [Q_KEY_CODE_A
] = 0x1c,
413 [Q_KEY_CODE_B
] = 0x32,
414 [Q_KEY_CODE_C
] = 0x21,
415 [Q_KEY_CODE_D
] = 0x23,
416 [Q_KEY_CODE_E
] = 0x24,
417 [Q_KEY_CODE_F
] = 0x2b,
418 [Q_KEY_CODE_G
] = 0x34,
419 [Q_KEY_CODE_H
] = 0x33,
420 [Q_KEY_CODE_I
] = 0x43,
421 [Q_KEY_CODE_J
] = 0x3b,
422 [Q_KEY_CODE_K
] = 0x42,
423 [Q_KEY_CODE_L
] = 0x4b,
424 [Q_KEY_CODE_M
] = 0x3a,
425 [Q_KEY_CODE_N
] = 0x31,
426 [Q_KEY_CODE_O
] = 0x44,
427 [Q_KEY_CODE_P
] = 0x4d,
428 [Q_KEY_CODE_Q
] = 0x15,
429 [Q_KEY_CODE_R
] = 0x2d,
430 [Q_KEY_CODE_S
] = 0x1b,
431 [Q_KEY_CODE_T
] = 0x2c,
432 [Q_KEY_CODE_U
] = 0x3c,
433 [Q_KEY_CODE_V
] = 0x2a,
434 [Q_KEY_CODE_W
] = 0x1d,
435 [Q_KEY_CODE_X
] = 0x22,
436 [Q_KEY_CODE_Y
] = 0x35,
437 [Q_KEY_CODE_Z
] = 0x1a,
438 [Q_KEY_CODE_0
] = 0x45,
439 [Q_KEY_CODE_1
] = 0x16,
440 [Q_KEY_CODE_2
] = 0x1e,
441 [Q_KEY_CODE_3
] = 0x26,
442 [Q_KEY_CODE_4
] = 0x25,
443 [Q_KEY_CODE_5
] = 0x2e,
444 [Q_KEY_CODE_6
] = 0x36,
445 [Q_KEY_CODE_7
] = 0x3d,
446 [Q_KEY_CODE_8
] = 0x3e,
447 [Q_KEY_CODE_9
] = 0x46,
448 [Q_KEY_CODE_GRAVE_ACCENT
] = 0x0e,
449 [Q_KEY_CODE_MINUS
] = 0x4e,
450 [Q_KEY_CODE_EQUAL
] = 0x55,
451 [Q_KEY_CODE_BACKSLASH
] = 0x5c,
452 [Q_KEY_CODE_BACKSPACE
] = 0x66,
453 [Q_KEY_CODE_SPC
] = 0x29,
454 [Q_KEY_CODE_TAB
] = 0x0d,
455 [Q_KEY_CODE_CAPS_LOCK
] = 0x14,
456 [Q_KEY_CODE_SHIFT
] = 0x12,
457 [Q_KEY_CODE_CTRL
] = 0x11,
458 [Q_KEY_CODE_META_L
] = 0x8b,
459 [Q_KEY_CODE_ALT
] = 0x19,
460 [Q_KEY_CODE_SHIFT_R
] = 0x59,
461 [Q_KEY_CODE_CTRL_R
] = 0x58,
462 [Q_KEY_CODE_META_R
] = 0x8c,
463 [Q_KEY_CODE_ALT_R
] = 0x39,
464 [Q_KEY_CODE_MENU
] = 0x8d,
465 [Q_KEY_CODE_RET
] = 0x5a,
466 [Q_KEY_CODE_ESC
] = 0x08,
467 [Q_KEY_CODE_F1
] = 0x07,
468 [Q_KEY_CODE_F2
] = 0x0f,
469 [Q_KEY_CODE_F3
] = 0x17,
470 [Q_KEY_CODE_F4
] = 0x1f,
471 [Q_KEY_CODE_F5
] = 0x27,
472 [Q_KEY_CODE_F6
] = 0x2f,
473 [Q_KEY_CODE_F7
] = 0x37,
474 [Q_KEY_CODE_F8
] = 0x3f,
475 [Q_KEY_CODE_F9
] = 0x47,
476 [Q_KEY_CODE_F10
] = 0x4f,
477 [Q_KEY_CODE_F11
] = 0x56,
478 [Q_KEY_CODE_F12
] = 0x5e,
479 [Q_KEY_CODE_PRINT
] = 0x57,
480 [Q_KEY_CODE_SCROLL_LOCK
] = 0x5f,
481 [Q_KEY_CODE_PAUSE
] = 0x62,
482 [Q_KEY_CODE_BRACKET_LEFT
] = 0x54,
483 [Q_KEY_CODE_INSERT
] = 0x67,
484 [Q_KEY_CODE_HOME
] = 0x6e,
485 [Q_KEY_CODE_PGUP
] = 0x6f,
486 [Q_KEY_CODE_DELETE
] = 0x64,
487 [Q_KEY_CODE_END
] = 0x65,
488 [Q_KEY_CODE_PGDN
] = 0x6d,
489 [Q_KEY_CODE_UP
] = 0x63,
490 [Q_KEY_CODE_LEFT
] = 0x61,
491 [Q_KEY_CODE_DOWN
] = 0x60,
492 [Q_KEY_CODE_RIGHT
] = 0x6a,
493 [Q_KEY_CODE_NUM_LOCK
] = 0x76,
494 [Q_KEY_CODE_KP_DIVIDE
] = 0x4a,
495 [Q_KEY_CODE_KP_MULTIPLY
] = 0x7e,
496 [Q_KEY_CODE_KP_SUBTRACT
] = 0x4e,
497 [Q_KEY_CODE_KP_ADD
] = 0x7c,
498 [Q_KEY_CODE_KP_ENTER
] = 0x79,
499 [Q_KEY_CODE_KP_DECIMAL
] = 0x71,
500 [Q_KEY_CODE_KP_0
] = 0x70,
501 [Q_KEY_CODE_KP_1
] = 0x69,
502 [Q_KEY_CODE_KP_2
] = 0x72,
503 [Q_KEY_CODE_KP_3
] = 0x7a,
504 [Q_KEY_CODE_KP_4
] = 0x6b,
505 [Q_KEY_CODE_KP_5
] = 0x73,
506 [Q_KEY_CODE_KP_6
] = 0x74,
507 [Q_KEY_CODE_KP_7
] = 0x6c,
508 [Q_KEY_CODE_KP_8
] = 0x75,
509 [Q_KEY_CODE_KP_9
] = 0x7d,
510 [Q_KEY_CODE_BRACKET_RIGHT
] = 0x5b,
511 [Q_KEY_CODE_SEMICOLON
] = 0x4c,
512 [Q_KEY_CODE_APOSTROPHE
] = 0x52,
513 [Q_KEY_CODE_COMMA
] = 0x41,
514 [Q_KEY_CODE_DOT
] = 0x49,
515 [Q_KEY_CODE_SLASH
] = 0x4a,
517 [Q_KEY_CODE_HIRAGANA
] = 0x87,
518 [Q_KEY_CODE_HENKAN
] = 0x86,
519 [Q_KEY_CODE_YEN
] = 0x5d,
522 static uint8_t translate_table
[256] = {
523 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
524 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
525 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
526 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
527 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
528 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
529 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
530 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
531 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
532 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
533 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
534 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
535 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
536 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
537 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
538 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
539 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
540 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
541 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
542 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
543 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
544 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
545 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
546 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
547 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
548 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
549 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
550 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
551 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
552 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
553 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
554 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
557 static unsigned int ps2_modifier_bit(QKeyCode key
)
560 case Q_KEY_CODE_CTRL
:
562 case Q_KEY_CODE_CTRL_R
:
564 case Q_KEY_CODE_SHIFT
:
566 case Q_KEY_CODE_SHIFT_R
:
570 case Q_KEY_CODE_ALT_R
:
577 static void ps2_reset_queue(PS2State
*s
)
579 PS2Queue
*q
= &s
->queue
;
586 void ps2_queue(PS2State
*s
, int b
)
588 PS2Queue
*q
= &s
->queue
;
590 if (q
->count
>= PS2_QUEUE_SIZE
- 1)
592 q
->data
[q
->wptr
] = b
;
593 if (++q
->wptr
== PS2_QUEUE_SIZE
)
596 s
->update_irq(s
->update_arg
, 1);
599 /* keycode is the untranslated scancode in the current scancode set. */
600 static void ps2_put_keycode(void *opaque
, int keycode
)
602 PS2KbdState
*s
= opaque
;
604 trace_ps2_put_keycode(opaque
, keycode
);
605 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
);
608 if (keycode
== 0xf0) {
609 s
->need_high_bit
= true;
610 } else if (s
->need_high_bit
) {
611 ps2_queue(&s
->common
, translate_table
[keycode
] | 0x80);
612 s
->need_high_bit
= false;
614 ps2_queue(&s
->common
, translate_table
[keycode
]);
617 ps2_queue(&s
->common
, keycode
);
621 static void ps2_keyboard_event(DeviceState
*dev
, QemuConsole
*src
,
624 PS2KbdState
*s
= (PS2KbdState
*)dev
;
625 InputKeyEvent
*key
= evt
->u
.key
.data
;
630 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
);
631 assert(evt
->type
== INPUT_EVENT_KIND_KEY
);
632 qcode
= qemu_input_key_value_to_qcode(key
->key
);
634 mod
= ps2_modifier_bit(qcode
);
635 trace_ps2_keyboard_event(s
, qcode
, key
->down
, mod
, s
->modifiers
);
639 s
->modifiers
&= ~mod
;
642 if (s
->scancode_set
== 1) {
643 if (qcode
== Q_KEY_CODE_PAUSE
) {
644 if (s
->modifiers
& (MOD_CTRL_L
| MOD_CTRL_R
)) {
646 ps2_put_keycode(s
, 0xe0);
647 ps2_put_keycode(s
, 0x46);
648 ps2_put_keycode(s
, 0xe0);
649 ps2_put_keycode(s
, 0xc6);
653 ps2_put_keycode(s
, 0xe1);
654 ps2_put_keycode(s
, 0x1d);
655 ps2_put_keycode(s
, 0x45);
656 ps2_put_keycode(s
, 0xe1);
657 ps2_put_keycode(s
, 0x9d);
658 ps2_put_keycode(s
, 0xc5);
661 } else if (qcode
== Q_KEY_CODE_PRINT
) {
662 if (s
->modifiers
& MOD_ALT_L
) {
664 ps2_put_keycode(s
, 0xb8);
665 ps2_put_keycode(s
, 0x38);
666 ps2_put_keycode(s
, 0x54);
668 ps2_put_keycode(s
, 0xd4);
669 ps2_put_keycode(s
, 0xb8);
670 ps2_put_keycode(s
, 0x38);
672 } else if (s
->modifiers
& MOD_ALT_R
) {
674 ps2_put_keycode(s
, 0xe0);
675 ps2_put_keycode(s
, 0xb8);
676 ps2_put_keycode(s
, 0xe0);
677 ps2_put_keycode(s
, 0x38);
678 ps2_put_keycode(s
, 0x54);
680 ps2_put_keycode(s
, 0xd4);
681 ps2_put_keycode(s
, 0xe0);
682 ps2_put_keycode(s
, 0xb8);
683 ps2_put_keycode(s
, 0xe0);
684 ps2_put_keycode(s
, 0x38);
686 } else if (s
->modifiers
& (MOD_SHIFT_L
| MOD_CTRL_L
|
687 MOD_SHIFT_R
| MOD_CTRL_R
)) {
689 ps2_put_keycode(s
, 0xe0);
690 ps2_put_keycode(s
, 0x37);
692 ps2_put_keycode(s
, 0xe0);
693 ps2_put_keycode(s
, 0xb7);
697 ps2_put_keycode(s
, 0xe0);
698 ps2_put_keycode(s
, 0x2a);
699 ps2_put_keycode(s
, 0xe0);
700 ps2_put_keycode(s
, 0x37);
702 ps2_put_keycode(s
, 0xe0);
703 ps2_put_keycode(s
, 0xb7);
704 ps2_put_keycode(s
, 0xe0);
705 ps2_put_keycode(s
, 0xaa);
709 keycode
= qcode_to_keycode_set1
[qcode
];
711 if (keycode
& 0xff00) {
712 ps2_put_keycode(s
, keycode
>> 8);
717 ps2_put_keycode(s
, keycode
& 0xff);
719 qemu_log_mask(LOG_UNIMP
,
720 "ps2: ignoring key with qcode %d\n", qcode
);
723 } else if (s
->scancode_set
== 2) {
724 if (qcode
== Q_KEY_CODE_PAUSE
) {
725 if (s
->modifiers
& (MOD_CTRL_L
| MOD_CTRL_R
)) {
727 ps2_put_keycode(s
, 0xe0);
728 ps2_put_keycode(s
, 0x7e);
729 ps2_put_keycode(s
, 0xe0);
730 ps2_put_keycode(s
, 0xf0);
731 ps2_put_keycode(s
, 0x7e);
735 ps2_put_keycode(s
, 0xe1);
736 ps2_put_keycode(s
, 0x14);
737 ps2_put_keycode(s
, 0x77);
738 ps2_put_keycode(s
, 0xe1);
739 ps2_put_keycode(s
, 0xf0);
740 ps2_put_keycode(s
, 0x14);
741 ps2_put_keycode(s
, 0xf0);
742 ps2_put_keycode(s
, 0x77);
745 } else if (qcode
== Q_KEY_CODE_PRINT
) {
746 if (s
->modifiers
& MOD_ALT_L
) {
748 ps2_put_keycode(s
, 0xf0);
749 ps2_put_keycode(s
, 0x11);
750 ps2_put_keycode(s
, 0x11);
751 ps2_put_keycode(s
, 0x84);
753 ps2_put_keycode(s
, 0xf0);
754 ps2_put_keycode(s
, 0x84);
755 ps2_put_keycode(s
, 0xf0);
756 ps2_put_keycode(s
, 0x11);
757 ps2_put_keycode(s
, 0x11);
759 } else if (s
->modifiers
& MOD_ALT_R
) {
761 ps2_put_keycode(s
, 0xe0);
762 ps2_put_keycode(s
, 0xf0);
763 ps2_put_keycode(s
, 0x11);
764 ps2_put_keycode(s
, 0xe0);
765 ps2_put_keycode(s
, 0x11);
766 ps2_put_keycode(s
, 0x84);
768 ps2_put_keycode(s
, 0xf0);
769 ps2_put_keycode(s
, 0x84);
770 ps2_put_keycode(s
, 0xe0);
771 ps2_put_keycode(s
, 0xf0);
772 ps2_put_keycode(s
, 0x11);
773 ps2_put_keycode(s
, 0xe0);
774 ps2_put_keycode(s
, 0x11);
776 } else if (s
->modifiers
& (MOD_SHIFT_L
| MOD_CTRL_L
|
777 MOD_SHIFT_R
| MOD_CTRL_R
)) {
779 ps2_put_keycode(s
, 0xe0);
780 ps2_put_keycode(s
, 0x7c);
782 ps2_put_keycode(s
, 0xe0);
783 ps2_put_keycode(s
, 0xf0);
784 ps2_put_keycode(s
, 0x7c);
788 ps2_put_keycode(s
, 0xe0);
789 ps2_put_keycode(s
, 0x12);
790 ps2_put_keycode(s
, 0xe0);
791 ps2_put_keycode(s
, 0x7c);
793 ps2_put_keycode(s
, 0xe0);
794 ps2_put_keycode(s
, 0xf0);
795 ps2_put_keycode(s
, 0x7c);
796 ps2_put_keycode(s
, 0xe0);
797 ps2_put_keycode(s
, 0xf0);
798 ps2_put_keycode(s
, 0x12);
802 keycode
= qcode_to_keycode_set2
[qcode
];
804 if (keycode
& 0xff00) {
805 ps2_put_keycode(s
, keycode
>> 8);
808 ps2_put_keycode(s
, 0xf0);
810 ps2_put_keycode(s
, keycode
& 0xff);
812 qemu_log_mask(LOG_UNIMP
,
813 "ps2: ignoring key with qcode %d\n", qcode
);
816 } else if (s
->scancode_set
== 3) {
817 keycode
= qcode_to_keycode_set3
[qcode
];
819 /* FIXME: break code should be configured on a key by key basis */
821 ps2_put_keycode(s
, 0xf0);
823 ps2_put_keycode(s
, keycode
);
825 qemu_log_mask(LOG_UNIMP
,
826 "ps2: ignoring key with qcode %d\n", qcode
);
831 uint32_t ps2_read_data(PS2State
*s
)
836 trace_ps2_read_data(s
);
839 /* NOTE: if no data left, we return the last keyboard one
840 (needed for EMM386) */
841 /* XXX: need a timer to do things correctly */
844 index
= PS2_QUEUE_SIZE
- 1;
845 val
= q
->data
[index
];
847 val
= q
->data
[q
->rptr
];
848 if (++q
->rptr
== PS2_QUEUE_SIZE
)
851 /* reading deasserts IRQ */
852 s
->update_irq(s
->update_arg
, 0);
853 /* reassert IRQs if data left */
854 s
->update_irq(s
->update_arg
, q
->count
!= 0);
859 static void ps2_set_ledstate(PS2KbdState
*s
, int ledstate
)
861 trace_ps2_set_ledstate(s
, ledstate
);
862 s
->ledstate
= ledstate
;
863 kbd_put_ledstate(ledstate
);
866 static void ps2_reset_keyboard(PS2KbdState
*s
)
868 trace_ps2_reset_keyboard(s
);
871 ps2_reset_queue(&s
->common
);
872 ps2_set_ledstate(s
, 0);
875 void ps2_write_keyboard(void *opaque
, int val
)
877 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
879 trace_ps2_write_keyboard(opaque
, val
);
880 switch(s
->common
.write_cmd
) {
885 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
888 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
891 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
892 /* We emulate a MF2 AT keyboard here */
893 ps2_queue(&s
->common
, KBD_REPLY_ID
);
895 ps2_queue(&s
->common
, 0x41);
897 ps2_queue(&s
->common
, 0x83);
900 ps2_queue(&s
->common
, KBD_CMD_ECHO
);
904 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
906 case KBD_CMD_SCANCODE
:
907 case KBD_CMD_SET_LEDS
:
908 case KBD_CMD_SET_RATE
:
909 s
->common
.write_cmd
= val
;
910 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
912 case KBD_CMD_RESET_DISABLE
:
913 ps2_reset_keyboard(s
);
915 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
917 case KBD_CMD_RESET_ENABLE
:
918 ps2_reset_keyboard(s
);
920 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
923 ps2_reset_keyboard(s
);
924 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
925 ps2_queue(&s
->common
, KBD_REPLY_POR
);
928 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
932 case KBD_CMD_SCANCODE
:
934 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
935 ps2_put_keycode(s
, s
->scancode_set
);
936 } else if (val
>= 1 && val
<= 3) {
937 s
->scancode_set
= val
;
938 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
940 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
942 s
->common
.write_cmd
= -1;
944 case KBD_CMD_SET_LEDS
:
945 ps2_set_ledstate(s
, val
);
946 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
947 s
->common
.write_cmd
= -1;
949 case KBD_CMD_SET_RATE
:
950 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
951 s
->common
.write_cmd
= -1;
956 /* Set the scancode translation mode.
958 1 = translated scancodes (used by qemu internally). */
960 void ps2_keyboard_set_translation(void *opaque
, int mode
)
962 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
963 trace_ps2_keyboard_set_translation(opaque
, mode
);
967 static void ps2_mouse_send_packet(PS2MouseState
*s
)
975 /* XXX: increase range to 8 bits ? */
984 b
= 0x08 | ((dx1
< 0) << 4) | ((dy1
< 0) << 5) | (s
->mouse_buttons
& 0x07);
985 ps2_queue(&s
->common
, b
);
986 ps2_queue(&s
->common
, dx1
& 0xff);
987 ps2_queue(&s
->common
, dy1
& 0xff);
988 /* extra byte for IMPS/2 or IMEX */
989 switch(s
->mouse_type
) {
997 ps2_queue(&s
->common
, dz1
& 0xff);
1004 b
= (dz1
& 0x0f) | ((s
->mouse_buttons
& 0x18) << 1);
1005 ps2_queue(&s
->common
, b
);
1009 trace_ps2_mouse_send_packet(s
, dx1
, dy1
, dz1
, b
);
1016 static void ps2_mouse_event(DeviceState
*dev
, QemuConsole
*src
,
1019 static const int bmap
[INPUT_BUTTON__MAX
] = {
1020 [INPUT_BUTTON_LEFT
] = PS2_MOUSE_BUTTON_LEFT
,
1021 [INPUT_BUTTON_MIDDLE
] = PS2_MOUSE_BUTTON_MIDDLE
,
1022 [INPUT_BUTTON_RIGHT
] = PS2_MOUSE_BUTTON_RIGHT
,
1023 [INPUT_BUTTON_SIDE
] = PS2_MOUSE_BUTTON_SIDE
,
1024 [INPUT_BUTTON_EXTRA
] = PS2_MOUSE_BUTTON_EXTRA
,
1026 PS2MouseState
*s
= (PS2MouseState
*)dev
;
1027 InputMoveEvent
*move
;
1030 /* check if deltas are recorded when disabled */
1031 if (!(s
->mouse_status
& MOUSE_STATUS_ENABLED
))
1034 switch (evt
->type
) {
1035 case INPUT_EVENT_KIND_REL
:
1036 move
= evt
->u
.rel
.data
;
1037 if (move
->axis
== INPUT_AXIS_X
) {
1038 s
->mouse_dx
+= move
->value
;
1039 } else if (move
->axis
== INPUT_AXIS_Y
) {
1040 s
->mouse_dy
-= move
->value
;
1044 case INPUT_EVENT_KIND_BTN
:
1045 btn
= evt
->u
.btn
.data
;
1047 s
->mouse_buttons
|= bmap
[btn
->button
];
1048 if (btn
->button
== INPUT_BUTTON_WHEEL_UP
) {
1050 } else if (btn
->button
== INPUT_BUTTON_WHEEL_DOWN
) {
1054 s
->mouse_buttons
&= ~bmap
[btn
->button
];
1059 /* keep gcc happy */
1064 static void ps2_mouse_sync(DeviceState
*dev
)
1066 PS2MouseState
*s
= (PS2MouseState
*)dev
;
1068 if (s
->mouse_buttons
) {
1069 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
);
1071 if (!(s
->mouse_status
& MOUSE_STATUS_REMOTE
)) {
1072 while (s
->common
.queue
.count
< PS2_QUEUE_SIZE
- 4) {
1073 /* if not remote, send event. Multiple events are sent if
1075 ps2_mouse_send_packet(s
);
1076 if (s
->mouse_dx
== 0 && s
->mouse_dy
== 0 && s
->mouse_dz
== 0)
1082 void ps2_mouse_fake_event(void *opaque
)
1084 PS2MouseState
*s
= opaque
;
1085 trace_ps2_mouse_fake_event(opaque
);
1087 ps2_mouse_sync(opaque
);
1090 void ps2_write_mouse(void *opaque
, int val
)
1092 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
1094 trace_ps2_write_mouse(opaque
, val
);
1096 printf("kbd: write mouse 0x%02x\n", val
);
1098 switch(s
->common
.write_cmd
) {
1102 if (s
->mouse_wrap
) {
1103 if (val
== AUX_RESET_WRAP
) {
1105 ps2_queue(&s
->common
, AUX_ACK
);
1107 } else if (val
!= AUX_RESET
) {
1108 ps2_queue(&s
->common
, val
);
1113 case AUX_SET_SCALE11
:
1114 s
->mouse_status
&= ~MOUSE_STATUS_SCALE21
;
1115 ps2_queue(&s
->common
, AUX_ACK
);
1117 case AUX_SET_SCALE21
:
1118 s
->mouse_status
|= MOUSE_STATUS_SCALE21
;
1119 ps2_queue(&s
->common
, AUX_ACK
);
1121 case AUX_SET_STREAM
:
1122 s
->mouse_status
&= ~MOUSE_STATUS_REMOTE
;
1123 ps2_queue(&s
->common
, AUX_ACK
);
1127 ps2_queue(&s
->common
, AUX_ACK
);
1129 case AUX_SET_REMOTE
:
1130 s
->mouse_status
|= MOUSE_STATUS_REMOTE
;
1131 ps2_queue(&s
->common
, AUX_ACK
);
1134 ps2_queue(&s
->common
, AUX_ACK
);
1135 ps2_queue(&s
->common
, s
->mouse_type
);
1138 case AUX_SET_SAMPLE
:
1139 s
->common
.write_cmd
= val
;
1140 ps2_queue(&s
->common
, AUX_ACK
);
1143 ps2_queue(&s
->common
, AUX_ACK
);
1144 ps2_queue(&s
->common
, s
->mouse_status
);
1145 ps2_queue(&s
->common
, s
->mouse_resolution
);
1146 ps2_queue(&s
->common
, s
->mouse_sample_rate
);
1149 ps2_queue(&s
->common
, AUX_ACK
);
1150 ps2_mouse_send_packet(s
);
1152 case AUX_ENABLE_DEV
:
1153 s
->mouse_status
|= MOUSE_STATUS_ENABLED
;
1154 ps2_queue(&s
->common
, AUX_ACK
);
1156 case AUX_DISABLE_DEV
:
1157 s
->mouse_status
&= ~MOUSE_STATUS_ENABLED
;
1158 ps2_queue(&s
->common
, AUX_ACK
);
1160 case AUX_SET_DEFAULT
:
1161 s
->mouse_sample_rate
= 100;
1162 s
->mouse_resolution
= 2;
1163 s
->mouse_status
= 0;
1164 ps2_queue(&s
->common
, AUX_ACK
);
1167 s
->mouse_sample_rate
= 100;
1168 s
->mouse_resolution
= 2;
1169 s
->mouse_status
= 0;
1171 ps2_queue(&s
->common
, AUX_ACK
);
1172 ps2_queue(&s
->common
, 0xaa);
1173 ps2_queue(&s
->common
, s
->mouse_type
);
1179 case AUX_SET_SAMPLE
:
1180 s
->mouse_sample_rate
= val
;
1181 /* detect IMPS/2 or IMEX */
1182 switch(s
->mouse_detect_state
) {
1186 s
->mouse_detect_state
= 1;
1190 s
->mouse_detect_state
= 2;
1191 else if (val
== 200)
1192 s
->mouse_detect_state
= 3;
1194 s
->mouse_detect_state
= 0;
1198 s
->mouse_type
= 3; /* IMPS/2 */
1199 s
->mouse_detect_state
= 0;
1203 s
->mouse_type
= 4; /* IMEX */
1204 s
->mouse_detect_state
= 0;
1207 ps2_queue(&s
->common
, AUX_ACK
);
1208 s
->common
.write_cmd
= -1;
1211 s
->mouse_resolution
= val
;
1212 ps2_queue(&s
->common
, AUX_ACK
);
1213 s
->common
.write_cmd
= -1;
1218 static void ps2_common_reset(PS2State
*s
)
1222 s
->update_irq(s
->update_arg
, 0);
1225 static void ps2_common_post_load(PS2State
*s
)
1227 PS2Queue
*q
= &s
->queue
;
1230 int tmp_data
[PS2_QUEUE_SIZE
];
1232 /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
1233 size
= q
->count
> PS2_QUEUE_SIZE
? 0 : q
->count
;
1235 /* move the queue elements to the start of data array */
1237 for (i
= 0; i
< size
; i
++) {
1238 /* move the queue elements to the temporary buffer */
1239 tmp_data
[i
] = q
->data
[q
->rptr
];
1240 if (++q
->rptr
== 256) {
1244 memcpy(q
->data
, tmp_data
, size
);
1246 /* reset rptr/wptr/count */
1250 s
->update_irq(s
->update_arg
, q
->count
!= 0);
1253 static void ps2_kbd_reset(void *opaque
)
1255 PS2KbdState
*s
= (PS2KbdState
*) opaque
;
1257 trace_ps2_kbd_reset(opaque
);
1258 ps2_common_reset(&s
->common
);
1259 s
->scan_enabled
= 0;
1261 s
->scancode_set
= 2;
1265 static void ps2_mouse_reset(void *opaque
)
1267 PS2MouseState
*s
= (PS2MouseState
*) opaque
;
1269 trace_ps2_mouse_reset(opaque
);
1270 ps2_common_reset(&s
->common
);
1271 s
->mouse_status
= 0;
1272 s
->mouse_resolution
= 0;
1273 s
->mouse_sample_rate
= 0;
1276 s
->mouse_detect_state
= 0;
1280 s
->mouse_buttons
= 0;
1283 static const VMStateDescription vmstate_ps2_common
= {
1284 .name
= "PS2 Common State",
1286 .minimum_version_id
= 2,
1287 .fields
= (VMStateField
[]) {
1288 VMSTATE_INT32(write_cmd
, PS2State
),
1289 VMSTATE_INT32(queue
.rptr
, PS2State
),
1290 VMSTATE_INT32(queue
.wptr
, PS2State
),
1291 VMSTATE_INT32(queue
.count
, PS2State
),
1292 VMSTATE_BUFFER(queue
.data
, PS2State
),
1293 VMSTATE_END_OF_LIST()
1297 static bool ps2_keyboard_ledstate_needed(void *opaque
)
1299 PS2KbdState
*s
= opaque
;
1301 return s
->ledstate
!= 0; /* 0 is default state */
1304 static int ps2_kbd_ledstate_post_load(void *opaque
, int version_id
)
1306 PS2KbdState
*s
= opaque
;
1308 kbd_put_ledstate(s
->ledstate
);
1312 static const VMStateDescription vmstate_ps2_keyboard_ledstate
= {
1313 .name
= "ps2kbd/ledstate",
1315 .minimum_version_id
= 2,
1316 .post_load
= ps2_kbd_ledstate_post_load
,
1317 .needed
= ps2_keyboard_ledstate_needed
,
1318 .fields
= (VMStateField
[]) {
1319 VMSTATE_INT32(ledstate
, PS2KbdState
),
1320 VMSTATE_END_OF_LIST()
1324 static bool ps2_keyboard_need_high_bit_needed(void *opaque
)
1326 PS2KbdState
*s
= opaque
;
1327 return s
->need_high_bit
!= 0; /* 0 is the usual state */
1330 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit
= {
1331 .name
= "ps2kbd/need_high_bit",
1333 .minimum_version_id
= 1,
1334 .needed
= ps2_keyboard_need_high_bit_needed
,
1335 .fields
= (VMStateField
[]) {
1336 VMSTATE_BOOL(need_high_bit
, PS2KbdState
),
1337 VMSTATE_END_OF_LIST()
1341 static int ps2_kbd_post_load(void* opaque
, int version_id
)
1343 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
1344 PS2State
*ps2
= &s
->common
;
1346 if (version_id
== 2)
1349 ps2_common_post_load(ps2
);
1354 static int ps2_kbd_pre_save(void *opaque
)
1356 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
1357 PS2State
*ps2
= &s
->common
;
1359 ps2_common_post_load(ps2
);
1364 static const VMStateDescription vmstate_ps2_keyboard
= {
1367 .minimum_version_id
= 2,
1368 .post_load
= ps2_kbd_post_load
,
1369 .pre_save
= ps2_kbd_pre_save
,
1370 .fields
= (VMStateField
[]) {
1371 VMSTATE_STRUCT(common
, PS2KbdState
, 0, vmstate_ps2_common
, PS2State
),
1372 VMSTATE_INT32(scan_enabled
, PS2KbdState
),
1373 VMSTATE_INT32(translate
, PS2KbdState
),
1374 VMSTATE_INT32_V(scancode_set
, PS2KbdState
,3),
1375 VMSTATE_END_OF_LIST()
1377 .subsections
= (const VMStateDescription
*[]) {
1378 &vmstate_ps2_keyboard_ledstate
,
1379 &vmstate_ps2_keyboard_need_high_bit
,
1384 static int ps2_mouse_post_load(void *opaque
, int version_id
)
1386 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
1387 PS2State
*ps2
= &s
->common
;
1389 ps2_common_post_load(ps2
);
1394 static int ps2_mouse_pre_save(void *opaque
)
1396 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
1397 PS2State
*ps2
= &s
->common
;
1399 ps2_common_post_load(ps2
);
1404 static const VMStateDescription vmstate_ps2_mouse
= {
1407 .minimum_version_id
= 2,
1408 .post_load
= ps2_mouse_post_load
,
1409 .pre_save
= ps2_mouse_pre_save
,
1410 .fields
= (VMStateField
[]) {
1411 VMSTATE_STRUCT(common
, PS2MouseState
, 0, vmstate_ps2_common
, PS2State
),
1412 VMSTATE_UINT8(mouse_status
, PS2MouseState
),
1413 VMSTATE_UINT8(mouse_resolution
, PS2MouseState
),
1414 VMSTATE_UINT8(mouse_sample_rate
, PS2MouseState
),
1415 VMSTATE_UINT8(mouse_wrap
, PS2MouseState
),
1416 VMSTATE_UINT8(mouse_type
, PS2MouseState
),
1417 VMSTATE_UINT8(mouse_detect_state
, PS2MouseState
),
1418 VMSTATE_INT32(mouse_dx
, PS2MouseState
),
1419 VMSTATE_INT32(mouse_dy
, PS2MouseState
),
1420 VMSTATE_INT32(mouse_dz
, PS2MouseState
),
1421 VMSTATE_UINT8(mouse_buttons
, PS2MouseState
),
1422 VMSTATE_END_OF_LIST()
1426 static QemuInputHandler ps2_keyboard_handler
= {
1427 .name
= "QEMU PS/2 Keyboard",
1428 .mask
= INPUT_EVENT_MASK_KEY
,
1429 .event
= ps2_keyboard_event
,
1432 void *ps2_kbd_init(void (*update_irq
)(void *, int), void *update_arg
)
1434 PS2KbdState
*s
= (PS2KbdState
*)g_malloc0(sizeof(PS2KbdState
));
1436 trace_ps2_kbd_init(s
);
1437 s
->common
.update_irq
= update_irq
;
1438 s
->common
.update_arg
= update_arg
;
1439 s
->scancode_set
= 2;
1440 vmstate_register(NULL
, 0, &vmstate_ps2_keyboard
, s
);
1441 qemu_input_handler_register((DeviceState
*)s
,
1442 &ps2_keyboard_handler
);
1443 qemu_register_reset(ps2_kbd_reset
, s
);
1447 static QemuInputHandler ps2_mouse_handler
= {
1448 .name
= "QEMU PS/2 Mouse",
1449 .mask
= INPUT_EVENT_MASK_BTN
| INPUT_EVENT_MASK_REL
,
1450 .event
= ps2_mouse_event
,
1451 .sync
= ps2_mouse_sync
,
1454 void *ps2_mouse_init(void (*update_irq
)(void *, int), void *update_arg
)
1456 PS2MouseState
*s
= (PS2MouseState
*)g_malloc0(sizeof(PS2MouseState
));
1458 trace_ps2_mouse_init(s
);
1459 s
->common
.update_irq
= update_irq
;
1460 s
->common
.update_arg
= update_arg
;
1461 vmstate_register(NULL
, 0, &vmstate_ps2_mouse
, s
);
1462 qemu_input_handler_register((DeviceState
*)s
,
1463 &ps2_mouse_handler
);
1464 qemu_register_reset(ps2_mouse_reset
, s
);