hid.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. /*
  2. * QEMU HID devices
  3. *
  4. * Copyright (c) 2005 Fabrice Bellard
  5. * Copyright (c) 2007 OpenMoko, Inc. (andrew@openedhand.com)
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. #include "hw.h"
  26. #include "console.h"
  27. #include "qemu-timer.h"
  28. #include "hid.h"
  29. #define HID_USAGE_ERROR_ROLLOVER 0x01
  30. #define HID_USAGE_POSTFAIL 0x02
  31. #define HID_USAGE_ERROR_UNDEFINED 0x03
  32. /* Indices are QEMU keycodes, values are from HID Usage Table. Indices
  33. * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */
  34. static const uint8_t hid_usage_keys[0x100] = {
  35. 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
  36. 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
  37. 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
  38. 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
  39. 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
  40. 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
  41. 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
  42. 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
  43. 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
  44. 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
  45. 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
  46. 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
  47. 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
  48. 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
  49. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  50. 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
  51. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  52. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  53. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  54. 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
  55. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  56. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  57. 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
  58. 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  59. 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
  60. 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
  61. 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
  62. 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00,
  63. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  64. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  65. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  66. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  67. };
  68. bool hid_has_events(HIDState *hs)
  69. {
  70. return hs->n > 0;
  71. }
  72. void hid_set_next_idle(HIDState *hs, int64_t curtime)
  73. {
  74. hs->next_idle_clock = curtime + (get_ticks_per_sec() * hs->idle * 4) / 1000;
  75. }
  76. static void hid_pointer_event_clear(HIDPointerEvent *e, int buttons)
  77. {
  78. e->xdx = e->ydy = e->dz = 0;
  79. e->buttons_state = buttons;
  80. }
  81. static void hid_pointer_event_combine(HIDPointerEvent *e, int xyrel,
  82. int x1, int y1, int z1) {
  83. if (xyrel) {
  84. e->xdx += x1;
  85. e->ydy += y1;
  86. } else {
  87. e->xdx = x1;
  88. e->ydy = y1;
  89. /* Windows drivers do not like the 0/0 position and ignore such
  90. * events. */
  91. if (!(x1 | y1)) {
  92. e->xdx = 1;
  93. }
  94. }
  95. e->dz += z1;
  96. }
  97. static void hid_pointer_event(void *opaque,
  98. int x1, int y1, int z1, int buttons_state)
  99. {
  100. HIDState *hs = opaque;
  101. unsigned use_slot = (hs->head + hs->n - 1) & QUEUE_MASK;
  102. unsigned previous_slot = (use_slot - 1) & QUEUE_MASK;
  103. /* We combine events where feasible to keep the queue small. We shouldn't
  104. * combine anything with the first event of a particular button state, as
  105. * that would change the location of the button state change. When the
  106. * queue is empty, a second event is needed because we don't know if
  107. * the first event changed the button state. */
  108. if (hs->n == QUEUE_LENGTH) {
  109. /* Queue full. Discard old button state, combine motion normally. */
  110. hs->ptr.queue[use_slot].buttons_state = buttons_state;
  111. } else if (hs->n < 2 ||
  112. hs->ptr.queue[use_slot].buttons_state != buttons_state ||
  113. hs->ptr.queue[previous_slot].buttons_state !=
  114. hs->ptr.queue[use_slot].buttons_state) {
  115. /* Cannot or should not combine, so add an empty item to the queue. */
  116. QUEUE_INCR(use_slot);
  117. hs->n++;
  118. hid_pointer_event_clear(&hs->ptr.queue[use_slot], buttons_state);
  119. }
  120. hid_pointer_event_combine(&hs->ptr.queue[use_slot],
  121. hs->kind == HID_MOUSE,
  122. x1, y1, z1);
  123. hs->event(hs);
  124. }
  125. static void hid_keyboard_event(void *opaque, int keycode)
  126. {
  127. HIDState *hs = opaque;
  128. int slot;
  129. if (hs->n == QUEUE_LENGTH) {
  130. fprintf(stderr, "usb-kbd: warning: key event queue full\n");
  131. return;
  132. }
  133. slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
  134. hs->kbd.keycodes[slot] = keycode;
  135. hs->event(hs);
  136. }
  137. static void hid_keyboard_process_keycode(HIDState *hs)
  138. {
  139. uint8_t hid_code, key;
  140. int i, keycode, slot;
  141. if (hs->n == 0) {
  142. return;
  143. }
  144. slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
  145. keycode = hs->kbd.keycodes[slot];
  146. key = keycode & 0x7f;
  147. hid_code = hid_usage_keys[key | ((hs->kbd.modifiers >> 1) & (1 << 7))];
  148. hs->kbd.modifiers &= ~(1 << 8);
  149. switch (hid_code) {
  150. case 0x00:
  151. return;
  152. case 0xe0:
  153. if (hs->kbd.modifiers & (1 << 9)) {
  154. hs->kbd.modifiers ^= 3 << 8;
  155. return;
  156. }
  157. case 0xe1 ... 0xe7:
  158. if (keycode & (1 << 7)) {
  159. hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f));
  160. return;
  161. }
  162. case 0xe8 ... 0xef:
  163. hs->kbd.modifiers |= 1 << (hid_code & 0x0f);
  164. return;
  165. }
  166. if (keycode & (1 << 7)) {
  167. for (i = hs->kbd.keys - 1; i >= 0; i--) {
  168. if (hs->kbd.key[i] == hid_code) {
  169. hs->kbd.key[i] = hs->kbd.key[-- hs->kbd.keys];
  170. hs->kbd.key[hs->kbd.keys] = 0x00;
  171. break;
  172. }
  173. }
  174. if (i < 0) {
  175. return;
  176. }
  177. } else {
  178. for (i = hs->kbd.keys - 1; i >= 0; i--) {
  179. if (hs->kbd.key[i] == hid_code) {
  180. break;
  181. }
  182. }
  183. if (i < 0) {
  184. if (hs->kbd.keys < sizeof(hs->kbd.key)) {
  185. hs->kbd.key[hs->kbd.keys++] = hid_code;
  186. }
  187. } else {
  188. return;
  189. }
  190. }
  191. }
  192. static inline int int_clamp(int val, int vmin, int vmax)
  193. {
  194. if (val < vmin) {
  195. return vmin;
  196. } else if (val > vmax) {
  197. return vmax;
  198. } else {
  199. return val;
  200. }
  201. }
  202. void hid_pointer_activate(HIDState *hs)
  203. {
  204. if (!hs->ptr.mouse_grabbed) {
  205. qemu_activate_mouse_event_handler(hs->ptr.eh_entry);
  206. hs->ptr.mouse_grabbed = 1;
  207. }
  208. }
  209. int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
  210. {
  211. int dx, dy, dz, b, l;
  212. int index;
  213. HIDPointerEvent *e;
  214. hid_pointer_activate(hs);
  215. /* When the buffer is empty, return the last event. Relative
  216. movements will all be zero. */
  217. index = (hs->n ? hs->head : hs->head - 1);
  218. e = &hs->ptr.queue[index & QUEUE_MASK];
  219. if (hs->kind == HID_MOUSE) {
  220. dx = int_clamp(e->xdx, -127, 127);
  221. dy = int_clamp(e->ydy, -127, 127);
  222. e->xdx -= dx;
  223. e->ydy -= dy;
  224. } else {
  225. dx = e->xdx;
  226. dy = e->ydy;
  227. }
  228. dz = int_clamp(e->dz, -127, 127);
  229. e->dz -= dz;
  230. b = 0;
  231. if (e->buttons_state & MOUSE_EVENT_LBUTTON) {
  232. b |= 0x01;
  233. }
  234. if (e->buttons_state & MOUSE_EVENT_RBUTTON) {
  235. b |= 0x02;
  236. }
  237. if (e->buttons_state & MOUSE_EVENT_MBUTTON) {
  238. b |= 0x04;
  239. }
  240. if (hs->n &&
  241. !e->dz &&
  242. (hs->kind == HID_TABLET || (!e->xdx && !e->ydy))) {
  243. /* that deals with this event */
  244. QUEUE_INCR(hs->head);
  245. hs->n--;
  246. }
  247. /* Appears we have to invert the wheel direction */
  248. dz = 0 - dz;
  249. l = 0;
  250. switch (hs->kind) {
  251. case HID_MOUSE:
  252. if (len > l) {
  253. buf[l++] = b;
  254. }
  255. if (len > l) {
  256. buf[l++] = dx;
  257. }
  258. if (len > l) {
  259. buf[l++] = dy;
  260. }
  261. if (len > l) {
  262. buf[l++] = dz;
  263. }
  264. break;
  265. case HID_TABLET:
  266. if (len > l) {
  267. buf[l++] = b;
  268. }
  269. if (len > l) {
  270. buf[l++] = dx & 0xff;
  271. }
  272. if (len > l) {
  273. buf[l++] = dx >> 8;
  274. }
  275. if (len > l) {
  276. buf[l++] = dy & 0xff;
  277. }
  278. if (len > l) {
  279. buf[l++] = dy >> 8;
  280. }
  281. if (len > l) {
  282. buf[l++] = dz;
  283. }
  284. break;
  285. default:
  286. abort();
  287. }
  288. return l;
  289. }
  290. int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len)
  291. {
  292. if (len < 2) {
  293. return 0;
  294. }
  295. hid_keyboard_process_keycode(hs);
  296. buf[0] = hs->kbd.modifiers & 0xff;
  297. buf[1] = 0;
  298. if (hs->kbd.keys > 6) {
  299. memset(buf + 2, HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
  300. } else {
  301. memcpy(buf + 2, hs->kbd.key, MIN(8, len) - 2);
  302. }
  303. return MIN(8, len);
  304. }
  305. int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len)
  306. {
  307. if (len > 0) {
  308. int ledstate = 0;
  309. /* 0x01: Num Lock LED
  310. * 0x02: Caps Lock LED
  311. * 0x04: Scroll Lock LED
  312. * 0x08: Compose LED
  313. * 0x10: Kana LED */
  314. hs->kbd.leds = buf[0];
  315. if (hs->kbd.leds & 0x04) {
  316. ledstate |= QEMU_SCROLL_LOCK_LED;
  317. }
  318. if (hs->kbd.leds & 0x01) {
  319. ledstate |= QEMU_NUM_LOCK_LED;
  320. }
  321. if (hs->kbd.leds & 0x02) {
  322. ledstate |= QEMU_CAPS_LOCK_LED;
  323. }
  324. kbd_put_ledstate(ledstate);
  325. }
  326. return 0;
  327. }
  328. void hid_reset(HIDState *hs)
  329. {
  330. switch (hs->kind) {
  331. case HID_KEYBOARD:
  332. memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
  333. memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
  334. hs->kbd.keys = 0;
  335. break;
  336. case HID_MOUSE:
  337. case HID_TABLET:
  338. memset(hs->ptr.queue, 0, sizeof(hs->ptr.queue));
  339. break;
  340. }
  341. hs->head = 0;
  342. hs->n = 0;
  343. hs->protocol = 1;
  344. hs->idle = 0;
  345. }
  346. void hid_free(HIDState *hs)
  347. {
  348. switch (hs->kind) {
  349. case HID_KEYBOARD:
  350. qemu_remove_kbd_event_handler();
  351. break;
  352. case HID_MOUSE:
  353. case HID_TABLET:
  354. qemu_remove_mouse_event_handler(hs->ptr.eh_entry);
  355. break;
  356. }
  357. }
  358. void hid_init(HIDState *hs, int kind, HIDEventFunc event)
  359. {
  360. hs->kind = kind;
  361. hs->event = event;
  362. if (hs->kind == HID_KEYBOARD) {
  363. qemu_add_kbd_event_handler(hid_keyboard_event, hs);
  364. } else if (hs->kind == HID_MOUSE) {
  365. hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
  366. 0, "QEMU HID Mouse");
  367. } else if (hs->kind == HID_TABLET) {
  368. hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
  369. 1, "QEMU HID Tablet");
  370. }
  371. }
  372. static int hid_post_load(void *opaque, int version_id)
  373. {
  374. HIDState *s = opaque;
  375. if (s->idle) {
  376. hid_set_next_idle(s, qemu_get_clock_ns(vm_clock));
  377. }
  378. return 0;
  379. }
  380. static const VMStateDescription vmstate_hid_ptr_queue = {
  381. .name = "HIDPointerEventQueue",
  382. .version_id = 1,
  383. .minimum_version_id = 1,
  384. .fields = (VMStateField[]) {
  385. VMSTATE_INT32(xdx, HIDPointerEvent),
  386. VMSTATE_INT32(ydy, HIDPointerEvent),
  387. VMSTATE_INT32(dz, HIDPointerEvent),
  388. VMSTATE_INT32(buttons_state, HIDPointerEvent),
  389. VMSTATE_END_OF_LIST()
  390. }
  391. };
  392. const VMStateDescription vmstate_hid_ptr_device = {
  393. .name = "HIDPointerDevice",
  394. .version_id = 1,
  395. .minimum_version_id = 1,
  396. .post_load = hid_post_load,
  397. .fields = (VMStateField[]) {
  398. VMSTATE_STRUCT_ARRAY(ptr.queue, HIDState, QUEUE_LENGTH, 0,
  399. vmstate_hid_ptr_queue, HIDPointerEvent),
  400. VMSTATE_UINT32(head, HIDState),
  401. VMSTATE_UINT32(n, HIDState),
  402. VMSTATE_INT32(protocol, HIDState),
  403. VMSTATE_UINT8(idle, HIDState),
  404. VMSTATE_END_OF_LIST(),
  405. }
  406. };
  407. const VMStateDescription vmstate_hid_keyboard_device = {
  408. .name = "HIDKeyboardDevice",
  409. .version_id = 1,
  410. .minimum_version_id = 1,
  411. .post_load = hid_post_load,
  412. .fields = (VMStateField[]) {
  413. VMSTATE_UINT32_ARRAY(kbd.keycodes, HIDState, QUEUE_LENGTH),
  414. VMSTATE_UINT32(head, HIDState),
  415. VMSTATE_UINT32(n, HIDState),
  416. VMSTATE_UINT16(kbd.modifiers, HIDState),
  417. VMSTATE_UINT8(kbd.leds, HIDState),
  418. VMSTATE_UINT8_ARRAY(kbd.key, HIDState, 16),
  419. VMSTATE_INT32(kbd.keys, HIDState),
  420. VMSTATE_INT32(protocol, HIDState),
  421. VMSTATE_UINT8(idle, HIDState),
  422. VMSTATE_END_OF_LIST(),
  423. }
  424. };