From patchwork Sun Feb 19 23:45:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony Liguori X-Patchwork-Id: 142085 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C91DDB6FA7 for ; Mon, 20 Feb 2012 10:45:57 +1100 (EST) Received: from localhost ([::1]:33628 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RzGS3-0000pG-IS for incoming@patchwork.ozlabs.org; Sun, 19 Feb 2012 18:45:55 -0500 Received: from eggs.gnu.org ([140.186.70.92]:54085) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RzGRg-0000al-6y for qemu-devel@nongnu.org; Sun, 19 Feb 2012 18:45:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RzGRc-0000ls-5a for qemu-devel@nongnu.org; Sun, 19 Feb 2012 18:45:31 -0500 Received: from e31.co.us.ibm.com ([32.97.110.149]:56985) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RzGRb-0000lX-Fa for qemu-devel@nongnu.org; Sun, 19 Feb 2012 18:45:27 -0500 Received: from /spool/local by e31.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Sun, 19 Feb 2012 16:45:26 -0700 Received: from d03dlp02.boulder.ibm.com (9.17.202.178) by e31.co.us.ibm.com (192.168.1.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Sun, 19 Feb 2012 16:45:23 -0700 Received: from d03relay04.boulder.ibm.com (d03relay04.boulder.ibm.com [9.17.195.106]) by d03dlp02.boulder.ibm.com (Postfix) with ESMTP id 43DEF3E40047 for ; Sun, 19 Feb 2012 16:45:23 -0700 (MST) Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by d03relay04.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q1JNjNJ2112300 for ; Sun, 19 Feb 2012 16:45:23 -0700 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q1JNjMRp002115 for ; Sun, 19 Feb 2012 16:45:22 -0700 Received: from titi.austin.rr.com (sig-9-65-240-157.mts.ibm.com [9.65.240.157]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q1JNj64g001215; Sun, 19 Feb 2012 16:45:21 -0700 From: Anthony Liguori To: qemu-devel@nongnu.org Date: Sun, 19 Feb 2012 17:45:03 -0600 Message-Id: <1329695104-15174-6-git-send-email-aliguori@us.ibm.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1329695104-15174-1-git-send-email-aliguori@us.ibm.com> References: <1329695104-15174-1-git-send-email-aliguori@us.ibm.com> X-Content-Scanned: Fidelis XPS MAILER x-cbid: 12021923-7282-0000-0000-000006AAB726 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 32.97.110.149 Cc: Anthony Liguori , Alex Graf Subject: [Qemu-devel] [PATCH 5/6] gtk: add support for screen scaling and full screen X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Basic menu items to enter full screen mode and zoom in/out. Unlike SDL, we don't allow arbitrary scaling based on window resizing. The current behavior with SDL causes a lot of problems for me. Sometimes I accidentally resize the window a tiny bit while trying to move it (Ubuntu's 1-pixel window decorations don't help here). After that, scaling is now active and if the screen changes size again, badness ensues since the aspect ratio is skewed. Allowing zooming by 25% in and out should cover most use cases. We can add a more flexible scaling later but for now, I think this is a more friendly behavior. Signed-off-by: Anthony Liguori --- ui/gtk.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 85 insertions(+), 4 deletions(-) diff --git a/ui/gtk.c b/ui/gtk.c index 73051db..b9a9bc3 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -58,6 +58,9 @@ typedef struct GtkDisplayState GtkWidget *view_menu_item; GtkWidget *view_menu; + GtkWidget *full_screen_item; + GtkWidget *zoom_in_item; + GtkWidget *zoom_out_item; GtkWidget *grab_item; GtkWidget *vga_item; @@ -78,6 +81,7 @@ typedef struct GtkDisplayState double scale_x; double scale_y; + gboolean full_screen; GdkCursor *null_cursor; Notifier mouse_mode_notifier; @@ -102,7 +106,7 @@ static void gd_update_cursor(GtkDisplayState *s, gboolean override) on_vga = (gtk_notebook_get_current_page(GTK_NOTEBOOK(s->notebook)) == 0); if ((override || on_vga) && - (kbd_mouse_is_absolute() || gd_is_grab_active(s))) { + (s->full_screen || kbd_mouse_is_absolute() || gd_is_grab_active(s))) { gdk_window_set_cursor(window, s->null_cursor); } else { gdk_window_set_cursor(window, NULL); @@ -194,9 +198,11 @@ static void gd_resize(DisplayState *ds) ds->surface->height, ds->surface->linesize); - gtk_widget_set_size_request(s->drawing_area, - ds->surface->width * s->scale_x, - ds->surface->height * s->scale_y); + if (!s->full_screen) { + gtk_widget_set_size_request(s->drawing_area, + ds->surface->width * s->scale_x, + ds->surface->height * s->scale_y); + } } /** QEMU Events **/ @@ -453,6 +459,51 @@ static void gd_menu_show_tabs(GtkMenuItem *item, void *opaque) } } +static void gd_menu_full_screen(GtkMenuItem *item, void *opaque) +{ + GtkDisplayState *s = opaque; + + if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->full_screen_item))) { + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(s->notebook), FALSE); + gtk_widget_set_size_request(s->menu_bar, 0, 0); + gtk_widget_set_size_request(s->drawing_area, -1, -1); + gtk_window_set_resizable(GTK_WINDOW(s->window), TRUE); + gtk_window_fullscreen(GTK_WINDOW(s->window)); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), TRUE); + s->full_screen = TRUE; + } else { + gtk_window_unfullscreen(GTK_WINDOW(s->window)); + gd_menu_show_tabs(GTK_MENU_ITEM(s->show_tabs_item), s); + gtk_widget_set_size_request(s->menu_bar, -1, -1); + gtk_widget_set_size_request(s->drawing_area, s->ds->surface->width, s->ds->surface->height); + gtk_window_set_resizable(GTK_WINDOW(s->window), FALSE); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), FALSE); + s->full_screen = FALSE; + } + + gd_update_cursor(s, FALSE); +} + +static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque) +{ + GtkDisplayState *s = opaque; + + s->scale_x *= 1.25; + s->scale_y *= 1.25; + + gd_resize(s->ds); +} + +static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque) +{ + GtkDisplayState *s = opaque; + + s->scale_x *= .75; + s->scale_y *= .75; + + gd_resize(s->ds); +} + static void gd_menu_grab_input(GtkMenuItem *item, void *opaque) { GtkDisplayState *s = opaque; @@ -495,6 +546,9 @@ static void gd_change_page(GtkNotebook *nb, gpointer arg1, guint arg2, if (!on_vga) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), FALSE); + } else if (s->full_screen) { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), + TRUE); } gtk_widget_set_sensitive(s->grab_item, on_vga); @@ -647,6 +701,12 @@ static void gd_connect_signals(GtkDisplayState *s) g_signal_connect(s->quit_item, "activate", G_CALLBACK(gd_menu_quit), s); + g_signal_connect(s->full_screen_item, "activate", + G_CALLBACK(gd_menu_full_screen), s); + g_signal_connect(s->zoom_in_item, "activate", + G_CALLBACK(gd_menu_zoom_in), s); + g_signal_connect(s->zoom_out_item, "activate", + G_CALLBACK(gd_menu_zoom_out), s); g_signal_connect(s->vga_item, "activate", G_CALLBACK(gd_menu_switch_vc), s); g_signal_connect(s->grab_item, "activate", @@ -678,6 +738,27 @@ static void gd_create_menus(GtkDisplayState *s) gtk_menu_set_accel_group(GTK_MENU(s->view_menu), accel_group); s->view_menu_item = gtk_menu_item_new_with_mnemonic("_View"); + s->full_screen_item = gtk_check_menu_item_new_with_mnemonic("_Full Screen"); + gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->full_screen_item), + "/View/Full Screen"); + gtk_accel_map_add_entry("/View/Full Screen", GDK_KEY_f, GDK_CONTROL_MASK | GDK_MOD1_MASK); + gtk_menu_append(GTK_MENU(s->view_menu), s->full_screen_item); + + separator = gtk_separator_menu_item_new(); + gtk_menu_append(GTK_MENU(s->view_menu), separator); + + 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), + "/View/Zoom In"); + gtk_accel_map_add_entry("/View/Zoom In", GDK_KEY_equal, GDK_CONTROL_MASK | GDK_MOD1_MASK); + gtk_menu_append(GTK_MENU(s->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), + "/View/Zoom Out"); + gtk_accel_map_add_entry("/View/Zoom Out", GDK_KEY_minus, GDK_CONTROL_MASK | GDK_MOD1_MASK); + gtk_menu_append(GTK_MENU(s->view_menu), s->zoom_out_item); + separator = gtk_separator_menu_item_new(); gtk_menu_append(GTK_MENU(s->view_menu), separator);