Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu
… into staging

UI queue

- virtio: add virtio-multitouch device
- sdl: various keyboard grab fixes
- gtk: enable multi-touch events
- misc fixes

# -----BEGIN PGP SIGNATURE-----
#
# iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmRzVQAcHG1hcmNhbmRy
# ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5a34D/9+1I9XnecCQk4rZhHI
# Fb1fUei4eLNOdxTZUK2zpOkArWf59VNsEa1LFqIiM+0IlWU3gQmrCLRFOuJrDxiA
# ugq9H23QLs3Z7HEab6/aq+VwUy+o1AXowLZBTrEGmw9SZQnrKeu4/prW0f5wbsTf
# u5ALDkJWo733vkbAplsfWPcOLzp3CoTvA89iw/I9eNVYsm6+vBJ+0cRBr0GCPmiJ
# 2xprhGkie491clNlbR3HmOX/RGFmcj/ClPraLXepaQq1gNCqurIrU7V3J/JcY5W0
# YemXDEgpZ8iVt1OOKGKzTftGZzuhRpxAYvSPwjAp1XeEXB7eJEmjUWoFpyVt1tQZ
# 4y6pQGYdM2XW0sbAkt3w2TIgj/odv7L3IHG3UcsBRefl6Pm43G1FuGWjbulQ1ch0
# YyFAr1xNPkWMYSW1MTb4vuTYFO9OEY08W4n+M6O187RUFiuf+W00OZUDqpp6zjqT
# LKjMktilpUOya1LvWU3D5et9LEXFgSrZj9rQlFsuMe3g24ZNPLypQh/jzSFs9ZsW
# At1nIGGrrZDr8YMFnANBudJbJc0Q1+ce5TB6090XSpNn/YXvu2H+n/ceA4/mA6sy
# MlQBrDmifb9iY6+62MbW8wJtiIy8Zi7A632pw8gbqB0ilkg4DNSBR5O42n1Fmhqp
# gLfxN48NN9Bx6H+zPJbwz2aDQQ==
# =3bPI
# -----END PGP SIGNATURE-----
# gpg: Signature made Sun 28 May 2023 06:20:00 AM PDT
# gpg:                using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5
# gpg:                issuer "marcandre.lureau@redhat.com"
# gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full]
# gpg:                 aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full]

