From patchwork Tue Aug 2 15:07:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: clord@redhat.com X-Patchwork-Id: 9258047 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0D96A6077C for ; Tue, 2 Aug 2016 15:11:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F1DF427CF9 for ; Tue, 2 Aug 2016 15:11:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E50EA28529; Tue, 2 Aug 2016 15:11:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id BB87F28346 for ; Tue, 2 Aug 2016 15:11:06 +0000 (UTC) Received: from localhost ([::1]:57213 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bUbLV-0004lk-7S for patchwork-qemu-devel@patchwork.kernel.org; Tue, 02 Aug 2016 11:11:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54208) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bUbI0-0002Fz-Fe for qemu-devel@nongnu.org; Tue, 02 Aug 2016 11:07:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bUbHv-0003HP-4Y for qemu-devel@nongnu.org; Tue, 02 Aug 2016 11:07:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38422) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bUbHu-0003HL-SF for qemu-devel@nongnu.org; Tue, 02 Aug 2016 11:07:23 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8C317C050064 for ; Tue, 2 Aug 2016 15:07:22 +0000 (UTC) Received: from dhcp-17-138.bos.redhat.com (dhcp-17-209.bos.redhat.com [10.18.17.209]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u72F7Ks6023842; Tue, 2 Aug 2016 11:07:21 -0400 From: Colin Lord To: qemu-devel@nongnu.org Date: Tue, 2 Aug 2016 11:07:19 -0400 Message-Id: <1470150439-28468-3-git-send-email-clord@redhat.com> In-Reply-To: <1470150439-28468-1-git-send-email-clord@redhat.com> References: <1470150439-28468-1-git-send-email-clord@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 02 Aug 2016 15:07:22 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 2/2] gtk: Modularize GTK display X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: pbonzini@redhat.com, kraxel@redhat.com, Colin Lord Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Allows GTK to be compiled as a module and loaded at runtime. If GTK is not the display being used, the module will not be loaded. In the case that the GTK module is not present, if GTK was specified explicitly by the user, qemu will exit with an error, otherwise it will default to display type None. This should give improvements in terms of performance, since much less libraries will be loaded at startup if GTK is not being used, and in terms of packaging, since GTK should be able to be packaged separately in binary package managers now. Signed-off-by: Colin Lord --- Makefile.objs | 1 + configure | 5 ++-- include/ui/console.h | 6 +++++ ui/Makefile.objs | 14 ++++++++---- ui/gtk-init.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ui/gtk.c | 11 +++++++-- vl.c | 14 ++++++++++-- 7 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 ui/gtk-init.c diff --git a/Makefile.objs b/Makefile.objs index 6d5ddcf..08c5746 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -62,6 +62,7 @@ common-obj-y += accel.o common-obj-y += replay/ common-obj-y += ui/ +common-obj-m += ui/ common-obj-y += bt-host.o bt-vhci.o bt-host.o-cflags := $(BLUEZ_CFLAGS) diff --git a/configure b/configure index f1e7d14..ab15662 100755 --- a/configure +++ b/configure @@ -2185,7 +2185,6 @@ if test "$gtk" != "no"; then gtk_cflags="$gtk_cflags $x11_cflags" gtk_libs="$gtk_libs $x11_libs" fi - libs_softmmu="$gtk_libs $libs_softmmu" gtk="yes" elif test "$gtk" = "yes"; then feature_not_found "gtk" "Install gtk2 or gtk3 devel" @@ -2422,7 +2421,6 @@ if test "$vte" != "no"; then vte_cflags=$($pkg_config --cflags $vtepackage) vte_libs=$($pkg_config --libs $vtepackage) vteversion=$($pkg_config --modversion $vtepackage) - libs_softmmu="$vte_libs $libs_softmmu" vte="yes" elif test "$vte" = "yes"; then if test "$gtkabi" = "3.0"; then @@ -5166,7 +5164,7 @@ if test "$glib_subprocess" = "yes" ; then fi echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak if test "$gtk" = "yes" ; then - echo "CONFIG_GTK=y" >> $config_host_mak + echo "CONFIG_GTK=m" >> $config_host_mak echo "CONFIG_GTKABI=$gtkabi" >> $config_host_mak echo "GTK_CFLAGS=$gtk_cflags" >> $config_host_mak echo "GTK_LIBS=$gtk_libs" >> $config_host_mak @@ -5211,6 +5209,7 @@ fi if test "$vte" = "yes" ; then echo "CONFIG_VTE=y" >> $config_host_mak echo "VTE_CFLAGS=$vte_cflags" >> $config_host_mak + echo "VTE_LIBS=$vte_libs" >> $config_host_mak fi if test "$virglrenderer" = "yes" ; then echo "CONFIG_VIRGL=y" >> $config_host_mak diff --git a/include/ui/console.h b/include/ui/console.h index 2703a3a..45f11e0 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -502,8 +502,14 @@ int index_from_key(const char *key, size_t key_length); /* gtk.c */ #ifdef CONFIG_GTK +bool gtk_mod_init(void); void early_gtk_display_init(int opengl); void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover); +void early_gtk_display_init_do(int opengl); +void gtk_display_init_do(DisplayState *ds, bool full_screen, + bool grab_on_hover); +void gtk_register_early_init_fun(void *fn); +void gtk_register_init_fun(void *fn); #else static inline void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover) diff --git a/ui/Makefile.objs b/ui/Makefile.objs index dc936f1..0e88c46 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -15,7 +15,11 @@ common-obj-$(CONFIG_SDL) += sdl.mo x_keymap.o common-obj-$(CONFIG_COCOA) += cocoa.o common-obj-$(CONFIG_CURSES) += curses.o common-obj-$(CONFIG_VNC) += $(vnc-obj-y) -common-obj-$(CONFIG_GTK) += gtk.o x_keymap.o +common-obj-$(CONFIG_GTK) += gtk.mo + +ifneq ($(CONFIG_GTK),) +common-obj-y += gtk-init.o x_keymap.o +endif ifeq ($(CONFIG_SDLABI),1.2) sdl.mo-objs := sdl.o sdl_zoom.o @@ -28,25 +32,27 @@ endif endif sdl.mo-cflags := $(SDL_CFLAGS) +gtk.mo-objs := gtk.o ifeq ($(CONFIG_OPENGL),y) common-obj-y += shader.o common-obj-y += console-gl.o common-obj-y += egl-helpers.o common-obj-y += egl-context.o ifeq ($(CONFIG_GTK_GL),y) -common-obj-$(CONFIG_GTK) += gtk-gl-area.o +gtk.mo-objs += gtk-gl-area.o else -common-obj-$(CONFIG_GTK) += gtk-egl.o +gtk.mo-objs += gtk-egl.o endif endif -gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) +gtk.mo-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) gtk-egl.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) $(OPENGL_CFLAGS) gtk-gl-area.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) $(OPENGL_CFLAGS) shader.o-cflags += $(OPENGL_CFLAGS) console-gl.o-cflags += $(OPENGL_CFLAGS) egl-helpers.o-cflags += $(OPENGL_CFLAGS) +gtk.mo-libs := $(GTK_LIBS) $(VTE_LIBS) gtk-egl.o-libs += $(OPENGL_LIBS) shader.o-libs += $(OPENGL_LIBS) console-gl.o-libs += $(OPENGL_LIBS) diff --git a/ui/gtk-init.c b/ui/gtk-init.c new file mode 100644 index 0000000..697972f --- /dev/null +++ b/ui/gtk-init.c @@ -0,0 +1,64 @@ +/* + * QEMU GTK display driver init function + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2016 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "ui/console.h" +#include "qemu/module.h" + +static void (*early_init_fn)(int opengl); +static void (*init_fn)(DisplayState *ds, bool full_screen, bool grab_on_hover); + +void gtk_register_early_init_fun(void *fn) +{ + assert(!early_init_fn); + early_init_fn = fn; +} + +void gtk_register_init_fun(void *fn) +{ + assert(!init_fn); + init_fn = fn; +} + +bool gtk_mod_init(void) +{ + module_load_one("ui-", "gtk"); + if (!early_init_fn || !init_fn) { + return false; + } + return true; +} + +void early_gtk_display_init(int opengl) +{ + assert(early_init_fn); + early_init_fn(opengl); +} + +void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover) +{ + assert(init_fn); + init_fn(ds, full_screen, grab_on_hover); +} diff --git a/ui/gtk.c b/ui/gtk.c index 58d20ee..a698144 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -2150,7 +2150,7 @@ static void gd_set_keycode_type(GtkDisplayState *s) static gboolean gtkinit; -void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover) +void gtk_display_init_do(DisplayState *ds, bool full_screen, bool grab_on_hover) { GtkDisplayState *s = g_malloc0(sizeof(*s)); char *filename; @@ -2240,7 +2240,7 @@ void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover) gd_set_keycode_type(s); } -void early_gtk_display_init(int opengl) +void early_gtk_display_init_do(int opengl) { /* The QEMU code relies on the assumption that it's always run in * the C locale. Therefore it is not prepared to deal with @@ -2288,3 +2288,10 @@ void early_gtk_display_init(int opengl) register_vc_handler(gd_vc_handler); #endif } + +__attribute__((constructor)) +static void gtk_init_fn(void) +{ + gtk_register_early_init_fun(early_gtk_display_init_do); + gtk_register_init_fun(gtk_display_init_do); +} diff --git a/vl.c b/vl.c index 1a5f807..5705a0a 100644 --- a/vl.c +++ b/vl.c @@ -4232,9 +4232,19 @@ int main(int argc, char **argv, char **envp) display_remote++; } #endif - if (display_type == DT_DEFAULT && !display_remote) { + if ((display_type == DT_DEFAULT && !display_remote) + || display_type == DT_GTK) { #if defined(CONFIG_GTK) - display_type = DT_GTK; + if (!gtk_mod_init()) { + if (display_type == DT_GTK) { + error_report("GTK could not be initialized, exiting"); + exit(1); + } + error_report("GTK could not be initialized, using display None"); + display_type = DT_NONE; + } else { + display_type = DT_GTK; + } #elif defined(CONFIG_SDL) display_type = DT_SDL; #elif defined(CONFIG_COCOA)