2
0

input-legacy.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. * QEMU System Emulator
  3. *
  4. * Copyright (c) 2003-2008 Fabrice Bellard
  5. *
  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:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  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
  22. * THE SOFTWARE.
  23. */
  24. #include "qemu/osdep.h"
  25. #include "qemu/log.h"
  26. #include "qapi/qapi-commands-ui.h"
  27. #include "ui/console.h"
  28. #include "keymaps.h"
  29. #include "ui/input.h"
  30. struct QEMUPutMouseEntry {
  31. QEMUPutMouseEvent *qemu_put_mouse_event;
  32. void *qemu_put_mouse_event_opaque;
  33. int qemu_put_mouse_event_absolute;
  34. /* new input core */
  35. QemuInputHandler h;
  36. QemuInputHandlerState *s;
  37. int axis[INPUT_AXIS__MAX];
  38. int buttons;
  39. };
  40. struct QEMUPutKbdEntry {
  41. QEMUPutKBDEvent *put_kbd;
  42. void *opaque;
  43. QemuInputHandlerState *s;
  44. };
  45. struct QEMUPutLEDEntry {
  46. QEMUPutLEDEvent *put_led;
  47. void *opaque;
  48. QTAILQ_ENTRY(QEMUPutLEDEntry) next;
  49. };
  50. static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers =
  51. QTAILQ_HEAD_INITIALIZER(led_handlers);
  52. int index_from_key(const char *key, size_t key_length)
  53. {
  54. int i;
  55. for (i = 0; i < Q_KEY_CODE__MAX; i++) {
  56. if (!strncmp(key, QKeyCode_str(i), key_length) &&
  57. !QKeyCode_str(i)[key_length]) {
  58. break;
  59. }
  60. }
  61. /* Return Q_KEY_CODE__MAX if the key is invalid */
  62. return i;
  63. }
  64. static KeyValue *copy_key_value(KeyValue *src)
  65. {
  66. KeyValue *dst = g_new(KeyValue, 1);
  67. memcpy(dst, src, sizeof(*src));
  68. if (dst->type == KEY_VALUE_KIND_NUMBER) {
  69. QKeyCode code = qemu_input_key_number_to_qcode(dst->u.number.data);
  70. dst->type = KEY_VALUE_KIND_QCODE;
  71. dst->u.qcode.data = code;
  72. }
  73. return dst;
  74. }
  75. void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
  76. Error **errp)
  77. {
  78. KeyValueList *p;
  79. KeyValue **up = NULL;
  80. int count = 0;
  81. if (!has_hold_time) {
  82. hold_time = 0; /* use default */
  83. }
  84. for (p = keys; p != NULL; p = p->next) {
  85. qemu_input_event_send_key(NULL, copy_key_value(p->value), true);
  86. qemu_input_event_send_key_delay(hold_time);
  87. up = g_realloc(up, sizeof(*up) * (count+1));
  88. up[count] = copy_key_value(p->value);
  89. count++;
  90. }
  91. while (count) {
  92. count--;
  93. qemu_input_event_send_key(NULL, up[count], false);
  94. qemu_input_event_send_key_delay(hold_time);
  95. }
  96. g_free(up);
  97. }
  98. static void legacy_kbd_event(DeviceState *dev, QemuConsole *src,
  99. InputEvent *evt)
  100. {
  101. QEMUPutKbdEntry *entry = (QEMUPutKbdEntry *)dev;
  102. int scancodes[3], i, count;
  103. InputKeyEvent *key = evt->u.key.data;
  104. if (!entry || !entry->put_kbd) {
  105. return;
  106. }
  107. count = qemu_input_key_value_to_scancode(key->key,
  108. key->down,
  109. scancodes);
  110. for (i = 0; i < count; i++) {
  111. entry->put_kbd(entry->opaque, scancodes[i]);
  112. }
  113. }
  114. static QemuInputHandler legacy_kbd_handler = {
  115. .name = "legacy-kbd",
  116. .mask = INPUT_EVENT_MASK_KEY,
  117. .event = legacy_kbd_event,
  118. };
  119. QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
  120. {
  121. QEMUPutKbdEntry *entry;
  122. entry = g_new0(QEMUPutKbdEntry, 1);
  123. entry->put_kbd = func;
  124. entry->opaque = opaque;
  125. entry->s = qemu_input_handler_register((DeviceState *)entry,
  126. &legacy_kbd_handler);
  127. qemu_input_handler_activate(entry->s);
  128. return entry;
  129. }
  130. static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
  131. InputEvent *evt)
  132. {
  133. static const int bmap[INPUT_BUTTON__MAX] = {
  134. [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
  135. [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
  136. [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
  137. };
  138. QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
  139. InputBtnEvent *btn;
  140. InputMoveEvent *move;
  141. switch (evt->type) {
  142. case INPUT_EVENT_KIND_BTN:
  143. btn = evt->u.btn.data;
  144. if (btn->down) {
  145. s->buttons |= bmap[btn->button];
  146. } else {
  147. s->buttons &= ~bmap[btn->button];
  148. }
  149. if (btn->down && btn->button == INPUT_BUTTON_WHEEL_UP) {
  150. s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
  151. s->axis[INPUT_AXIS_X],
  152. s->axis[INPUT_AXIS_Y],
  153. -1,
  154. s->buttons);
  155. }
  156. if (btn->down && btn->button == INPUT_BUTTON_WHEEL_DOWN) {
  157. s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
  158. s->axis[INPUT_AXIS_X],
  159. s->axis[INPUT_AXIS_Y],
  160. 1,
  161. s->buttons);
  162. }
  163. if (btn->down && btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
  164. s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
  165. s->axis[INPUT_AXIS_X],
  166. s->axis[INPUT_AXIS_Y],
  167. -2,
  168. s->buttons);
  169. }
  170. if (btn->down && btn->button == INPUT_BUTTON_WHEEL_LEFT) {
  171. s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
  172. s->axis[INPUT_AXIS_X],
  173. s->axis[INPUT_AXIS_Y],
  174. 2,
  175. s->buttons);
  176. }
  177. break;
  178. case INPUT_EVENT_KIND_ABS:
  179. move = evt->u.abs.data;
  180. s->axis[move->axis] = move->value;
  181. break;
  182. case INPUT_EVENT_KIND_REL:
  183. move = evt->u.rel.data;
  184. s->axis[move->axis] += move->value;
  185. break;
  186. default:
  187. break;
  188. }
  189. }
  190. static void legacy_mouse_sync(DeviceState *dev)
  191. {
  192. QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
  193. s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
  194. s->axis[INPUT_AXIS_X],
  195. s->axis[INPUT_AXIS_Y],
  196. 0,
  197. s->buttons);
  198. if (!s->qemu_put_mouse_event_absolute) {
  199. s->axis[INPUT_AXIS_X] = 0;
  200. s->axis[INPUT_AXIS_Y] = 0;
  201. }
  202. }
  203. QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
  204. void *opaque, int absolute,
  205. const char *name)
  206. {
  207. QEMUPutMouseEntry *s;
  208. s = g_new0(QEMUPutMouseEntry, 1);
  209. s->qemu_put_mouse_event = func;
  210. s->qemu_put_mouse_event_opaque = opaque;
  211. s->qemu_put_mouse_event_absolute = absolute;
  212. s->h.name = name;
  213. s->h.mask = INPUT_EVENT_MASK_BTN |
  214. (absolute ? INPUT_EVENT_MASK_ABS : INPUT_EVENT_MASK_REL);
  215. s->h.event = legacy_mouse_event;
  216. s->h.sync = legacy_mouse_sync;
  217. s->s = qemu_input_handler_register((DeviceState *)s,
  218. &s->h);
  219. return s;
  220. }
  221. void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry)
  222. {
  223. qemu_input_handler_activate(entry->s);
  224. }
  225. void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
  226. {
  227. qemu_input_handler_unregister(entry->s);
  228. g_free(entry);
  229. }
  230. QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func,
  231. void *opaque)
  232. {
  233. QEMUPutLEDEntry *s;
  234. s = g_new0(QEMUPutLEDEntry, 1);
  235. s->put_led = func;
  236. s->opaque = opaque;
  237. QTAILQ_INSERT_TAIL(&led_handlers, s, next);
  238. return s;
  239. }
  240. void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
  241. {
  242. if (entry == NULL)
  243. return;
  244. QTAILQ_REMOVE(&led_handlers, entry, next);
  245. g_free(entry);
  246. }
  247. void kbd_put_ledstate(int ledstate)
  248. {
  249. QEMUPutLEDEntry *cursor;
  250. QTAILQ_FOREACH(cursor, &led_handlers, next) {
  251. cursor->put_led(cursor->opaque, ledstate);
  252. }
  253. }