#include <glib/gi18n.h>
#include <locale.h>
#include <vte/vte.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/wait.h>
#include <math.h>
#include "ui/console.h"
#define GDK_KEY_minus GDK_minus
#endif
+#define HOTKEY_MODIFIERS (GDK_CONTROL_MASK | GDK_MOD1_MASK)
+#define IGNORE_MODIFIER_MASK \
+ (GDK_MODIFIER_MASK & ~(GDK_LOCK_MASK | GDK_MOD2_MASK))
+
static const int modifier_keycode[] = {
/* shift, control, alt keys, meta keys, both left & right */
0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8, 0xdb, 0xdd,
GtkWidget *notebook;
GtkWidget *drawing_area;
cairo_surface_t *surface;
+ pixman_image_t *convert;
DisplayChangeListener dcl;
DisplaySurface *ds;
int button_mask;
DPRINTF("update(x=%d, y=%d, w=%d, h=%d)\n", x, y, w, h);
+ if (s->convert) {
+ pixman_image_composite(PIXMAN_OP_SRC, s->ds->image, NULL, s->convert,
+ x, y, 0, 0, x, y, w, h);
+ }
+
x1 = floor(x * s->scale_x);
y1 = floor(y * s->scale_y);
pixbuf, c->hot_x, c->hot_y);
gdk_window_set_cursor(gtk_widget_get_window(s->drawing_area), cursor);
g_object_unref(pixbuf);
+#if !GTK_CHECK_VERSION(3, 0, 0)
gdk_cursor_unref(cursor);
+#else
+ g_object_unref(cursor);
+#endif
}
static void gd_switch(DisplayChangeListener *dcl,
DisplaySurface *surface)
{
GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
- cairo_format_t kind;
bool resized = true;
- int stride;
DPRINTF("resize(width=%d, height=%d)\n",
surface_width(surface), surface_height(surface));
resized = false;
}
s->ds = surface;
- switch (surface_bits_per_pixel(surface)) {
- case 8:
- kind = CAIRO_FORMAT_A8;
- break;
- case 16:
- kind = CAIRO_FORMAT_RGB16_565;
- break;
- case 32:
- kind = CAIRO_FORMAT_RGB24;
- break;
- default:
- g_assert_not_reached();
- break;
- }
- stride = cairo_format_stride_for_width(kind, surface_width(surface));
- g_assert(surface_stride(surface) == stride);
+ if (s->convert) {
+ pixman_image_unref(s->convert);
+ s->convert = NULL;
+ }
- s->surface = cairo_image_surface_create_for_data(surface_data(surface),
- kind,
- surface_width(surface),
- surface_height(surface),
- surface_stride(surface));
+ if (surface->format == PIXMAN_x8r8g8b8) {
+ /*
+ * PIXMAN_x8r8g8b8 == CAIRO_FORMAT_RGB24
+ *
+ * No need to convert, use surface directly. Should be the
+ * common case as this is qemu_default_pixelformat(32) too.
+ */
+ s->surface = cairo_image_surface_create_for_data
+ (surface_data(surface),
+ CAIRO_FORMAT_RGB24,
+ surface_width(surface),
+ surface_height(surface),
+ surface_stride(surface));
+ } else {
+ /* Must convert surface, use pixman to do it. */
+ s->convert = pixman_image_create_bits(PIXMAN_x8r8g8b8,
+ surface_width(surface),
+ surface_height(surface),
+ NULL, 0);
+ s->surface = cairo_image_surface_create_for_data
+ ((void *)pixman_image_get_data(s->convert),
+ CAIRO_FORMAT_RGB24,
+ pixman_image_get_width(s->convert),
+ pixman_image_get_height(s->convert),
+ pixman_image_get_stride(s->convert));
+ pixman_image_composite(PIXMAN_OP_SRC, s->ds->image, NULL, s->convert,
+ 0, 0, 0, 0, 0, 0,
+ pixman_image_get_width(s->convert),
+ pixman_image_get_height(s->convert));
+ }
if (resized) {
gd_update_windowsize(s);
static gboolean gd_window_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque)
{
GtkDisplayState *s = opaque;
- GtkAccelGroupEntry *entries;
- guint n_entries = 0;
- gboolean propagate_accel = TRUE;
gboolean handled = FALSE;
- entries = gtk_accel_group_query(s->accel_group, key->keyval,
- key->state, &n_entries);
- if (n_entries) {
- const char *quark = g_quark_to_string(entries[0].accel_path_quark);
-
- if (gd_is_grab_active(s) && strstart(quark, "<QEMU>/File/", NULL)) {
- propagate_accel = FALSE;
- }
- }
-
- if (!handled && propagate_accel) {
+ if (!gd_is_grab_active(s) ||
+ (key->state & IGNORE_MODIFIER_MASK) == HOTKEY_MODIFIERS) {
handled = gtk_window_activate_key(GTK_WINDOW(widget), key);
}
if (handled) {
GIOChannel *chan;
GtkWidget *scrolled_window;
GtkAdjustment *vadjustment;
- int master_fd, slave_fd, ret;
- struct termios tty;
+ int master_fd, slave_fd;
snprintf(buffer, sizeof(buffer), "vc%d", index);
snprintf(path, sizeof(path), "<QEMU>/View/VC%d", index);
vc->menu_item = gtk_radio_menu_item_new_with_mnemonic(group, label);
group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(vc->menu_item));
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(vc->menu_item), path);
- gtk_accel_map_add_entry(path, GDK_KEY_2 + index, GDK_CONTROL_MASK | GDK_MOD1_MASK);
+ gtk_accel_map_add_entry(path, GDK_KEY_2 + index, HOTKEY_MODIFIERS);
vc->terminal = vte_terminal_new();
- ret = openpty(&master_fd, &slave_fd, NULL, NULL, NULL);
- g_assert(ret != -1);
-
- /* Set raw attributes on the pty. */
- tcgetattr(slave_fd, &tty);
- cfmakeraw(&tty);
- tcsetattr(slave_fd, TCSAFLUSH, &tty);
+ master_fd = qemu_openpty_raw(&slave_fd, NULL);
+ g_assert(master_fd != -1);
#if VTE_CHECK_VERSION(0, 26, 0)
pty = vte_pty_new_foreign(master_fd, NULL);
gtk_image_menu_item_new_from_stock(GTK_STOCK_FULLSCREEN, NULL);
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->full_screen_item),
"<QEMU>/View/Full Screen");
- gtk_accel_map_add_entry("<QEMU>/View/Full Screen", GDK_KEY_f, GDK_CONTROL_MASK | GDK_MOD1_MASK);
+ gtk_accel_map_add_entry("<QEMU>/View/Full Screen", GDK_KEY_f,
+ HOTKEY_MODIFIERS);
gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->full_screen_item);
separator = gtk_separator_menu_item_new();
s->zoom_in_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_IN, NULL);
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_in_item),
"<QEMU>/View/Zoom In");
- gtk_accel_map_add_entry("<QEMU>/View/Zoom In", GDK_KEY_plus, GDK_CONTROL_MASK | GDK_MOD1_MASK);
+ gtk_accel_map_add_entry("<QEMU>/View/Zoom In", GDK_KEY_plus,
+ HOTKEY_MODIFIERS);
gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_in_item);
s->zoom_out_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_OUT, NULL);
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_out_item),
"<QEMU>/View/Zoom Out");
- gtk_accel_map_add_entry("<QEMU>/View/Zoom Out", GDK_KEY_minus, GDK_CONTROL_MASK | GDK_MOD1_MASK);
+ gtk_accel_map_add_entry("<QEMU>/View/Zoom Out", GDK_KEY_minus,
+ HOTKEY_MODIFIERS);
gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_out_item);
s->zoom_fixed_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ZOOM_100, NULL);
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_fixed_item),
"<QEMU>/View/Zoom Fixed");
- gtk_accel_map_add_entry("<QEMU>/View/Zoom Fixed", GDK_KEY_0, GDK_CONTROL_MASK | GDK_MOD1_MASK);
+ gtk_accel_map_add_entry("<QEMU>/View/Zoom Fixed", GDK_KEY_0,
+ HOTKEY_MODIFIERS);
gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_fixed_item);
s->zoom_fit_item = gtk_check_menu_item_new_with_mnemonic(_("Zoom To _Fit"));
s->grab_item = gtk_check_menu_item_new_with_mnemonic(_("_Grab Input"));
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->grab_item),
"<QEMU>/View/Grab Input");
- gtk_accel_map_add_entry("<QEMU>/View/Grab Input", GDK_KEY_g, GDK_CONTROL_MASK | GDK_MOD1_MASK);
+ gtk_accel_map_add_entry("<QEMU>/View/Grab Input", GDK_KEY_g,
+ HOTKEY_MODIFIERS);
gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->grab_item);
separator = gtk_separator_menu_item_new();
group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(s->vga_item));
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->vga_item),
"<QEMU>/View/VGA");
- gtk_accel_map_add_entry("<QEMU>/View/VGA", GDK_KEY_1, GDK_CONTROL_MASK | GDK_MOD1_MASK);
+ gtk_accel_map_add_entry("<QEMU>/View/VGA", GDK_KEY_1, HOTKEY_MODIFIERS);
gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->vga_item);
for (i = 0; i < nb_vcs; i++) {