2
0

input-legacy.c 7.9 KB

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