input-legacy.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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_mouse_event(DeviceState *dev, QemuConsole *src,
  99. InputEvent *evt)
  100. {
  101. static const int bmap[INPUT_BUTTON__MAX] = {
  102. [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
  103. [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
  104. [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
  105. };
  106. QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
  107. InputBtnEvent *btn;
  108. InputMoveEvent *move;
  109. switch (evt->type) {
  110. case INPUT_EVENT_KIND_BTN:
  111. btn = evt->u.btn.data;
  112. if (btn->down) {
  113. s->buttons |= bmap[btn->button];
  114. } else {
  115. s->buttons &= ~bmap[btn->button];
  116. }
  117. if (btn->down && btn->button == INPUT_BUTTON_WHEEL_UP) {
  118. s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
  119. s->axis[INPUT_AXIS_X],
  120. s->axis[INPUT_AXIS_Y],
  121. -1,
  122. s->buttons);
  123. }
  124. if (btn->down && btn->button == INPUT_BUTTON_WHEEL_DOWN) {
  125. s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
  126. s->axis[INPUT_AXIS_X],
  127. s->axis[INPUT_AXIS_Y],
  128. 1,
  129. s->buttons);
  130. }
  131. if (btn->down && btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
  132. s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
  133. s->axis[INPUT_AXIS_X],
  134. s->axis[INPUT_AXIS_Y],
  135. -2,
  136. s->buttons);
  137. }
  138. if (btn->down && btn->button == INPUT_BUTTON_WHEEL_LEFT) {
  139. s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
  140. s->axis[INPUT_AXIS_X],
  141. s->axis[INPUT_AXIS_Y],
  142. 2,
  143. s->buttons);
  144. }
  145. break;
  146. case INPUT_EVENT_KIND_ABS:
  147. move = evt->u.abs.data;
  148. s->axis[move->axis] = move->value;
  149. break;
  150. case INPUT_EVENT_KIND_REL:
  151. move = evt->u.rel.data;
  152. s->axis[move->axis] += move->value;
  153. break;
  154. default:
  155. break;
  156. }
  157. }
  158. static void legacy_mouse_sync(DeviceState *dev)
  159. {
  160. QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
  161. s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
  162. s->axis[INPUT_AXIS_X],
  163. s->axis[INPUT_AXIS_Y],
  164. 0,
  165. s->buttons);
  166. if (!s->qemu_put_mouse_event_absolute) {
  167. s->axis[INPUT_AXIS_X] = 0;
  168. s->axis[INPUT_AXIS_Y] = 0;
  169. }
  170. }
  171. QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
  172. void *opaque, int absolute,
  173. const char *name)
  174. {
  175. QEMUPutMouseEntry *s;
  176. s = g_new0(QEMUPutMouseEntry, 1);
  177. s->qemu_put_mouse_event = func;
  178. s->qemu_put_mouse_event_opaque = opaque;
  179. s->qemu_put_mouse_event_absolute = absolute;
  180. s->h.name = name;
  181. s->h.mask = INPUT_EVENT_MASK_BTN |
  182. (absolute ? INPUT_EVENT_MASK_ABS : INPUT_EVENT_MASK_REL);
  183. s->h.event = legacy_mouse_event;
  184. s->h.sync = legacy_mouse_sync;
  185. s->s = qemu_input_handler_register((DeviceState *)s,
  186. &s->h);
  187. return s;
  188. }
  189. void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry)
  190. {
  191. qemu_input_handler_activate(entry->s);
  192. }
  193. void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
  194. {
  195. qemu_input_handler_unregister(entry->s);
  196. g_free(entry);
  197. }
  198. QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func,
  199. void *opaque)
  200. {
  201. QEMUPutLEDEntry *s;
  202. s = g_new0(QEMUPutLEDEntry, 1);
  203. s->put_led = func;
  204. s->opaque = opaque;
  205. QTAILQ_INSERT_TAIL(&led_handlers, s, next);
  206. return s;
  207. }
  208. void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
  209. {
  210. if (entry == NULL)
  211. return;
  212. QTAILQ_REMOVE(&led_handlers, entry, next);
  213. g_free(entry);
  214. }
  215. void kbd_put_ledstate(int ledstate)
  216. {
  217. QEMUPutLEDEntry *cursor;
  218. QTAILQ_FOREACH(cursor, &led_handlers, next) {
  219. cursor->put_led(cursor->opaque, ledstate);
  220. }
  221. }