diff options
| -rw-r--r-- | balloon.c | 1 | ||||
| -rw-r--r-- | hmp-commands.hx | 3 | ||||
| -rw-r--r-- | hw/virtio/virtio-balloon.c | 2 | ||||
| -rw-r--r-- | include/ui/console.h | 1 | ||||
| -rw-r--r-- | include/ui/qemu-pixman.h | 2 | ||||
| -rw-r--r-- | include/ui/qemu-spice.h | 7 | ||||
| -rw-r--r-- | include/ui/spice-display.h | 3 | ||||
| -rw-r--r-- | monitor.c | 28 | ||||
| -rw-r--r-- | qmp-commands.hx | 7 | ||||
| -rw-r--r-- | scripts/qapi-visit.py | 22 | ||||
| -rw-r--r-- | ui/console.c | 15 | ||||
| -rw-r--r-- | ui/gtk.c | 160 | ||||
| -rw-r--r-- | ui/spice-core.c | 26 | ||||
| -rw-r--r-- | ui/spice-display.c | 23 |
14 files changed, 184 insertions, 116 deletions
diff --git a/balloon.c b/balloon.c index 70c00f5f84..c7033e3dc3 100644 --- a/balloon.c +++ b/balloon.c @@ -58,7 +58,6 @@ int qemu_add_balloon_handler(QEMUBalloonEvent *event_func, /* We're already registered one balloon handler. How many can * a guest really have? */ - error_report("Another balloon device already registered"); return -1; } balloon_event_fn = event_func; diff --git a/hmp-commands.hx b/hmp-commands.hx index 3089533a4f..a6de819f69 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -998,8 +998,7 @@ ETEXI .params = "protocol hostname port tls-port cert-subject", .help = "send migration info to spice/vnc client", .user_print = monitor_user_noop, - .mhandler.cmd_async = client_migrate_info, - .flags = MONITOR_CMD_ASYNC, + .mhandler.cmd_new = client_migrate_info, }, STEXI diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 95b0643448..484c3c333c 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -383,7 +383,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) virtio_balloon_stat, s); if (ret < 0) { - error_setg(errp, "Adding balloon handler failed"); + error_setg(errp, "Only one balloon device is supported"); virtio_cleanup(vdev); return; } diff --git a/include/ui/console.h b/include/ui/console.h index 2f5b9f0634..03cd665a8f 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -307,6 +307,7 @@ QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head); bool qemu_console_is_visible(QemuConsole *con); bool qemu_console_is_graphic(QemuConsole *con); bool qemu_console_is_fixedsize(QemuConsole *con); +char *qemu_console_get_label(QemuConsole *con); int qemu_console_get_index(QemuConsole *con); uint32_t qemu_console_get_head(QemuConsole *con); QemuUIInfo *qemu_console_get_ui_info(QemuConsole *con); diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h index 5d7a9ac6f2..e34c4effcb 100644 --- a/include/ui/qemu-pixman.h +++ b/include/ui/qemu-pixman.h @@ -35,6 +35,7 @@ # define PIXMAN_BE_r8g8b8a8 PIXMAN_r8g8b8a8 # define PIXMAN_BE_x8b8g8r8 PIXMAN_x8b8g8r8 # define PIXMAN_BE_a8b8g8r8 PIXMAN_a8b8g8r8 +# define PIXMAN_LE_x8r8g8b8 PIXMAN_b8g8r8x8 #else # define PIXMAN_BE_r8g8b8 PIXMAN_b8g8r8 # define PIXMAN_BE_x8r8g8b8 PIXMAN_b8g8r8x8 @@ -45,6 +46,7 @@ # define PIXMAN_BE_r8g8b8a8 PIXMAN_a8b8g8r8 # define PIXMAN_BE_x8b8g8r8 PIXMAN_r8g8b8x8 # define PIXMAN_BE_a8b8g8r8 PIXMAN_r8g8b8a8 +# define PIXMAN_LE_x8r8g8b8 PIXMAN_x8r8g8b8 #endif /* -------------------------------------------------------------------- */ diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h index 25b94c7530..42db3c1645 100644 --- a/include/ui/qemu-spice.h +++ b/include/ui/qemu-spice.h @@ -42,8 +42,7 @@ int qemu_spice_set_passwd(const char *passwd, bool fail_if_connected, bool disconnect_if_connected); int qemu_spice_set_pw_expire(time_t expires); int qemu_spice_migrate_info(const char *hostname, int port, int tls_port, - const char *subject, - MonitorCompletion cb, void *opaque); + const char *subject); CharDriverState *qemu_chr_open_spice_vmc(const char *type); #if SPICE_SERVER_VERSION >= 0x000c02 @@ -70,10 +69,8 @@ static inline int qemu_spice_set_pw_expire(time_t expires) return -1; } static inline int qemu_spice_migrate_info(const char *h, int p, int t, - const char *s, - MonitorCompletion cb, void *opaque) + const char *s) { - cb(opaque, NULL); return -1; } diff --git a/include/ui/spice-display.h b/include/ui/spice-display.h index 53883a17fc..b25328a6ba 100644 --- a/include/ui/spice-display.h +++ b/include/ui/spice-display.h @@ -97,7 +97,8 @@ struct SimpleSpiceDisplay { /* cursor (without qxl): displaychangelistener -> spice server */ SimpleSpiceCursor *ptr_define; SimpleSpiceCursor *ptr_move; - uint16_t ptr_x, ptr_y; + int16_t ptr_x, ptr_y; + int16_t hot_x, hot_y; /* cursor (with qxl): qxl local renderer -> displaychangelistener */ QEMUCursor *cursor; diff --git a/monitor.c b/monitor.c index c7a4db6a41..31369d3b09 100644 --- a/monitor.c +++ b/monitor.c @@ -1086,7 +1086,7 @@ static void hmp_info_trace_events(Monitor *mon, const QDict *qdict) } static int client_migrate_info(Monitor *mon, const QDict *qdict, - MonitorCompletion cb, void *opaque) + QObject **ret_data) { const char *protocol = qdict_get_str(qdict, "protocol"); const char *hostname = qdict_get_str(qdict, "hostname"); @@ -1108,8 +1108,7 @@ static int client_migrate_info(Monitor *mon, const QDict *qdict, return -1; } - ret = qemu_spice_migrate_info(hostname, port, tls_port, subject, - cb, opaque); + ret = qemu_spice_migrate_info(hostname, port, tls_port, subject); if (ret != 0) { qerror_report(QERR_UNDEFINED_ERROR); return -1; @@ -4784,10 +4783,22 @@ static int monitor_can_read(void *opaque) return (mon->suspend_cnt == 0) ? 1 : 0; } -static int invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd) +static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd) { - int is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities; - return (qmp_cmd_mode(mon) ? is_cap : !is_cap); + bool is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities; + if (is_cap && qmp_cmd_mode(mon)) { + qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND, + "Capabilities negotiation is already complete, command " + "'%s' ignored", cmd->name); + return true; + } + if (!is_cap && !qmp_cmd_mode(mon)) { + qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND, + "Expecting capabilities negotiation with " + "'qmp_capabilities' before command '%s'", cmd->name); + return true; + } + return false; } /* @@ -5081,11 +5092,14 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) cmd_name = qdict_get_str(input, "execute"); trace_handle_qmp_command(mon, cmd_name); cmd = qmp_find_cmd(cmd_name); - if (!cmd || invalid_qmp_mode(mon, cmd)) { + if (!cmd) { qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND, "The command %s has not been found", cmd_name); goto err_out; } + if (invalid_qmp_mode(mon, cmd)) { + goto err_out; + } obj = qdict_get(input, "arguments"); if (!obj) { diff --git a/qmp-commands.hx b/qmp-commands.hx index 3a42ad0bff..1e59541665 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -332,7 +332,7 @@ EQMP { .name = "send-key", - .args_type = "keys:O,hold-time:i?", + .args_type = "keys:q,hold-time:i?", .mhandler.cmd_new = qmp_marshal_input_send_key, }, @@ -785,8 +785,7 @@ EQMP .args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?", .params = "protocol hostname port tls-port cert-subject", .help = "send migration info to spice/vnc client", - .mhandler.cmd_async = client_migrate_info, - .flags = MONITOR_CMD_ASYNC, + .mhandler.cmd_new = client_migrate_info, }, SQMP @@ -3288,7 +3287,7 @@ EQMP { .name = "migrate-set-capabilities", - .args_type = "capabilities:O", + .args_type = "capabilities:q", .params = "capability:s,state:b", .mhandler.cmd_new = qmp_marshal_input_migrate_set_capabilities, }, diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index 8f845a2b29..1be4d67d8a 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -2,7 +2,7 @@ # QAPI visitor generator # # Copyright IBM, Corp. 2011 -# Copyright (C) 2014 Red Hat, Inc. +# Copyright (C) 2014-2015 Red Hat, Inc. # # Authors: # Anthony Liguori <aliguori@us.ibm.com> @@ -401,34 +401,31 @@ out: return ret -def generate_declaration(name, members, genlist=True, builtin_type=False): +def generate_declaration(name, members, builtin_type=False): ret = "" if not builtin_type: ret += mcgen(''' void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp); ''', - name=name) + name=name) - if genlist: - ret += mcgen(''' + ret += mcgen(''' void visit_type_%(name)sList(Visitor *m, %(name)sList **obj, const char *name, Error **errp); ''', name=name) return ret -def generate_enum_declaration(name, members, genlist=True): - ret = "" - if genlist: - ret += mcgen(''' +def generate_enum_declaration(name, members): + ret = mcgen(''' void visit_type_%(name)sList(Visitor *m, %(name)sList **obj, const char *name, Error **errp); ''', - name=name) + name=name) return ret -def generate_decl_enum(name, members, genlist=True): +def generate_decl_enum(name, members): return mcgen(''' void visit_type_%(name)s(Visitor *m, %(name)s *obj, const char *name, Error **errp); @@ -542,8 +539,7 @@ exprs = parse_schema(input_file) # for built-in types in our header files and simply guard them fdecl.write(guardstart("QAPI_VISIT_BUILTIN_VISITOR_DECL")) for typename in builtin_types: - fdecl.write(generate_declaration(typename, None, genlist=True, - builtin_type=True)) + fdecl.write(generate_declaration(typename, None, builtin_type=True)) fdecl.write(guardend("QAPI_VISIT_BUILTIN_VISITOR_DECL")) # ...this doesn't work for cases where we link in multiple objects that diff --git a/ui/console.c b/ui/console.c index b15ca87f0f..29275136c7 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1788,6 +1788,21 @@ bool qemu_console_is_fixedsize(QemuConsole *con) return con && (con->console_type != TEXT_CONSOLE); } +char *qemu_console_get_label(QemuConsole *con) +{ + if (con->console_type == GRAPHIC_CONSOLE) { + if (con->device) { + return g_strdup(object_get_typename(con->device)); + } + return g_strdup("VGA"); + } else { + if (con->chr && con->chr->label) { + return g_strdup(con->chr->label); + } + return g_strdup_printf("vc%d", con->index); + } +} + int qemu_console_get_index(QemuConsole *con) { if (con == NULL) { diff --git a/ui/gtk.c b/ui/gtk.c index 51abac9f47..51ea1b95ee 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -170,6 +170,7 @@ typedef struct VirtualConsole { GtkWidget *window; GtkWidget *menu_item; GtkWidget *tab_item; + GtkWidget *focus; VirtualConsoleType type; union { VirtualGfxConsole gfx; @@ -230,6 +231,7 @@ struct GtkDisplayState { bool modifier_pressed[ARRAY_SIZE(modifier_keycode)]; bool has_evdev; + bool ignore_keys; }; static void gd_grab_pointer(VirtualConsole *vc); @@ -290,7 +292,8 @@ static void gd_update_cursor(VirtualConsole *vc) GtkDisplayState *s = vc->s; GdkWindow *window; - if (vc->type != GD_VC_GFX) { + if (vc->type != GD_VC_GFX || + !qemu_console_is_graphic(vc->gfx.dcl.con)) { return; } @@ -363,6 +366,9 @@ static void gd_update_geometry_hints(VirtualConsole *vc) GtkWindow *geo_window; if (vc->type == GD_VC_GFX) { + if (!vc->gfx.ds) { + return; + } if (s->free_scale) { geo.min_width = surface_width(vc->gfx.ds) * VC_SCALE_MIN; geo.min_height = surface_height(vc->gfx.ds) * VC_SCALE_MIN; @@ -427,7 +433,8 @@ static void gtk_release_modifiers(GtkDisplayState *s) VirtualConsole *vc = gd_vc_find_current(s); int i, keycode; - if (vc->type != GD_VC_GFX) { + if (vc->type != GD_VC_GFX || + !qemu_console_is_graphic(vc->gfx.dcl.con)) { return; } for (i = 0; i < ARRAY_SIZE(modifier_keycode); i++) { @@ -455,6 +462,7 @@ static void gd_update(DisplayChangeListener *dcl, int x, int y, int w, int h) { VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); + GdkWindow *win; int x1, x2, y1, y2; int mx, my; int fbw, fbh; @@ -481,8 +489,11 @@ static void gd_update(DisplayChangeListener *dcl, fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x; fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y; - gdk_drawable_get_size(gtk_widget_get_window(vc->gfx.drawing_area), - &ww, &wh); + win = gtk_widget_get_window(vc->gfx.drawing_area); + if (!win) { + return; + } + gdk_drawable_get_size(win, &ww, &wh); mx = my = 0; if (ww > fbw) { @@ -574,22 +585,28 @@ static void gd_switch(DisplayChangeListener *dcl, VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); bool resized = true; - trace_gd_switch(vc->label, surface_width(surface), surface_height(surface)); + trace_gd_switch(vc->label, + surface ? surface_width(surface) : 0, + surface ? surface_height(surface) : 0); if (vc->gfx.surface) { cairo_surface_destroy(vc->gfx.surface); + vc->gfx.surface = NULL; + } + if (vc->gfx.convert) { + pixman_image_unref(vc->gfx.convert); + vc->gfx.convert = NULL; } - if (vc->gfx.ds && + if (vc->gfx.ds && surface && surface_width(vc->gfx.ds) == surface_width(surface) && surface_height(vc->gfx.ds) == surface_height(surface)) { resized = false; } vc->gfx.ds = surface; - if (vc->gfx.convert) { - pixman_image_unref(vc->gfx.convert); - vc->gfx.convert = NULL; + if (!surface) { + return; } if (surface->format == PIXMAN_x8r8g8b8) { @@ -690,6 +707,9 @@ static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque) if (!gtk_widget_get_realized(widget)) { return FALSE; } + if (!vc->gfx.ds) { + return FALSE; + } fbw = surface_width(vc->gfx.ds); fbh = surface_height(vc->gfx.ds); @@ -771,6 +791,10 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, int fbh, fbw; int ww, wh; + if (!vc->gfx.ds) { + return TRUE; + } + fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x; fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y; @@ -945,6 +969,23 @@ static int gd_map_keycode(GtkDisplayState *s, GdkDisplay *dpy, int gdk_keycode) return qemu_keycode; } +static gboolean gd_text_key_down(GtkWidget *widget, + GdkEventKey *key, void *opaque) +{ + VirtualConsole *vc = opaque; + QemuConsole *con = vc->gfx.dcl.con; + + if (key->length) { + kbd_put_string_console(con, key->string, key->length); + } else { + int num = gd_map_keycode(vc->s, gtk_widget_get_display(widget), + key->hardware_keycode); + int qcode = qemu_input_key_number_to_qcode(num); + kbd_put_qcode_console(con, qcode); + } + return TRUE; +} + static gboolean gd_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque) { VirtualConsole *vc = opaque; @@ -953,6 +994,11 @@ static gboolean gd_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque) int qemu_keycode; int i; + if (s->ignore_keys) { + s->ignore_keys = (key->type == GDK_KEY_PRESS); + return TRUE; + } + if (key->keyval == GDK_KEY_Pause) { qemu_input_event_send_key_qcode(vc->gfx.dcl.con, Q_KEY_CODE_PAUSE, key->type == GDK_KEY_PRESS); @@ -1021,22 +1067,26 @@ static void gd_menu_switch_vc(GtkMenuItem *item, void *opaque) GtkDisplayState *s = opaque; VirtualConsole *vc = gd_vc_find_by_menu(s); GtkNotebook *nb = GTK_NOTEBOOK(s->notebook); - GtkWidget *child; gint page; gtk_release_modifiers(s); if (vc) { page = gtk_notebook_page_num(nb, vc->tab_item); gtk_notebook_set_current_page(nb, page); - child = gtk_notebook_get_nth_page(nb, page); - gtk_widget_grab_focus(child); + gtk_widget_grab_focus(vc->focus); } + s->ignore_keys = false; } static void gd_accel_switch_vc(void *opaque) { VirtualConsole *vc = opaque; + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vc->menu_item), TRUE); +#if !GTK_CHECK_VERSION(3, 0, 0) + /* GTK2 sends the accel key to the target console - ignore this until */ + vc->s->ignore_keys = true; +#endif } static void gd_menu_show_tabs(GtkMenuItem *item, void *opaque) @@ -1086,7 +1136,8 @@ static void gd_menu_untabify(GtkMenuItem *item, void *opaque) GtkDisplayState *s = opaque; VirtualConsole *vc = gd_vc_find_current(s); - if (vc->type == GD_VC_GFX) { + if (vc->type == GD_VC_GFX && + qemu_console_is_graphic(vc->gfx.dcl.con)) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), FALSE); } @@ -1099,11 +1150,14 @@ static void gd_menu_untabify(GtkMenuItem *item, void *opaque) G_CALLBACK(gd_tab_window_close), vc); gtk_widget_show_all(vc->window); - GtkAccelGroup *ag = gtk_accel_group_new(); - gtk_window_add_accel_group(GTK_WINDOW(vc->window), ag); + if (qemu_console_is_graphic(vc->gfx.dcl.con)) { + GtkAccelGroup *ag = gtk_accel_group_new(); + gtk_window_add_accel_group(GTK_WINDOW(vc->window), ag); - GClosure *cb = g_cclosure_new_swap(G_CALLBACK(gd_win_grab), vc, NULL); - gtk_accel_group_connect(ag, GDK_KEY_g, HOTKEY_MODIFIERS, 0, cb); + GClosure *cb = g_cclosure_new_swap(G_CALLBACK(gd_win_grab), + vc, NULL); + gtk_accel_group_connect(ag, GDK_KEY_g, HOTKEY_MODIFIERS, 0, cb); + } gd_update_geometry_hints(vc); gd_update_caption(s); @@ -1120,8 +1174,10 @@ static void gd_menu_full_screen(GtkMenuItem *item, void *opaque) gtk_widget_hide(s->menu_bar); if (vc->type == GD_VC_GFX) { gtk_widget_set_size_request(vc->gfx.drawing_area, -1, -1); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), - TRUE); + if (qemu_console_is_graphic(vc->gfx.dcl.con)) { + gtk_check_menu_item_set_active + (GTK_CHECK_MENU_ITEM(s->grab_item), TRUE); + } } gtk_window_fullscreen(GTK_WINDOW(s->window)); s->full_screen = TRUE; @@ -1370,7 +1426,8 @@ static void gd_change_page(GtkNotebook *nb, gpointer arg1, guint arg2, #endif gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vc->menu_item), TRUE); - on_vga = (vc->type == GD_VC_GFX); + on_vga = (vc->type == GD_VC_GFX && + qemu_console_is_graphic(vc->gfx.dcl.con)); if (!on_vga) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), FALSE); @@ -1542,6 +1599,7 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc, vc->type = GD_VC_VTE; vc->tab_item = box; + vc->focus = vc->vte.terminal; gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), vc->tab_item, gtk_label_new(vc->label)); @@ -1577,25 +1635,30 @@ static void gd_connect_vc_gfx_signals(VirtualConsole *vc) g_signal_connect(vc->gfx.drawing_area, "expose-event", G_CALLBACK(gd_expose_event), vc); #endif - g_signal_connect(vc->gfx.drawing_area, "event", - G_CALLBACK(gd_event), vc); - g_signal_connect(vc->gfx.drawing_area, "button-press-event", - G_CALLBACK(gd_button_event), vc); - g_signal_connect(vc->gfx.drawing_area, "button-release-event", - G_CALLBACK(gd_button_event), vc); - g_signal_connect(vc->gfx.drawing_area, "scroll-event", - G_CALLBACK(gd_scroll_event), vc); - g_signal_connect(vc->gfx.drawing_area, "key-press-event", - G_CALLBACK(gd_key_event), vc); - g_signal_connect(vc->gfx.drawing_area, "key-release-event", - G_CALLBACK(gd_key_event), vc); - - g_signal_connect(vc->gfx.drawing_area, "enter-notify-event", - G_CALLBACK(gd_enter_event), vc); - g_signal_connect(vc->gfx.drawing_area, "leave-notify-event", - G_CALLBACK(gd_leave_event), vc); - g_signal_connect(vc->gfx.drawing_area, "focus-out-event", - G_CALLBACK(gd_focus_out_event), vc); + if (qemu_console_is_graphic(vc->gfx.dcl.con)) { + g_signal_connect(vc->gfx.drawing_area, "event", + G_CALLBACK(gd_event), vc); + g_signal_connect(vc->gfx.drawing_area, "button-press-event", + G_CALLBACK(gd_button_event), vc); + g_signal_connect(vc->gfx.drawing_area, "button-release-event", + G_CALLBACK(gd_button_event), vc); + g_signal_connect(vc->gfx.drawing_area, "scroll-event", + G_CALLBACK(gd_scroll_event), vc); + g_signal_connect(vc->gfx.drawing_area, "key-press-event", + G_CALLBACK(gd_key_event), vc); + g_signal_connect(vc->gfx.drawing_area, "key-release-event", + G_CALLBACK(gd_key_event), vc); + + g_signal_connect(vc->gfx.drawing_area, "enter-notify-event", + G_CALLBACK(gd_enter_event), vc); + g_signal_connect(vc->gfx.drawing_area, "leave-notify-event", + G_CALLBACK(gd_leave_event), vc); + g_signal_connect(vc->gfx.drawing_area, "focus-out-event", + G_CALLBACK(gd_focus_out_event), vc); + } else { + g_signal_connect(vc->gfx.drawing_area, "key-press-event", + G_CALLBACK(gd_text_key_down), vc); + } } static void gd_connect_signals(GtkDisplayState *s) @@ -1679,15 +1742,7 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc, QemuConsole *con, int idx, GSList *group, GtkWidget *view_menu) { - Object *obj; - - obj = object_property_get_link(OBJECT(con), "device", NULL); - if (obj) { - vc->label = g_strdup_printf("%s", object_get_typename(obj)); - } else { - vc->label = g_strdup_printf("VGA"); - } - + vc->label = qemu_console_get_label(con); vc->s = s; vc->gfx.scale_x = 1.0; vc->gfx.scale_y = 1.0; @@ -1706,16 +1761,17 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc, vc->type = GD_VC_GFX; vc->tab_item = vc->gfx.drawing_area; + vc->focus = vc->gfx.drawing_area; gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), vc->tab_item, gtk_label_new(vc->label)); - gd_connect_vc_gfx_signals(vc); - - group = gd_vc_menu_init(s, vc, idx, group, view_menu); vc->gfx.dcl.ops = &dcl_ops; vc->gfx.dcl.con = con; register_displaychangelistener(&vc->gfx.dcl); + gd_connect_vc_gfx_signals(vc); + group = gd_vc_menu_init(s, vc, idx, group, view_menu); + return group; } @@ -1787,7 +1843,7 @@ static GtkWidget *gd_create_menu_view(GtkDisplayState *s) /* gfx */ for (vc = 0;; vc++) { con = qemu_console_lookup_by_index(vc); - if (!con || !qemu_console_is_graphic(con)) { + if (!con) { break; } group = gd_vc_gfx_init(s, &s->vc[vc], con, diff --git a/ui/spice-core.c b/ui/spice-core.c index c8f7f183c6..f00e0742b4 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -273,14 +273,6 @@ static SpiceCoreInterface core_interface = { .channel_event = channel_event, }; -typedef struct SpiceMigration { - SpiceMigrateInstance sin; - struct { - MonitorCompletion *cb; - void *opaque; - } connect_complete; -} SpiceMigration; - static void migrate_connect_complete_cb(SpiceMigrateInstance *sin); static void migrate_end_complete_cb(SpiceMigrateInstance *sin); @@ -293,15 +285,11 @@ static const SpiceMigrateInterface migrate_interface = { .migrate_end_complete = migrate_end_complete_cb, }; -static SpiceMigration spice_migrate; +static SpiceMigrateInstance spice_migrate; static void migrate_connect_complete_cb(SpiceMigrateInstance *sin) { - SpiceMigration *sm = container_of(sin, SpiceMigration, sin); - if (sm->connect_complete.cb) { - sm->connect_complete.cb(sm->connect_complete.opaque, NULL); - } - sm->connect_complete.cb = NULL; + /* nothing, but libspice-server expects this cb being present. */ } static void migrate_end_complete_cb(SpiceMigrateInstance *sin) @@ -585,13 +573,10 @@ static void migration_state_notifier(Notifier *notifier, void *data) } int qemu_spice_migrate_info(const char *hostname, int port, int tls_port, - const char *subject, - MonitorCompletion *cb, void *opaque) + const char *subject) { int ret; - spice_migrate.connect_complete.cb = cb; - spice_migrate.connect_complete.opaque = opaque; ret = spice_server_migrate_connect(spice_server, hostname, port, tls_port, subject); spice_have_target_host = true; @@ -812,9 +797,8 @@ void qemu_spice_init(void) migration_state.notify = migration_state_notifier; add_migration_state_change_notifier(&migration_state); - spice_migrate.sin.base.sif = &migrate_interface.base; - spice_migrate.connect_complete.cb = NULL; - qemu_spice_add_interface(&spice_migrate.sin.base); + spice_migrate.base.sif = &migrate_interface.base; + qemu_spice_add_interface(&spice_migrate.base); qemu_spice_input_init(); qemu_spice_audio_init(); diff --git a/ui/spice-display.c b/ui/spice-display.c index 16441852e4..c71a059e35 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -178,7 +178,7 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd, image->bitmap.palette = 0; image->bitmap.format = SPICE_BITMAP_FMT_32BIT; - dest = pixman_image_create_bits(PIXMAN_x8r8g8b8, bw, bh, + dest = pixman_image_create_bits(PIXMAN_LE_x8r8g8b8, bw, bh, (void *)update->bitmap, bw * 4); pixman_image_composite(PIXMAN_OP_SRC, ssd->surface, NULL, ssd->mirror, rect->left, rect->top, 0, 0, @@ -260,7 +260,8 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) static SimpleSpiceCursor* qemu_spice_create_cursor_update(SimpleSpiceDisplay *ssd, - QEMUCursor *c) + QEMUCursor *c, + int on) { size_t size = c ? c->width * c->height * 4 : 0; SimpleSpiceCursor *update; @@ -275,8 +276,8 @@ qemu_spice_create_cursor_update(SimpleSpiceDisplay *ssd, if (c) { ccmd->type = QXL_CURSOR_SET; - ccmd->u.set.position.x = ssd->ptr_x; - ccmd->u.set.position.y = ssd->ptr_y; + ccmd->u.set.position.x = ssd->ptr_x + ssd->hot_x; + ccmd->u.set.position.y = ssd->ptr_y + ssd->hot_y; ccmd->u.set.visible = true; ccmd->u.set.shape = (uintptr_t)cursor; cursor->header.unique = ssd->unique++; @@ -288,10 +289,12 @@ qemu_spice_create_cursor_update(SimpleSpiceDisplay *ssd, cursor->data_size = size; cursor->chunk.data_size = size; memcpy(cursor->chunk.data, c->data, size); + } else if (!on) { + ccmd->type = QXL_CURSOR_HIDE; } else { ccmd->type = QXL_CURSOR_MOVE; - ccmd->u.position.x = ssd->ptr_x; - ccmd->u.position.y = ssd->ptr_y; + ccmd->u.position.x = ssd->ptr_x + ssd->hot_x; + ccmd->u.position.y = ssd->ptr_y + ssd->hot_y; } ccmd->release_info.id = (uintptr_t)(&update->ext); @@ -734,11 +737,11 @@ static void display_mouse_set(DisplayChangeListener *dcl, qemu_mutex_lock(&ssd->lock); ssd->ptr_x = x; - ssd->ptr_y = x; + ssd->ptr_y = y; if (ssd->ptr_move) { g_free(ssd->ptr_move); } - ssd->ptr_move = qemu_spice_create_cursor_update(ssd, NULL); + ssd->ptr_move = qemu_spice_create_cursor_update(ssd, NULL, on); qemu_mutex_unlock(&ssd->lock); } @@ -748,6 +751,8 @@ static void display_mouse_define(DisplayChangeListener *dcl, SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl); qemu_mutex_lock(&ssd->lock); + ssd->hot_x = c->hot_x; + ssd->hot_y = c->hot_y; if (ssd->ptr_move) { g_free(ssd->ptr_move); ssd->ptr_move = NULL; @@ -755,7 +760,7 @@ static void display_mouse_define(DisplayChangeListener *dcl, if (ssd->ptr_define) { g_free(ssd->ptr_define); } - ssd->ptr_define = qemu_spice_create_cursor_update(ssd, c); + ssd->ptr_define = qemu_spice_create_cursor_update(ssd, c, 0); qemu_mutex_unlock(&ssd->lock); } |