input: Allow to choose console with qemu_input_is_absolute

Although an input is routed depending on the console,
qemu_input_is_absolute() had no mechanism to specify the console.

Accept QemuConsole as an argument for qemu_input_is_absolute, and let
the display know the absolute/relative state for a particular console.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20230921082936.28100-1-akihiko.odaki@daynix.com>
This commit is contained in:
Akihiko Odaki 2023-09-21 17:29:34 +09:00 committed by Marc-André Lureau
parent 50d0bfd0ed
commit 0337e4123e
9 changed files with 33 additions and 49 deletions

View File

@ -57,7 +57,7 @@ void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down);
void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map, 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(QemuConsole *con);
int qemu_input_scale_axis(int value, int qemu_input_scale_axis(int value,
int min_in, int max_in, int min_in, int max_in,
int min_out, int max_out); int min_out, int max_out);

View File

@ -2001,7 +2001,7 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n"); COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
graphic_hw_update(NULL); graphic_hw_update(NULL);
if (qemu_input_is_absolute()) { if (qemu_input_is_absolute(dcl->con)) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
if (![cocoaView isAbsoluteEnabled]) { if (![cocoaView isAbsoluteEnabled]) {
if ([cocoaView isMouseGrabbed]) { if ([cocoaView isMouseGrabbed]) {

View File

@ -386,7 +386,7 @@ dbus_mouse_rel_motion(DBusDisplayConsole *ddc,
{ {
trace_dbus_mouse_rel_motion(dx, dy); trace_dbus_mouse_rel_motion(dx, dy);
if (qemu_input_is_absolute()) { if (qemu_input_is_absolute(ddc->dcl.con)) {
g_dbus_method_invocation_return_error( g_dbus_method_invocation_return_error(
invocation, DBUS_DISPLAY_ERROR, invocation, DBUS_DISPLAY_ERROR,
DBUS_DISPLAY_ERROR_INVALID, DBUS_DISPLAY_ERROR_INVALID,
@ -453,7 +453,7 @@ dbus_mouse_set_pos(DBusDisplayConsole *ddc,
trace_dbus_mouse_set_pos(x, y); trace_dbus_mouse_set_pos(x, y);
if (!qemu_input_is_absolute()) { if (!qemu_input_is_absolute(ddc->dcl.con)) {
g_dbus_method_invocation_return_error( g_dbus_method_invocation_return_error(
invocation, DBUS_DISPLAY_ERROR, invocation, DBUS_DISPLAY_ERROR,
DBUS_DISPLAY_ERROR_INVALID, DBUS_DISPLAY_ERROR_INVALID,
@ -514,7 +514,7 @@ static void
dbus_mouse_update_is_absolute(DBusDisplayConsole *ddc) dbus_mouse_update_is_absolute(DBusDisplayConsole *ddc)
{ {
g_object_set(ddc->iface_mouse, g_object_set(ddc->iface_mouse,
"is-absolute", qemu_input_is_absolute(), "is-absolute", qemu_input_is_absolute(ddc->dcl.con),
NULL); NULL);
} }

View File

@ -204,7 +204,7 @@ static void gd_update_cursor(VirtualConsole *vc)
} }
window = gtk_widget_get_window(GTK_WIDGET(vc->gfx.drawing_area)); window = gtk_widget_get_window(GTK_WIDGET(vc->gfx.drawing_area));
if (s->full_screen || qemu_input_is_absolute() || s->ptr_owner == vc) { if (s->full_screen || qemu_input_is_absolute(vc->gfx.dcl.con) || s->ptr_owner == vc) {
gdk_window_set_cursor(window, s->null_cursor); gdk_window_set_cursor(window, s->null_cursor);
} else { } else {
gdk_window_set_cursor(window, NULL); gdk_window_set_cursor(window, NULL);
@ -453,7 +453,7 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
gint x_root, y_root; gint x_root, y_root;
if (!gtk_widget_get_realized(vc->gfx.drawing_area) || if (!gtk_widget_get_realized(vc->gfx.drawing_area) ||
qemu_input_is_absolute()) { qemu_input_is_absolute(dcl->con)) {
return; return;
} }
@ -689,7 +689,7 @@ static void gd_mouse_mode_change(Notifier *notify, void *data)
s = container_of(notify, GtkDisplayState, mouse_mode_notifier); s = container_of(notify, GtkDisplayState, mouse_mode_notifier);
/* release the grab at switching to absolute mode */ /* release the grab at switching to absolute mode */
if (qemu_input_is_absolute() && s->ptr_owner) { if (s->ptr_owner && qemu_input_is_absolute(s->ptr_owner->gfx.dcl.con)) {
if (!s->ptr_owner->window) { if (!s->ptr_owner->window) {
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
FALSE); FALSE);
@ -903,7 +903,7 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
x = (motion->x - mx) / vc->gfx.scale_x * ws; x = (motion->x - mx) / vc->gfx.scale_x * ws;
y = (motion->y - my) / vc->gfx.scale_y * ws; y = (motion->y - my) / vc->gfx.scale_y * ws;
if (qemu_input_is_absolute()) { if (qemu_input_is_absolute(vc->gfx.dcl.con)) {
if (x < 0 || y < 0 || if (x < 0 || y < 0 ||
x >= surface_width(vc->gfx.ds) || x >= surface_width(vc->gfx.ds) ||
y >= surface_height(vc->gfx.ds)) { y >= surface_height(vc->gfx.ds)) {
@ -923,7 +923,7 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
s->last_y = y; s->last_y = y;
s->last_set = TRUE; s->last_set = TRUE;
if (!qemu_input_is_absolute() && s->ptr_owner == vc) { if (!qemu_input_is_absolute(vc->gfx.dcl.con) && s->ptr_owner == vc) {
GdkScreen *screen = gtk_widget_get_screen(vc->gfx.drawing_area); GdkScreen *screen = gtk_widget_get_screen(vc->gfx.drawing_area);
GdkDisplay *dpy = gtk_widget_get_display(widget); GdkDisplay *dpy = gtk_widget_get_display(widget);
GdkWindow *win = gtk_widget_get_window(widget); GdkWindow *win = gtk_widget_get_window(widget);
@ -965,7 +965,7 @@ static gboolean gd_button_event(GtkWidget *widget, GdkEventButton *button,
/* implicitly grab the input at the first click in the relative mode */ /* implicitly grab the input at the first click in the relative mode */
if (button->button == 1 && button->type == GDK_BUTTON_PRESS && if (button->button == 1 && button->type == GDK_BUTTON_PRESS &&
!qemu_input_is_absolute() && s->ptr_owner != vc) { !qemu_input_is_absolute(vc->gfx.dcl.con) && s->ptr_owner != vc) {
if (!vc->window) { if (!vc->window) {
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
TRUE); TRUE);

View File

@ -56,7 +56,7 @@ QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev,
s->id = id++; s->id = id++;
QTAILQ_INSERT_TAIL(&handlers, s, node); QTAILQ_INSERT_TAIL(&handlers, s, node);
qemu_input_check_mode_change(); notifier_list_notify(&mouse_mode_notifiers, NULL);
return s; return s;
} }
@ -64,21 +64,21 @@ void qemu_input_handler_activate(QemuInputHandlerState *s)
{ {
QTAILQ_REMOVE(&handlers, s, node); QTAILQ_REMOVE(&handlers, s, node);
QTAILQ_INSERT_HEAD(&handlers, s, node); QTAILQ_INSERT_HEAD(&handlers, s, node);
qemu_input_check_mode_change(); notifier_list_notify(&mouse_mode_notifiers, NULL);
} }
void qemu_input_handler_deactivate(QemuInputHandlerState *s) void qemu_input_handler_deactivate(QemuInputHandlerState *s)
{ {
QTAILQ_REMOVE(&handlers, s, node); QTAILQ_REMOVE(&handlers, s, node);
QTAILQ_INSERT_TAIL(&handlers, s, node); QTAILQ_INSERT_TAIL(&handlers, s, node);
qemu_input_check_mode_change(); notifier_list_notify(&mouse_mode_notifiers, NULL);
} }
void qemu_input_handler_unregister(QemuInputHandlerState *s) void qemu_input_handler_unregister(QemuInputHandlerState *s)
{ {
QTAILQ_REMOVE(&handlers, s, node); QTAILQ_REMOVE(&handlers, s, node);
g_free(s); g_free(s);
qemu_input_check_mode_change(); notifier_list_notify(&mouse_mode_notifiers, NULL);
} }
void qemu_input_handler_bind(QemuInputHandlerState *s, void qemu_input_handler_bind(QemuInputHandlerState *s,
@ -494,12 +494,12 @@ void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map,
} }
} }
bool qemu_input_is_absolute(void) bool qemu_input_is_absolute(QemuConsole *con)
{ {
QemuInputHandlerState *s; QemuInputHandlerState *s;
s = qemu_input_find_handler(INPUT_EVENT_MASK_REL | INPUT_EVENT_MASK_ABS, s = qemu_input_find_handler(INPUT_EVENT_MASK_REL | INPUT_EVENT_MASK_ABS,
NULL); con);
return (s != NULL) && (s->handler->mask & INPUT_EVENT_MASK_ABS); return (s != NULL) && (s->handler->mask & INPUT_EVENT_MASK_ABS);
} }
@ -583,21 +583,6 @@ void qemu_input_queue_mtt_abs(QemuConsole *src, InputAxis axis, int value,
qemu_input_event_send(src, &evt); qemu_input_event_send(src, &evt);
} }
void qemu_input_check_mode_change(void)
{
static int current_is_absolute;
int is_absolute;
is_absolute = qemu_input_is_absolute();
if (is_absolute != current_is_absolute) {
trace_input_mouse_mode(is_absolute);
notifier_list_notify(&mouse_mode_notifiers, NULL);
}
current_is_absolute = is_absolute;
}
void qemu_add_mouse_mode_change_notifier(Notifier *notify) void qemu_add_mouse_mode_change_notifier(Notifier *notify)
{ {
notifier_list_add(&mouse_mode_notifiers, notify); notifier_list_add(&mouse_mode_notifiers, notify);
@ -657,6 +642,6 @@ bool qemu_mouse_set(int index, Error **errp)
} }
qemu_input_handler_activate(s); qemu_input_handler_activate(s);
qemu_input_check_mode_change(); notifier_list_notify(&mouse_mode_notifiers, NULL);
return true; return true;
} }

View File

@ -203,7 +203,7 @@ static void sdl_hide_cursor(struct sdl2_console *scon)
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
SDL_SetCursor(sdl_cursor_hidden); SDL_SetCursor(sdl_cursor_hidden);
if (!qemu_input_is_absolute()) { if (!qemu_input_is_absolute(scon->dcl.con)) {
SDL_SetRelativeMouseMode(SDL_TRUE); SDL_SetRelativeMouseMode(SDL_TRUE);
} }
} }
@ -214,12 +214,12 @@ static void sdl_show_cursor(struct sdl2_console *scon)
return; return;
} }
if (!qemu_input_is_absolute()) { if (!qemu_input_is_absolute(scon->dcl.con)) {
SDL_SetRelativeMouseMode(SDL_FALSE); SDL_SetRelativeMouseMode(SDL_FALSE);
} }
if (guest_cursor && if (guest_cursor &&
(gui_grab || qemu_input_is_absolute() || absolute_enabled)) { (gui_grab || qemu_input_is_absolute(scon->dcl.con) || absolute_enabled)) {
SDL_SetCursor(guest_sprite); SDL_SetCursor(guest_sprite);
} else { } else {
SDL_SetCursor(sdl_cursor_normal); SDL_SetCursor(sdl_cursor_normal);
@ -245,7 +245,7 @@ static void sdl_grab_start(struct sdl2_console *scon)
} }
if (guest_cursor) { if (guest_cursor) {
SDL_SetCursor(guest_sprite); SDL_SetCursor(guest_sprite);
if (!qemu_input_is_absolute() && !absolute_enabled) { if (!qemu_input_is_absolute(scon->dcl.con) && !absolute_enabled) {
SDL_WarpMouseInWindow(scon->real_window, guest_x, guest_y); SDL_WarpMouseInWindow(scon->real_window, guest_x, guest_y);
} }
} else { } else {
@ -280,7 +280,7 @@ static void absolute_mouse_grab(struct sdl2_console *scon)
static void sdl_mouse_mode_change(Notifier *notify, void *data) static void sdl_mouse_mode_change(Notifier *notify, void *data)
{ {
if (qemu_input_is_absolute()) { if (qemu_input_is_absolute(sdl2_console[0].dcl.con)) {
if (!absolute_enabled) { if (!absolute_enabled) {
absolute_enabled = 1; absolute_enabled = 1;
SDL_SetRelativeMouseMode(SDL_FALSE); SDL_SetRelativeMouseMode(SDL_FALSE);
@ -311,7 +311,7 @@ static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
prev_state = state; prev_state = state;
} }
if (qemu_input_is_absolute()) { if (qemu_input_is_absolute(scon->dcl.con)) {
qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X,
x, 0, surface_width(scon->surface)); x, 0, surface_width(scon->surface));
qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y,
@ -497,7 +497,7 @@ static void handle_mousemotion(SDL_Event *ev)
return; return;
} }
if (qemu_input_is_absolute() || absolute_enabled) { if (qemu_input_is_absolute(scon->dcl.con) || absolute_enabled) {
int scr_w, scr_h; int scr_w, scr_h;
SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h); SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);
max_x = scr_w - 1; max_x = scr_w - 1;
@ -513,7 +513,7 @@ static void handle_mousemotion(SDL_Event *ev)
sdl_grab_start(scon); sdl_grab_start(scon);
} }
} }
if (gui_grab || qemu_input_is_absolute() || absolute_enabled) { if (gui_grab || qemu_input_is_absolute(scon->dcl.con) || absolute_enabled) {
sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel, sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel,
ev->motion.x, ev->motion.y, ev->motion.state); ev->motion.x, ev->motion.y, ev->motion.state);
} }
@ -530,7 +530,7 @@ static void handle_mousebutton(SDL_Event *ev)
} }
bev = &ev->button; bev = &ev->button;
if (!gui_grab && !qemu_input_is_absolute()) { if (!gui_grab && !qemu_input_is_absolute(scon->dcl.con)) {
if (ev->type == SDL_MOUSEBUTTONUP && bev->button == SDL_BUTTON_LEFT) { if (ev->type == SDL_MOUSEBUTTONUP && bev->button == SDL_BUTTON_LEFT) {
/* start grabbing all events */ /* start grabbing all events */
sdl_grab_start(scon); sdl_grab_start(scon);
@ -603,7 +603,7 @@ static void handle_windowevent(SDL_Event *ev)
} }
/* fall through */ /* fall through */
case SDL_WINDOWEVENT_ENTER: case SDL_WINDOWEVENT_ENTER:
if (!gui_grab && (qemu_input_is_absolute() || absolute_enabled)) { if (!gui_grab && (qemu_input_is_absolute(scon->dcl.con) || absolute_enabled)) {
absolute_mouse_grab(scon); absolute_mouse_grab(scon);
} }
/* If a new console window opened using a hotkey receives the /* If a new console window opened using a hotkey receives the
@ -733,9 +733,9 @@ static void sdl_mouse_warp(DisplayChangeListener *dcl,
if (!guest_cursor) { if (!guest_cursor) {
sdl_show_cursor(scon); sdl_show_cursor(scon);
} }
if (gui_grab || qemu_input_is_absolute() || absolute_enabled) { if (gui_grab || qemu_input_is_absolute(scon->dcl.con) || absolute_enabled) {
SDL_SetCursor(guest_sprite); SDL_SetCursor(guest_sprite);
if (!qemu_input_is_absolute() && !absolute_enabled) { if (!qemu_input_is_absolute(scon->dcl.con) && !absolute_enabled) {
SDL_WarpMouseInWindow(scon->real_window, x, y); SDL_WarpMouseInWindow(scon->real_window, x, y);
} }
} }
@ -773,7 +773,7 @@ static void sdl_mouse_define(DisplayChangeListener *dcl,
return; return;
} }
if (guest_cursor && if (guest_cursor &&
(gui_grab || qemu_input_is_absolute() || absolute_enabled)) { (gui_grab || qemu_input_is_absolute(dcl->con) || absolute_enabled)) {
SDL_SetCursor(guest_sprite); SDL_SetCursor(guest_sprite);
} }
} }

View File

@ -224,7 +224,7 @@ static const SpiceTabletInterface tablet_interface = {
static void mouse_mode_notifier(Notifier *notifier, void *data) static void mouse_mode_notifier(Notifier *notifier, void *data)
{ {
QemuSpicePointer *pointer = container_of(notifier, QemuSpicePointer, mouse_mode); QemuSpicePointer *pointer = container_of(notifier, QemuSpicePointer, mouse_mode);
bool is_absolute = qemu_input_is_absolute(); bool is_absolute = qemu_input_is_absolute(NULL);
if (pointer->absolute == is_absolute) { if (pointer->absolute == is_absolute) {
return; return;

View File

@ -92,7 +92,6 @@ input_event_rel(int conidx, const char *axis, int value) "con %d, axis %s, value
input_event_abs(int conidx, const char *axis, int value) "con %d, axis %s, value 0x%x" input_event_abs(int conidx, const char *axis, int value) "con %d, axis %s, value 0x%x"
input_event_mtt(int conidx, const char *axis, int value) "con %d, axis %s, value 0x%x" input_event_mtt(int conidx, const char *axis, int value) "con %d, axis %s, value 0x%x"
input_event_sync(void) "" input_event_sync(void) ""
input_mouse_mode(int absolute) "absolute %d"
# sdl2-input.c # sdl2-input.c
sdl2_process_key(int sdl_scancode, int qcode, const char *action) "translated SDL scancode %d to QKeyCode %d (%s)" sdl2_process_key(int sdl_scancode, int qcode, const char *action) "translated SDL scancode %d to QKeyCode %d (%s)"

View File

@ -1771,7 +1771,7 @@ uint32_t read_u32(uint8_t *data, size_t offset)
static void check_pointer_type_change(Notifier *notifier, void *data) static void check_pointer_type_change(Notifier *notifier, void *data)
{ {
VncState *vs = container_of(notifier, VncState, mouse_mode_notifier); VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
int absolute = qemu_input_is_absolute(); int absolute = qemu_input_is_absolute(vs->vd->dcl.con);
if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) { if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
vnc_lock_output(vs); vnc_lock_output(vs);