mirror of https://github.com/xemu-project/xemu.git
ui: Support non-zero minimum values for absolute input axes
This patch refactors ui/input.c to support absolute axis minimum values other than 0. All dependent calls to qemu_input_queue_abs have been updated to explicitly supply 0 as the axis minimum value. Signed-off-by: Philippe Voinov <philippevoinov@gmail.com> Message-id: 20170505133952.29885-1-philippevoinov@gmail.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
76d20ea0f1
commit
9cfa7ab939
|
@ -484,12 +484,14 @@ static struct virtio_input_config virtio_tablet_config[] = {
|
||||||
.select = VIRTIO_INPUT_CFG_ABS_INFO,
|
.select = VIRTIO_INPUT_CFG_ABS_INFO,
|
||||||
.subsel = ABS_X,
|
.subsel = ABS_X,
|
||||||
.size = sizeof(virtio_input_absinfo),
|
.size = sizeof(virtio_input_absinfo),
|
||||||
.u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
|
.u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
|
||||||
|
.u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
|
||||||
},{
|
},{
|
||||||
.select = VIRTIO_INPUT_CFG_ABS_INFO,
|
.select = VIRTIO_INPUT_CFG_ABS_INFO,
|
||||||
.subsel = ABS_Y,
|
.subsel = ABS_Y,
|
||||||
.size = sizeof(virtio_input_absinfo),
|
.size = sizeof(virtio_input_absinfo),
|
||||||
.u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE - 1),
|
.u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
|
||||||
|
.u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
|
||||||
},
|
},
|
||||||
{ /* end of list */ },
|
{ /* end of list */ },
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
#define INPUT_EVENT_MASK_REL (1<<INPUT_EVENT_KIND_REL)
|
#define INPUT_EVENT_MASK_REL (1<<INPUT_EVENT_KIND_REL)
|
||||||
#define INPUT_EVENT_MASK_ABS (1<<INPUT_EVENT_KIND_ABS)
|
#define INPUT_EVENT_MASK_ABS (1<<INPUT_EVENT_KIND_ABS)
|
||||||
|
|
||||||
#define INPUT_EVENT_ABS_SIZE 0x8000
|
#define INPUT_EVENT_ABS_MIN 0x0000
|
||||||
|
#define INPUT_EVENT_ABS_MAX 0x7FFF
|
||||||
|
|
||||||
typedef struct QemuInputHandler QemuInputHandler;
|
typedef struct QemuInputHandler QemuInputHandler;
|
||||||
typedef struct QemuInputHandlerState QemuInputHandlerState;
|
typedef struct QemuInputHandlerState QemuInputHandlerState;
|
||||||
|
@ -54,12 +55,14 @@ void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map,
|
||||||
uint32_t button_old, uint32_t button_new);
|
uint32_t button_old, uint32_t button_new);
|
||||||
|
|
||||||
bool qemu_input_is_absolute(void);
|
bool qemu_input_is_absolute(void);
|
||||||
int qemu_input_scale_axis(int value, int size_in, int size_out);
|
int qemu_input_scale_axis(int value,
|
||||||
|
int min_in, int max_in,
|
||||||
|
int min_out, int max_out);
|
||||||
InputEvent *qemu_input_event_new_move(InputEventKind kind,
|
InputEvent *qemu_input_event_new_move(InputEventKind kind,
|
||||||
InputAxis axis, int value);
|
InputAxis axis, int value);
|
||||||
void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value);
|
void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value);
|
||||||
void qemu_input_queue_abs(QemuConsole *src, InputAxis axis,
|
void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value,
|
||||||
int value, int size);
|
int min_in, int max_in);
|
||||||
|
|
||||||
void qemu_input_check_mode_change(void);
|
void qemu_input_check_mode_change(void);
|
||||||
void qemu_add_mouse_mode_change_notifier(Notifier *notify);
|
void qemu_add_mouse_mode_change_notifier(Notifier *notify);
|
||||||
|
|
|
@ -749,8 +749,8 @@ QemuCocoaView *cocoaView;
|
||||||
* clicks in the titlebar.
|
* clicks in the titlebar.
|
||||||
*/
|
*/
|
||||||
if ([self screenContainsPoint:p]) {
|
if ([self screenContainsPoint:p]) {
|
||||||
qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, screen.width);
|
qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, 0, screen.width);
|
||||||
qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height - p.y, screen.height);
|
qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height - p.y, 0, screen.height);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, (int)[event deltaX]);
|
qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, (int)[event deltaX]);
|
||||||
|
|
4
ui/gtk.c
4
ui/gtk.c
|
@ -912,9 +912,9 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_X, x,
|
qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_X, x,
|
||||||
surface_width(vc->gfx.ds));
|
0, surface_width(vc->gfx.ds));
|
||||||
qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_Y, y,
|
qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_Y, y,
|
||||||
surface_height(vc->gfx.ds));
|
0, surface_height(vc->gfx.ds));
|
||||||
qemu_input_event_sync();
|
qemu_input_event_sync();
|
||||||
} else if (s->last_set && s->ptr_owner == vc) {
|
} else if (s->last_set && s->ptr_owner == vc) {
|
||||||
qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_X, x - s->last_x);
|
qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_X, x - s->last_x);
|
||||||
|
|
31
ui/input.c
31
ui/input.c
|
@ -166,6 +166,11 @@ void qmp_input_send_event(bool has_device, const char *device,
|
||||||
qemu_input_event_sync();
|
qemu_input_event_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int qemu_input_transform_invert_abs_value(int value)
|
||||||
|
{
|
||||||
|
return (int64_t)INPUT_EVENT_ABS_MAX - value + INPUT_EVENT_ABS_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
static void qemu_input_transform_abs_rotate(InputEvent *evt)
|
static void qemu_input_transform_abs_rotate(InputEvent *evt)
|
||||||
{
|
{
|
||||||
InputMoveEvent *move = evt->u.abs.data;
|
InputMoveEvent *move = evt->u.abs.data;
|
||||||
|
@ -175,16 +180,16 @@ static void qemu_input_transform_abs_rotate(InputEvent *evt)
|
||||||
move->axis = INPUT_AXIS_Y;
|
move->axis = INPUT_AXIS_Y;
|
||||||
} else if (move->axis == INPUT_AXIS_Y) {
|
} else if (move->axis == INPUT_AXIS_Y) {
|
||||||
move->axis = INPUT_AXIS_X;
|
move->axis = INPUT_AXIS_X;
|
||||||
move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
|
move->value = qemu_input_transform_invert_abs_value(move->value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 180:
|
case 180:
|
||||||
move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
|
move->value = qemu_input_transform_invert_abs_value(move->value);
|
||||||
break;
|
break;
|
||||||
case 270:
|
case 270:
|
||||||
if (move->axis == INPUT_AXIS_X) {
|
if (move->axis == INPUT_AXIS_X) {
|
||||||
move->axis = INPUT_AXIS_Y;
|
move->axis = INPUT_AXIS_Y;
|
||||||
move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
|
move->value = qemu_input_transform_invert_abs_value(move->value);
|
||||||
} else if (move->axis == INPUT_AXIS_Y) {
|
} else if (move->axis == INPUT_AXIS_Y) {
|
||||||
move->axis = INPUT_AXIS_X;
|
move->axis = INPUT_AXIS_X;
|
||||||
}
|
}
|
||||||
|
@ -467,12 +472,17 @@ bool qemu_input_is_absolute(void)
|
||||||
return (s != NULL) && (s->handler->mask & INPUT_EVENT_MASK_ABS);
|
return (s != NULL) && (s->handler->mask & INPUT_EVENT_MASK_ABS);
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemu_input_scale_axis(int value, int size_in, int size_out)
|
int qemu_input_scale_axis(int value,
|
||||||
|
int min_in, int max_in,
|
||||||
|
int min_out, int max_out)
|
||||||
{
|
{
|
||||||
if (size_in < 2) {
|
int64_t range_in = (int64_t)max_in - min_in;
|
||||||
return size_out / 2;
|
int64_t range_out = (int64_t)max_out - min_out;
|
||||||
|
|
||||||
|
if (range_in < 1) {
|
||||||
|
return min_out + range_out / 2;
|
||||||
}
|
}
|
||||||
return (int64_t)value * (size_out - 1) / (size_in - 1);
|
return ((int64_t)value - min_in) * range_out / range_in + min_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputEvent *qemu_input_event_new_move(InputEventKind kind,
|
InputEvent *qemu_input_event_new_move(InputEventKind kind,
|
||||||
|
@ -496,10 +506,13 @@ void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value)
|
||||||
qapi_free_InputEvent(evt);
|
qapi_free_InputEvent(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, int size)
|
void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value,
|
||||||
|
int min_in, int max_in)
|
||||||
{
|
{
|
||||||
InputEvent *evt;
|
InputEvent *evt;
|
||||||
int scaled = qemu_input_scale_axis(value, size, INPUT_EVENT_ABS_SIZE);
|
int scaled = qemu_input_scale_axis(value, min_in, max_in,
|
||||||
|
INPUT_EVENT_ABS_MIN,
|
||||||
|
INPUT_EVENT_ABS_MAX);
|
||||||
evt = qemu_input_event_new_move(INPUT_EVENT_KIND_ABS, axis, scaled);
|
evt = qemu_input_event_new_move(INPUT_EVENT_KIND_ABS, axis, scaled);
|
||||||
qemu_input_event_send(src, evt);
|
qemu_input_event_send(src, evt);
|
||||||
qapi_free_InputEvent(evt);
|
qapi_free_InputEvent(evt);
|
||||||
|
|
4
ui/sdl.c
4
ui/sdl.c
|
@ -490,9 +490,9 @@ static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state)
|
||||||
|
|
||||||
if (qemu_input_is_absolute()) {
|
if (qemu_input_is_absolute()) {
|
||||||
qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, x,
|
qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, x,
|
||||||
real_screen->w);
|
0, real_screen->w);
|
||||||
qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, y,
|
qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, y,
|
||||||
real_screen->h);
|
0, real_screen->h);
|
||||||
} else {
|
} else {
|
||||||
if (guest_cursor) {
|
if (guest_cursor) {
|
||||||
x -= guest_x;
|
x -= guest_x;
|
||||||
|
|
|
@ -298,8 +298,8 @@ static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, off_x + x, max_w);
|
qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, off_x + x, 0, max_w);
|
||||||
qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, off_y + y, max_h);
|
qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, off_y + y, 0, max_h);
|
||||||
} else {
|
} else {
|
||||||
if (guest_cursor) {
|
if (guest_cursor) {
|
||||||
x -= guest_x;
|
x -= guest_x;
|
||||||
|
|
|
@ -172,8 +172,8 @@ static void tablet_position(SpiceTabletInstance* sin, int x, int y,
|
||||||
QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
|
QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
|
||||||
|
|
||||||
spice_update_buttons(pointer, 0, buttons_state);
|
spice_update_buttons(pointer, 0, buttons_state);
|
||||||
qemu_input_queue_abs(NULL, INPUT_AXIS_X, x, pointer->width);
|
qemu_input_queue_abs(NULL, INPUT_AXIS_X, x, 0, pointer->width);
|
||||||
qemu_input_queue_abs(NULL, INPUT_AXIS_Y, y, pointer->height);
|
qemu_input_queue_abs(NULL, INPUT_AXIS_Y, y, 0, pointer->height);
|
||||||
qemu_input_event_sync();
|
qemu_input_event_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
ui/vnc.c
4
ui/vnc.c
|
@ -1556,8 +1556,8 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vs->absolute) {
|
if (vs->absolute) {
|
||||||
qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
|
qemu_input_queue_abs(con, INPUT_AXIS_X, x, 0, width);
|
||||||
qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
|
qemu_input_queue_abs(con, INPUT_AXIS_Y, y, 0, height);
|
||||||
} else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
|
} else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
|
||||||
qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
|
qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
|
||||||
qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
|
qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
|
||||||
|
|
Loading…
Reference in New Issue