* tag 'ui-pull-request' of https://gitlab.com/marcandre.lureau/qemu:
  ui/gtk: enable backend to send multi-touch events
  ui: add helpers for virtio-multitouch events
  virtio-input-pci: add virtio-multitouch-pci
  virtio-input: add a virtio-mulitouch device
  ui: add the infrastructure to support MT events
  virtio-input: generalize virtio_input_key_config()
  ui/cursor: make width/height unsigned 16-bit integer
  ui/sdl2: disable SDL_HINT_GRAB_KEYBOARD on Windows
  ui/sdl2: Grab Alt+F4 also under Windows
  ui/sdl2: Grab Alt+Tab also in fullscreen mode
  ui/dbus: add a FIXME about texture/dmabuf scanout handling
  gtk: add gl-area support on win32
  virtio-gpu: add a FIXME for virtio_gpu_load()
  win32: wrap socket close() with an exception handler
  ui/dbus: fix compilation when GBM && !OPENGL
  ui/sdl2: fix surface_gl_update_texture: Assertion 'gls' failed
  ui/gtk-egl: fix scaling for cursor position in scanout mode
  ui/gtk: use widget size for cursor motion event
  ui/gtk: fix passing y0_top parameter to scanout

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed May 29, 2023
2 parents ac84b57 + 5a4cb61 commit 57b93c0
Show file tree
Hide file tree
Showing 19 changed files with 442 additions and 60 deletions.
1 change: 1 addition & 0 deletions hw/display/virtio-gpu.c
Expand Up @@ -1289,6 +1289,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
/* load & apply scanout state */
vmstate_load_state(f, &vmstate_virtio_gpu_scanouts, g, 1);
for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
/* FIXME: should take scanout.r.{x,y} into account */
scanout = &g->parent_obj.scanout[i];
if (!scanout->resource_id) {
continue;
Expand Down
156 changes: 136 additions & 20 deletions hw/input/virtio-input-hid.c
Expand Up @@ -16,9 +16,10 @@

#include "standard-headers/linux/input.h"

#define VIRTIO_ID_NAME_KEYBOARD "QEMU Virtio Keyboard"
#define VIRTIO_ID_NAME_MOUSE "QEMU Virtio Mouse"
#define VIRTIO_ID_NAME_TABLET "QEMU Virtio Tablet"
#define VIRTIO_ID_NAME_KEYBOARD "QEMU Virtio Keyboard"
#define VIRTIO_ID_NAME_MOUSE "QEMU Virtio Mouse"
#define VIRTIO_ID_NAME_TABLET "QEMU Virtio Tablet"
#define VIRTIO_ID_NAME_MULTITOUCH "QEMU Virtio MultiTouch"

/* ----------------------------------------------------------------- */

Expand All @@ -30,6 +31,7 @@ static const unsigned short keymap_button[INPUT_BUTTON__MAX] = {
[INPUT_BUTTON_WHEEL_DOWN] = BTN_GEAR_DOWN,
[INPUT_BUTTON_SIDE] = BTN_SIDE,
[INPUT_BUTTON_EXTRA] = BTN_EXTRA,
[INPUT_BUTTON_TOUCH] = BTN_TOUCH,
};

static const unsigned short axismap_rel[INPUT_AXIS__MAX] = {
Expand All @@ -42,32 +44,38 @@ static const unsigned short axismap_abs[INPUT_AXIS__MAX] = {
[INPUT_AXIS_Y] = ABS_Y,
};

static const unsigned short axismap_tch[INPUT_AXIS__MAX] = {
[INPUT_AXIS_X] = ABS_MT_POSITION_X,
[INPUT_AXIS_Y] = ABS_MT_POSITION_Y,
};

/* ----------------------------------------------------------------- */

static void virtio_input_key_config(VirtIOInput *vinput,
const unsigned short *keymap,
size_t mapsize)
static void virtio_input_extend_config(VirtIOInput *vinput,
const unsigned short *map,
size_t mapsize,
uint8_t select, uint8_t subsel)
{
virtio_input_config keys;
virtio_input_config ext;
int i, bit, byte, bmax = 0;

memset(&keys, 0, sizeof(keys));
memset(&ext, 0, sizeof(ext));
for (i = 0; i < mapsize; i++) {
bit = keymap[i];
bit = map[i];
if (!bit) {
continue;
}
byte = bit / 8;
bit = bit % 8;
keys.u.bitmap[byte] |= (1 << bit);
ext.u.bitmap[byte] |= (1 << bit);
if (bmax < byte+1) {
bmax = byte+1;
}
}
keys.select = VIRTIO_INPUT_CFG_EV_BITS;
keys.subsel = EV_KEY;
keys.size = bmax;
virtio_input_add_config(vinput, &keys);
ext.select = select;
ext.subsel = subsel;
ext.size = bmax;
virtio_input_add_config(vinput, &ext);
}

static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
Expand All @@ -80,6 +88,7 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
InputKeyEvent *key;
InputMoveEvent *move;
InputBtnEvent *btn;
InputMultiTouchEvent *mtt;

switch (evt->type) {
case INPUT_EVENT_KIND_KEY:
Expand Down Expand Up @@ -136,6 +145,24 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
event.value = cpu_to_le32(move->value);
virtio_input_send(vinput, &event);
break;
case INPUT_EVENT_KIND_MTT:
mtt = evt->u.mtt.data;
if (mtt->type == INPUT_MULTI_TOUCH_TYPE_DATA) {
event.type = cpu_to_le16(EV_ABS);
event.code = cpu_to_le16(axismap_tch[mtt->axis]);
event.value = cpu_to_le32(mtt->value);
virtio_input_send(vinput, &event);
} else {
event.type = cpu_to_le16(EV_ABS);
event.code = cpu_to_le16(ABS_MT_SLOT);
event.value = cpu_to_le32(mtt->slot);
virtio_input_send(vinput, &event);
event.type = cpu_to_le16(EV_ABS);
event.code = cpu_to_le16(ABS_MT_TRACKING_ID);
event.value = cpu_to_le32(mtt->tracking_id);
virtio_input_send(vinput, &event);
}
break;
default:
/* keep gcc happy */
break;
Expand Down Expand Up @@ -281,8 +308,9 @@ static void virtio_keyboard_init(Object *obj)

vhid->handler = &virtio_keyboard_handler;
virtio_input_init_config(vinput, virtio_keyboard_config);
virtio_input_key_config(vinput, qemu_input_map_qcode_to_linux,
qemu_input_map_qcode_to_linux_len);
virtio_input_extend_config(vinput, qemu_input_map_qcode_to_linux,
qemu_input_map_qcode_to_linux_len,
VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
}

static const TypeInfo virtio_keyboard_info = {
Expand Down Expand Up @@ -373,8 +401,9 @@ static void virtio_mouse_init(Object *obj)
virtio_input_init_config(vinput, vhid->wheel_axis
? virtio_mouse_config_v2
: virtio_mouse_config_v1);
virtio_input_key_config(vinput, keymap_button,
ARRAY_SIZE(keymap_button));
virtio_input_extend_config(vinput, keymap_button,
ARRAY_SIZE(keymap_button),
VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
}

static const TypeInfo virtio_mouse_info = {
Expand Down Expand Up @@ -497,8 +526,9 @@ static void virtio_tablet_init(Object *obj)
virtio_input_init_config(vinput, vhid->wheel_axis
? virtio_tablet_config_v2
: virtio_tablet_config_v1);
virtio_input_key_config(vinput, keymap_button,
ARRAY_SIZE(keymap_button));
virtio_input_extend_config(vinput, keymap_button,
ARRAY_SIZE(keymap_button),
VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
}

static const TypeInfo virtio_tablet_info = {
Expand All @@ -511,12 +541,98 @@ static const TypeInfo virtio_tablet_info = {

/* ----------------------------------------------------------------- */

static QemuInputHandler virtio_multitouch_handler = {
.name = VIRTIO_ID_NAME_MULTITOUCH,
.mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_MTT,
.event = virtio_input_handle_event,
.sync = virtio_input_handle_sync,
};

static struct virtio_input_config virtio_multitouch_config[] = {
{
.select = VIRTIO_INPUT_CFG_ID_NAME,
.size = sizeof(VIRTIO_ID_NAME_MULTITOUCH),
.u.string = VIRTIO_ID_NAME_MULTITOUCH,
},{
.select = VIRTIO_INPUT_CFG_ID_DEVIDS,
.size = sizeof(struct virtio_input_devids),
.u.ids = {
.bustype = const_le16(BUS_VIRTUAL),
.vendor = const_le16(0x0627), /* same we use for usb hid devices */
.product = const_le16(0x0003),
.version = const_le16(0x0001),
},
},{
.select = VIRTIO_INPUT_CFG_ABS_INFO,
.subsel = ABS_MT_SLOT,
.size = sizeof(virtio_input_absinfo),
.u.abs.min = const_le32(INPUT_EVENT_SLOTS_MIN),
.u.abs.max = const_le32(INPUT_EVENT_SLOTS_MAX),
},{
.select = VIRTIO_INPUT_CFG_ABS_INFO,
.subsel = ABS_MT_TRACKING_ID,
.size = sizeof(virtio_input_absinfo),
.u.abs.min = const_le32(INPUT_EVENT_SLOTS_MIN),
.u.abs.max = const_le32(INPUT_EVENT_SLOTS_MAX),
},{
.select = VIRTIO_INPUT_CFG_ABS_INFO,
.subsel = ABS_MT_POSITION_X,
.size = sizeof(virtio_input_absinfo),
.u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
.u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
},{
.select = VIRTIO_INPUT_CFG_ABS_INFO,
.subsel = ABS_MT_POSITION_Y,
.size = sizeof(virtio_input_absinfo),
.u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
.u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
},
{ /* end of list */ },
};

static void virtio_multitouch_init(Object *obj)
{
VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
VirtIOInput *vinput = VIRTIO_INPUT(obj);
unsigned short abs_props[] = {
INPUT_PROP_DIRECT,
};
unsigned short abs_bits[] = {
ABS_MT_SLOT,
ABS_MT_TRACKING_ID,
ABS_MT_POSITION_X,
ABS_MT_POSITION_Y,
};

vhid->handler = &virtio_multitouch_handler;
virtio_input_init_config(vinput, virtio_multitouch_config);
virtio_input_extend_config(vinput, keymap_button,
ARRAY_SIZE(keymap_button),
VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
virtio_input_extend_config(vinput, abs_props,
ARRAY_SIZE(abs_props),
VIRTIO_INPUT_CFG_PROP_BITS, 0);
virtio_input_extend_config(vinput, abs_bits,
ARRAY_SIZE(abs_bits),
VIRTIO_INPUT_CFG_EV_BITS, EV_ABS);
}

static const TypeInfo virtio_multitouch_info = {
.name = TYPE_VIRTIO_MULTITOUCH,
.parent = TYPE_VIRTIO_INPUT_HID,
.instance_size = sizeof(VirtIOInputHID),
.instance_init = virtio_multitouch_init,
};

/* ----------------------------------------------------------------- */

static void virtio_register_types(void)
{
type_register_static(&virtio_input_hid_info);
type_register_static(&virtio_keyboard_info);
type_register_static(&virtio_mouse_info);
type_register_static(&virtio_tablet_info);
type_register_static(&virtio_multitouch_info);
}

type_init(virtio_register_types)
25 changes: 21 additions & 4 deletions hw/virtio/virtio-input-pci.c
Expand Up @@ -25,10 +25,11 @@ struct VirtIOInputPCI {
VirtIOInput vdev;
};

#define TYPE_VIRTIO_INPUT_HID_PCI "virtio-input-hid-pci"
#define TYPE_VIRTIO_KEYBOARD_PCI "virtio-keyboard-pci"
#define TYPE_VIRTIO_MOUSE_PCI "virtio-mouse-pci"
#define TYPE_VIRTIO_TABLET_PCI "virtio-tablet-pci"
#define TYPE_VIRTIO_INPUT_HID_PCI "virtio-input-hid-pci"
#define TYPE_VIRTIO_KEYBOARD_PCI "virtio-keyboard-pci"
#define TYPE_VIRTIO_MOUSE_PCI "virtio-mouse-pci"
#define TYPE_VIRTIO_TABLET_PCI "virtio-tablet-pci"
#define TYPE_VIRTIO_MULTITOUCH_PCI "virtio-multitouch-pci"
OBJECT_DECLARE_SIMPLE_TYPE(VirtIOInputHIDPCI, VIRTIO_INPUT_HID_PCI)

struct VirtIOInputHIDPCI {
Expand Down Expand Up @@ -102,6 +103,14 @@ static void virtio_tablet_initfn(Object *obj)
TYPE_VIRTIO_TABLET);
}

static void virtio_multitouch_initfn(Object *obj)
{
VirtIOInputHIDPCI *dev = VIRTIO_INPUT_HID_PCI(obj);

virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_MULTITOUCH);
}

static const TypeInfo virtio_input_pci_info = {
.name = TYPE_VIRTIO_INPUT_PCI,
.parent = TYPE_VIRTIO_PCI,
Expand Down Expand Up @@ -140,6 +149,13 @@ static const VirtioPCIDeviceTypeInfo virtio_tablet_pci_info = {
.instance_init = virtio_tablet_initfn,
};

static const VirtioPCIDeviceTypeInfo virtio_multitouch_pci_info = {
.generic_name = TYPE_VIRTIO_MULTITOUCH_PCI,
.parent = TYPE_VIRTIO_INPUT_HID_PCI,
.instance_size = sizeof(VirtIOInputHIDPCI),
.instance_init = virtio_multitouch_initfn,
};

static void virtio_pci_input_register(void)
{
/* Base types: */
Expand All @@ -150,6 +166,7 @@ static void virtio_pci_input_register(void)
virtio_pci_types_register(&virtio_keyboard_pci_info);
virtio_pci_types_register(&virtio_mouse_pci_info);
virtio_pci_types_register(&virtio_tablet_pci_info);
virtio_pci_types_register(&virtio_multitouch_pci_info);
}

type_init(virtio_pci_input_register)
9 changes: 5 additions & 4 deletions include/hw/virtio/virtio-input.h
Expand Up @@ -24,10 +24,11 @@ OBJECT_DECLARE_TYPE(VirtIOInput, VirtIOInputClass,
#define VIRTIO_INPUT_GET_PARENT_CLASS(obj) \
OBJECT_GET_PARENT_CLASS(obj, TYPE_VIRTIO_INPUT)

#define TYPE_VIRTIO_INPUT_HID "virtio-input-hid-device"
#define TYPE_VIRTIO_KEYBOARD "virtio-keyboard-device"
#define TYPE_VIRTIO_MOUSE "virtio-mouse-device"
#define TYPE_VIRTIO_TABLET "virtio-tablet-device"
#define TYPE_VIRTIO_INPUT_HID "virtio-input-hid-device"
#define TYPE_VIRTIO_KEYBOARD "virtio-keyboard-device"
#define TYPE_VIRTIO_MOUSE "virtio-mouse-device"
#define TYPE_VIRTIO_TABLET "virtio-tablet-device"
#define TYPE_VIRTIO_MULTITOUCH "virtio-multitouch-device"

OBJECT_DECLARE_SIMPLE_TYPE(VirtIOInputHID, VIRTIO_INPUT_HID)
#define VIRTIO_INPUT_HID_GET_PARENT_CLASS(obj) \
Expand Down
4 changes: 4 additions & 0 deletions include/sysemu/os-win32.h
Expand Up @@ -259,6 +259,10 @@ ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags);
ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *addr, socklen_t *addrlen);

EXCEPTION_DISPOSITION
win32_close_exception_handler(struct _EXCEPTION_RECORD*, void*,
struct _CONTEXT*, void*);

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 2 additions & 2 deletions include/ui/console.h
Expand Up @@ -144,13 +144,13 @@ typedef struct QemuUIInfo {

/* cursor data format is 32bit RGBA */
typedef struct QEMUCursor {
int width, height;
uint16_t width, height;
int hot_x, hot_y;
int refcount;
uint32_t data[];
} QEMUCursor;

QEMUCursor *cursor_alloc(int width, int height);
QEMUCursor *cursor_alloc(uint16_t width, uint16_t height);
QEMUCursor *cursor_ref(QEMUCursor *c);
void cursor_unref(QEMUCursor *c);
QEMUCursor *cursor_builtin_hidden(void);
Expand Down
8 changes: 8 additions & 0 deletions include/ui/input.h
Expand Up @@ -8,9 +8,12 @@
#define INPUT_EVENT_MASK_BTN (1<<INPUT_EVENT_KIND_BTN)
#define INPUT_EVENT_MASK_REL (1<<INPUT_EVENT_KIND_REL)
#define INPUT_EVENT_MASK_ABS (1<<INPUT_EVENT_KIND_ABS)
#define INPUT_EVENT_MASK_MTT (1<<INPUT_EVENT_KIND_MTT)

#define INPUT_EVENT_ABS_MIN 0x0000
#define INPUT_EVENT_ABS_MAX 0x7FFF
#define INPUT_EVENT_SLOTS_MIN 0x0
#define INPUT_EVENT_SLOTS_MAX 0xa

typedef struct QemuInputHandler QemuInputHandler;
typedef struct QemuInputHandlerState QemuInputHandlerState;
Expand Down Expand Up @@ -61,6 +64,11 @@ int qemu_input_scale_axis(int value,
void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value);
void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value,
int min_in, int max_in);
void qemu_input_queue_mtt(QemuConsole *src, InputMultiTouchType type, int slot,
int tracking_id);
void qemu_input_queue_mtt_abs(QemuConsole *src, InputAxis axis, int value,
int min_in, int max_in,
int slot, int tracking_id);

void qemu_input_check_mode_change(void);
void qemu_add_mouse_mode_change_notifier(Notifier *notify);
Expand Down

0 comments on commit 57b93c0

Please sign in to comment.