aboutsummaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/egl-helpers.c9
-rw-r--r--ui/gtk.c115
-rw-r--r--ui/sdl2.c4
-rw-r--r--ui/shader.c8
-rw-r--r--ui/spice-display.c34
5 files changed, 138 insertions, 32 deletions
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index 558edfdeb7..22835c0626 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -49,18 +49,15 @@ int qemu_egl_rendernode_open(void)
continue;
}
- r = asprintf(&p, "/dev/dri/%s", e->d_name);
- if (r < 0) {
- return -1;
- }
+ p = g_strdup_printf("/dev/dri/%s", e->d_name);
r = open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
if (r < 0) {
- free(p);
+ g_free(p);
continue;
}
fd = r;
- free(p);
+ g_free(p);
break;
}
diff --git a/ui/gtk.c b/ui/gtk.c
index f372a6d5ae..7572cec8c5 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -139,6 +139,7 @@ struct GtkDisplayState {
GtkWidget *view_menu_item;
GtkWidget *view_menu;
GtkWidget *full_screen_item;
+ GtkWidget *copy_item;
GtkWidget *zoom_in_item;
GtkWidget *zoom_out_item;
GtkWidget *zoom_fixed_item;
@@ -328,7 +329,23 @@ static void gd_update_geometry_hints(VirtualConsole *vc)
#if defined(CONFIG_VTE)
} else if (vc->type == GD_VC_VTE) {
VteTerminal *term = VTE_TERMINAL(vc->vte.terminal);
- GtkBorder *ib;
+ GtkBorder padding = { 0 };
+
+#if VTE_CHECK_VERSION(0, 37, 0)
+ gtk_style_context_get_padding(
+ gtk_widget_get_style_context(vc->vte.terminal),
+ gtk_widget_get_state_flags(vc->vte.terminal),
+ &padding);
+#else
+ {
+ GtkBorder *ib = NULL;
+ gtk_widget_style_get(vc->vte.terminal, "inner-border", &ib, NULL);
+ if (ib) {
+ padding = *ib;
+ gtk_border_free(ib);
+ }
+ }
+#endif
geo.width_inc = vte_terminal_get_char_width(term);
geo.height_inc = vte_terminal_get_char_height(term);
@@ -339,11 +356,11 @@ static void gd_update_geometry_hints(VirtualConsole *vc)
geo.min_width = geo.width_inc * VC_TERM_X_MIN;
geo.min_height = geo.height_inc * VC_TERM_Y_MIN;
mask |= GDK_HINT_MIN_SIZE;
- gtk_widget_style_get(vc->vte.terminal, "inner-border", &ib, NULL);
- geo.base_width += ib->left + ib->right;
- geo.base_height += ib->top + ib->bottom;
- geo.min_width += ib->left + ib->right;
- geo.min_height += ib->top + ib->bottom;
+
+ geo.base_width += padding.left + padding.right;
+ geo.base_height += padding.top + padding.bottom;
+ geo.min_width += padding.left + padding.right;
+ geo.min_height += padding.top + padding.bottom;
geo_widget = vc->vte.terminal;
#endif
}
@@ -463,12 +480,21 @@ static void gd_refresh(DisplayChangeListener *dcl)
}
#if GTK_CHECK_VERSION(3, 0, 0)
+static GdkDevice *gd_get_pointer(GdkDisplay *dpy)
+{
+#if GTK_CHECK_VERSION(3, 20, 0)
+ return gdk_seat_get_pointer(gdk_display_get_default_seat(dpy));
+#else
+ return gdk_device_manager_get_client_pointer(
+ gdk_display_get_device_manager(dpy));
+#endif
+}
+
static void gd_mouse_set(DisplayChangeListener *dcl,
int x, int y, int visible)
{
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
GdkDisplay *dpy;
- GdkDeviceManager *mgr;
gint x_root, y_root;
if (qemu_input_is_absolute()) {
@@ -476,10 +502,9 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
}
dpy = gtk_widget_get_display(vc->gfx.drawing_area);
- mgr = gdk_display_get_device_manager(dpy);
gdk_window_get_root_coords(gtk_widget_get_window(vc->gfx.drawing_area),
x, y, &x_root, &y_root);
- gdk_device_warp(gdk_device_manager_get_client_pointer(mgr),
+ gdk_device_warp(gd_get_pointer(dpy),
gtk_widget_get_screen(vc->gfx.drawing_area),
x_root, y_root);
vc->s->last_x = x;
@@ -1307,7 +1332,31 @@ static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
gd_update_full_redraw(vc);
}
-#if GTK_CHECK_VERSION(3, 0, 0)
+#if GTK_CHECK_VERSION(3, 20, 0)
+static void gd_grab_update(VirtualConsole *vc, bool kbd, bool ptr)
+{
+ GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area);
+ GdkSeat *seat = gdk_display_get_default_seat(display);
+ GdkWindow *window = gtk_widget_get_window(vc->gfx.drawing_area);
+ GdkSeatCapabilities caps = 0;
+ GdkCursor *cursor = NULL;
+
+ if (kbd) {
+ caps |= GDK_SEAT_CAPABILITY_KEYBOARD;
+ }
+ if (ptr) {
+ caps |= GDK_SEAT_CAPABILITY_ALL_POINTING;
+ cursor = vc->s->null_cursor;
+ }
+
+ if (caps) {
+ gdk_seat_grab(seat, window, caps, false, cursor,
+ NULL, NULL, NULL);
+ } else {
+ gdk_seat_ungrab(seat);
+ }
+}
+#elif GTK_CHECK_VERSION(3, 0, 0)
static void gd_grab_devices(VirtualConsole *vc, bool grab,
GdkInputSource source, GdkEventMask mask,
GdkCursor *cursor)
@@ -1344,7 +1393,9 @@ static void gd_grab_keyboard(VirtualConsole *vc, const char *reason)
}
}
-#if GTK_CHECK_VERSION(3, 0, 0)
+#if GTK_CHECK_VERSION(3, 20, 0)
+ gd_grab_update(vc, true, vc->s->ptr_owner == vc);
+#elif GTK_CHECK_VERSION(3, 0, 0)
gd_grab_devices(vc, true, GDK_SOURCE_KEYBOARD,
GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
NULL);
@@ -1367,7 +1418,9 @@ static void gd_ungrab_keyboard(GtkDisplayState *s)
}
s->kbd_owner = NULL;
-#if GTK_CHECK_VERSION(3, 0, 0)
+#if GTK_CHECK_VERSION(3, 20, 0)
+ gd_grab_update(vc, false, vc->s->ptr_owner == vc);
+#elif GTK_CHECK_VERSION(3, 0, 0)
gd_grab_devices(vc, false, GDK_SOURCE_KEYBOARD, 0, NULL);
#else
gdk_keyboard_ungrab(GDK_CURRENT_TIME);
@@ -1388,8 +1441,11 @@ static void gd_grab_pointer(VirtualConsole *vc, const char *reason)
}
}
-#if GTK_CHECK_VERSION(3, 0, 0)
- GdkDeviceManager *mgr = gdk_display_get_device_manager(display);
+#if GTK_CHECK_VERSION(3, 20, 0)
+ gd_grab_update(vc, vc->s->kbd_owner == vc, true);
+ gdk_device_get_position(gd_get_pointer(display),
+ NULL, &vc->s->grab_x_root, &vc->s->grab_y_root);
+#elif GTK_CHECK_VERSION(3, 0, 0)
gd_grab_devices(vc, true, GDK_SOURCE_MOUSE,
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
@@ -1397,7 +1453,7 @@ static void gd_grab_pointer(VirtualConsole *vc, const char *reason)
GDK_BUTTON_MOTION_MASK |
GDK_SCROLL_MASK,
vc->s->null_cursor);
- gdk_device_get_position(gdk_device_manager_get_client_pointer(mgr),
+ gdk_device_get_position(gd_get_pointer(display),
NULL, &vc->s->grab_x_root, &vc->s->grab_y_root);
#else
gdk_pointer_grab(gtk_widget_get_window(vc->gfx.drawing_area),
@@ -1421,17 +1477,21 @@ static void gd_grab_pointer(VirtualConsole *vc, const char *reason)
static void gd_ungrab_pointer(GtkDisplayState *s)
{
VirtualConsole *vc = s->ptr_owner;
+ GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area);
if (vc == NULL) {
return;
}
s->ptr_owner = NULL;
- GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area);
-#if GTK_CHECK_VERSION(3, 0, 0)
- GdkDeviceManager *mgr = gdk_display_get_device_manager(display);
+#if GTK_CHECK_VERSION(3, 20, 0)
+ gd_grab_update(vc, vc->s->kbd_owner == vc, false);
+ gdk_device_warp(gd_get_pointer(display),
+ gtk_widget_get_screen(vc->gfx.drawing_area),
+ vc->s->grab_x_root, vc->s->grab_y_root);
+#elif GTK_CHECK_VERSION(3, 0, 0)
gd_grab_devices(vc, false, GDK_SOURCE_MOUSE, 0, NULL);
- gdk_device_warp(gdk_device_manager_get_client_pointer(mgr),
+ gdk_device_warp(gd_get_pointer(display),
gtk_widget_get_screen(vc->gfx.drawing_area),
vc->s->grab_x_root, vc->s->grab_y_root);
#else
@@ -1570,6 +1630,14 @@ static GSList *gd_vc_menu_init(GtkDisplayState *s, VirtualConsole *vc,
}
#if defined(CONFIG_VTE)
+static void gd_menu_copy(GtkMenuItem *item, void *opaque)
+{
+ GtkDisplayState *s = opaque;
+ VirtualConsole *vc = gd_vc_find_current(s);
+
+ vte_terminal_copy_clipboard(VTE_TERMINAL(vc->vte.terminal));
+}
+
static void gd_vc_adjustment_changed(GtkAdjustment *adjustment, void *opaque)
{
VirtualConsole *vc = opaque;
@@ -1806,6 +1874,10 @@ static void gd_connect_signals(GtkDisplayState *s)
G_CALLBACK(gd_menu_powerdown), s);
g_signal_connect(s->quit_item, "activate",
G_CALLBACK(gd_menu_quit), s);
+#if defined(CONFIG_VTE)
+ g_signal_connect(s->copy_item, "activate",
+ G_CALLBACK(gd_menu_copy), s);
+#endif
g_signal_connect(s->full_screen_item, "activate",
G_CALLBACK(gd_menu_full_screen), s);
g_signal_connect(s->zoom_in_item, "activate",
@@ -1939,6 +2011,11 @@ static GtkWidget *gd_create_menu_view(GtkDisplayState *s)
s->full_screen_item = gtk_menu_item_new_with_mnemonic(_("_Fullscreen"));
+#if defined(CONFIG_VTE)
+ s->copy_item = gtk_menu_item_new_with_mnemonic(_("_Copy"));
+ gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->copy_item);
+#endif
+
gtk_accel_group_connect(s->accel_group, GDK_KEY_f, HOTKEY_MODIFIERS, 0,
g_cclosure_new_swap(G_CALLBACK(gd_accel_full_screen), s, NULL));
#if GTK_CHECK_VERSION(3, 8, 0)
diff --git a/ui/sdl2.c b/ui/sdl2.c
index d0424421ec..909038f81d 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -357,6 +357,10 @@ static void handle_keydown(SDL_Event *ev)
case SDL_SCANCODE_7:
case SDL_SCANCODE_8:
case SDL_SCANCODE_9:
+ if (gui_grab) {
+ sdl_grab_end(scon);
+ }
+
win = ev->key.keysym.scancode - SDL_SCANCODE_1;
if (win < sdl2_num_outputs) {
sdl2_console[win].hidden = !sdl2_console[win].hidden;
diff --git a/ui/shader.c b/ui/shader.c
index 9264009b80..1ffddbef3b 100644
--- a/ui/shader.c
+++ b/ui/shader.c
@@ -83,12 +83,12 @@ GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src)
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (!status) {
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
- errmsg = malloc(length);
+ errmsg = g_malloc(length);
glGetShaderInfoLog(shader, length, &length, errmsg);
fprintf(stderr, "%s: compile %s error\n%s\n", __func__,
(type == GL_VERTEX_SHADER) ? "vertex" : "fragment",
errmsg);
- free(errmsg);
+ g_free(errmsg);
return 0;
}
return shader;
@@ -108,10 +108,10 @@ GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag)
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (!status) {
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
- errmsg = malloc(length);
+ errmsg = g_malloc(length);
glGetProgramInfoLog(program, length, &length, errmsg);
fprintf(stderr, "%s: link program: %s\n", __func__, errmsg);
- free(errmsg);
+ g_free(errmsg);
return 0;
}
return program;
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 242ab5f468..0553c5e5b0 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -660,6 +660,11 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
qemu_bh_schedule(ssd->gl_unblock_bh);
break;
}
+ case QXL_COOKIE_TYPE_IO:
+ if (cookie->io == QXL_IO_MONITORS_CONFIG_ASYNC) {
+ g_free(cookie->u.data);
+ }
+ break;
#endif
default:
/* should never be called, used in qxl native mode only */
@@ -769,9 +774,7 @@ static void display_mouse_define(DisplayChangeListener *dcl,
SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
qemu_mutex_lock(&ssd->lock);
- if (c) {
- cursor_get(c);
- }
+ cursor_get(c);
cursor_put(ssd->cursor);
ssd->cursor = c;
ssd->hot_x = c->hot_x;
@@ -795,6 +798,29 @@ static const DisplayChangeListenerOps display_listener_ops = {
#ifdef HAVE_SPICE_GL
+static void qemu_spice_gl_monitor_config(SimpleSpiceDisplay *ssd,
+ int x, int y, int w, int h)
+{
+ QXLMonitorsConfig *config;
+ QXLCookie *cookie;
+
+ config = g_malloc0(sizeof(QXLMonitorsConfig) + sizeof(QXLHead));
+ config->count = 1;
+ config->max_allowed = 1;
+ config->heads[0].x = x;
+ config->heads[0].y = y;
+ config->heads[0].width = w;
+ config->heads[0].height = h;
+ cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
+ QXL_IO_MONITORS_CONFIG_ASYNC);
+ cookie->u.data = config;
+
+ spice_qxl_monitors_config_async(&ssd->qxl,
+ (uintptr_t)config,
+ MEMSLOT_GROUP_HOST,
+ (uintptr_t)cookie);
+}
+
static void qemu_spice_gl_block(SimpleSpiceDisplay *ssd, bool block)
{
uint64_t timeout;
@@ -858,6 +884,8 @@ static void qemu_spice_gl_scanout(DisplayChangeListener *dcl,
surface_width(ssd->ds),
surface_height(ssd->ds),
stride, fourcc, y_0_top);
+
+ qemu_spice_gl_monitor_config(ssd, x, y, w, h);
}
static void qemu_spice_gl_update(DisplayChangeListener *dcl,