123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- /*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
- #include "qemu/osdep.h"
- #include "qemu/log.h"
- #include "qapi/qapi-commands-ui.h"
- #include "ui/console.h"
- #include "keymaps.h"
- #include "ui/input.h"
- struct QEMUPutMouseEntry {
- QEMUPutMouseEvent *qemu_put_mouse_event;
- void *qemu_put_mouse_event_opaque;
- int qemu_put_mouse_event_absolute;
- /* new input core */
- QemuInputHandler h;
- QemuInputHandlerState *s;
- int axis[INPUT_AXIS__MAX];
- int buttons;
- };
- struct QEMUPutKbdEntry {
- QEMUPutKBDEvent *put_kbd;
- void *opaque;
- QemuInputHandlerState *s;
- };
- struct QEMUPutLEDEntry {
- QEMUPutLEDEvent *put_led;
- void *opaque;
- QTAILQ_ENTRY(QEMUPutLEDEntry) next;
- };
- static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers =
- QTAILQ_HEAD_INITIALIZER(led_handlers);
- int index_from_key(const char *key, size_t key_length)
- {
- int i;
- for (i = 0; i < Q_KEY_CODE__MAX; i++) {
- if (!strncmp(key, QKeyCode_str(i), key_length) &&
- !QKeyCode_str(i)[key_length]) {
- break;
- }
- }
- /* Return Q_KEY_CODE__MAX if the key is invalid */
- return i;
- }
- static KeyValue *copy_key_value(KeyValue *src)
- {
- KeyValue *dst = g_new(KeyValue, 1);
- memcpy(dst, src, sizeof(*src));
- if (dst->type == KEY_VALUE_KIND_NUMBER) {
- QKeyCode code = qemu_input_key_number_to_qcode(dst->u.number.data);
- dst->type = KEY_VALUE_KIND_QCODE;
- dst->u.qcode.data = code;
- }
- return dst;
- }
- void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
- Error **errp)
- {
- KeyValueList *p;
- KeyValue **up = NULL;
- int count = 0;
- if (!has_hold_time) {
- hold_time = 0; /* use default */
- }
- for (p = keys; p != NULL; p = p->next) {
- qemu_input_event_send_key(NULL, copy_key_value(p->value), true);
- qemu_input_event_send_key_delay(hold_time);
- up = g_realloc(up, sizeof(*up) * (count+1));
- up[count] = copy_key_value(p->value);
- count++;
- }
- while (count) {
- count--;
- qemu_input_event_send_key(NULL, up[count], false);
- qemu_input_event_send_key_delay(hold_time);
- }
- g_free(up);
- }
- static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
- InputEvent *evt)
- {
- static const int bmap[INPUT_BUTTON__MAX] = {
- [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
- [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
- [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
- };
- QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
- InputBtnEvent *btn;
- InputMoveEvent *move;
- switch (evt->type) {
- case INPUT_EVENT_KIND_BTN:
- btn = evt->u.btn.data;
- if (btn->down) {
- s->buttons |= bmap[btn->button];
- } else {
- s->buttons &= ~bmap[btn->button];
- }
- if (btn->down && btn->button == INPUT_BUTTON_WHEEL_UP) {
- s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
- s->axis[INPUT_AXIS_X],
- s->axis[INPUT_AXIS_Y],
- -1,
- s->buttons);
- }
- if (btn->down && btn->button == INPUT_BUTTON_WHEEL_DOWN) {
- s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
- s->axis[INPUT_AXIS_X],
- s->axis[INPUT_AXIS_Y],
- 1,
- s->buttons);
- }
- if (btn->down && btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
- s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
- s->axis[INPUT_AXIS_X],
- s->axis[INPUT_AXIS_Y],
- -2,
- s->buttons);
- }
- if (btn->down && btn->button == INPUT_BUTTON_WHEEL_LEFT) {
- s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
- s->axis[INPUT_AXIS_X],
- s->axis[INPUT_AXIS_Y],
- 2,
- s->buttons);
- }
- break;
- case INPUT_EVENT_KIND_ABS:
- move = evt->u.abs.data;
- s->axis[move->axis] = move->value;
- break;
- case INPUT_EVENT_KIND_REL:
- move = evt->u.rel.data;
- s->axis[move->axis] += move->value;
- break;
- default:
- break;
- }
- }
- static void legacy_mouse_sync(DeviceState *dev)
- {
- QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
- s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
- s->axis[INPUT_AXIS_X],
- s->axis[INPUT_AXIS_Y],
- 0,
- s->buttons);
- if (!s->qemu_put_mouse_event_absolute) {
- s->axis[INPUT_AXIS_X] = 0;
- s->axis[INPUT_AXIS_Y] = 0;
- }
- }
- QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
- void *opaque, int absolute,
- const char *name)
- {
- QEMUPutMouseEntry *s;
- s = g_new0(QEMUPutMouseEntry, 1);
- s->qemu_put_mouse_event = func;
- s->qemu_put_mouse_event_opaque = opaque;
- s->qemu_put_mouse_event_absolute = absolute;
- s->h.name = name;
- s->h.mask = INPUT_EVENT_MASK_BTN |
- (absolute ? INPUT_EVENT_MASK_ABS : INPUT_EVENT_MASK_REL);
- s->h.event = legacy_mouse_event;
- s->h.sync = legacy_mouse_sync;
- s->s = qemu_input_handler_register((DeviceState *)s,
- &s->h);
- return s;
- }
- void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry)
- {
- qemu_input_handler_activate(entry->s);
- }
- void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
- {
- qemu_input_handler_unregister(entry->s);
- g_free(entry);
- }
- QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func,
- void *opaque)
- {
- QEMUPutLEDEntry *s;
- s = g_new0(QEMUPutLEDEntry, 1);
- s->put_led = func;
- s->opaque = opaque;
- QTAILQ_INSERT_TAIL(&led_handlers, s, next);
- return s;
- }
- void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
- {
- if (entry == NULL)
- return;
- QTAILQ_REMOVE(&led_handlers, entry, next);
- g_free(entry);
- }
- void kbd_put_ledstate(int ledstate)
- {
- QEMUPutLEDEntry *cursor;
- QTAILQ_FOREACH(cursor, &led_handlers, next) {
- cursor->put_led(cursor->opaque, ledstate);
- }
- }
|