mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 19:49:43 +00:00
gtk: add opengl rendering support.
small bugfixes for gtk and opengl ui code. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJVaDUWAAoJEEy22O7T6HE4efQQAMnUoWwYLT882zI5DF07Viji +ZJ7QdEi+uj+/S9GKKpVmWRGsuiStgPVcIP4jop2IaoMjp8TWVIjkINS6mxlps3Z PMFjm/XIoWMpyQlU7kGWWoE2wU0JszAakwcOFaOcOOxxS7QpCzafRHkHUMEQc0TS trBgsY69VD9DxpEuC3tt9OAbmOmuMhpZxe5eYS2lyMGawYQRydxui0HNN3fsOIwY KuWKpOj4u2/oMlVHTNso1SzSZp0dsmLNR1z/RDQ8Q+5E4sRKL6XQUMZdSz+/CQVI lyi0Oll8H8v54tQB7PrpIw4HjqDbySxV9418SQQqOIoFliLMMdquSFEbAIEktQJz mfyEChQHevu1zUQlBRE+bbY6voDZ4Dmib/Az8OwRAe7LdG+gYDTScxt67Fr+jLLg rrq9zk329+91UofqUf5Bnfl199i2KqvV6buw85g/QhbXuPOFFHZj30qem0virodL X++EoHi1lfuwbAKrFfLLruCLp3dHw/arMxVQXPQ/6iFJSP0vbgSjGkFYJvjciO6L vQKMJsWkn/LJ9M2r/AOs6WvRXoDZ68pa5jp6tuAB3UTWEo7x7/mYsixiFwKV74HK on08TCqQaVQ9h2L9OdUgNMl/4nTbF402OPSFBAFCzzSAIVfvldw5PVAqrJZxMmEk ro0vR8KDvWOKy9L7VfiL =rTz0 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/pull-gtk-20150529-1' into staging gtk: add opengl rendering support. small bugfixes for gtk and opengl ui code. # gpg: Signature made Fri May 29 10:44:54 2015 BST using RSA key ID D3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" * remotes/kraxel/tags/pull-gtk-20150529-1: gtk: Replace gdk_cursor_new() gtk: add opengl support, using egl ui: add egl-helpers ui: shader.h protect against double inclusion ui: use libexpoxy Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
2a90c454a1
4
configure
vendored
4
configure
vendored
@ -3166,14 +3166,14 @@ else
|
||||
fi
|
||||
|
||||
if test "$opengl" != "no" ; then
|
||||
opengl_pkgs="gl glesv2"
|
||||
opengl_pkgs="gl glesv2 epoxy egl"
|
||||
if $pkg_config $opengl_pkgs x11 && test "$have_glx" = "yes"; then
|
||||
opengl_cflags="$($pkg_config --cflags $opengl_pkgs) $x11_cflags"
|
||||
opengl_libs="$($pkg_config --libs $opengl_pkgs) $x11_libs"
|
||||
opengl=yes
|
||||
else
|
||||
if test "$opengl" = "yes" ; then
|
||||
feature_not_found "opengl" "Install GL devel (e.g. MESA)"
|
||||
feature_not_found "opengl" "Please install opengl (mesa) devel pkgs: $opengl_pkgs"
|
||||
fi
|
||||
opengl_cflags=""
|
||||
opengl_libs=""
|
||||
|
@ -10,8 +10,7 @@
|
||||
#include "qapi/error.h"
|
||||
|
||||
#ifdef CONFIG_OPENGL
|
||||
# include <GLES2/gl2.h>
|
||||
# include <GLES2/gl2ext.h>
|
||||
# include <epoxy/gl.h>
|
||||
#endif
|
||||
|
||||
/* keyboard/mouse support */
|
||||
@ -394,7 +393,7 @@ void curses_display_init(DisplayState *ds, int full_screen);
|
||||
int index_from_key(const char *key);
|
||||
|
||||
/* gtk.c */
|
||||
void early_gtk_display_init(void);
|
||||
void early_gtk_display_init(int opengl);
|
||||
void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover);
|
||||
|
||||
#endif
|
||||
|
16
include/ui/egl-helpers.h
Normal file
16
include/ui/egl-helpers.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef EGL_HELPERS_H
|
||||
#define EGL_HELPERS_H
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
extern EGLDisplay *qemu_egl_display;
|
||||
extern EGLConfig qemu_egl_config;
|
||||
|
||||
EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win);
|
||||
|
||||
int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug);
|
||||
EGLContext qemu_egl_init_ctx(void);
|
||||
bool qemu_egl_has_ext(const char *haystack, const char *needle);
|
||||
|
||||
#endif /* EGL_HELPERS_H */
|
@ -22,6 +22,10 @@
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OPENGL)
|
||||
#include "ui/egl-helpers.h"
|
||||
#endif
|
||||
|
||||
/* Compatibility define to let us build on both Gtk2 and Gtk3 */
|
||||
#if GTK_CHECK_VERSION(3, 0, 0)
|
||||
static inline void gdk_drawable_get_size(GdkWindow *w, gint *ww, gint *wh)
|
||||
@ -41,6 +45,12 @@ typedef struct VirtualGfxConsole {
|
||||
cairo_surface_t *surface;
|
||||
double scale_x;
|
||||
double scale_y;
|
||||
#if defined(CONFIG_OPENGL)
|
||||
ConsoleGLState *gls;
|
||||
EGLContext ectx;
|
||||
EGLSurface esurface;
|
||||
int glupdates;
|
||||
#endif
|
||||
} VirtualGfxConsole;
|
||||
|
||||
#if defined(CONFIG_VTE)
|
||||
@ -73,4 +83,17 @@ typedef struct VirtualConsole {
|
||||
};
|
||||
} VirtualConsole;
|
||||
|
||||
/* ui/gtk.c */
|
||||
void gd_update_windowsize(VirtualConsole *vc);
|
||||
|
||||
/* ui/gtk-egl.c */
|
||||
void gd_egl_init(VirtualConsole *vc);
|
||||
void gd_egl_draw(VirtualConsole *vc);
|
||||
void gd_egl_update(DisplayChangeListener *dcl,
|
||||
int x, int y, int w, int h);
|
||||
void gd_egl_refresh(DisplayChangeListener *dcl);
|
||||
void gd_egl_switch(DisplayChangeListener *dcl,
|
||||
DisplaySurface *surface);
|
||||
void gtk_egl_init(void);
|
||||
|
||||
#endif /* UI_GTK_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifdef CONFIG_OPENGL
|
||||
# include <GLES2/gl2.h>
|
||||
# include <GLES2/gl2ext.h>
|
||||
#endif
|
||||
#ifndef QEMU_SHADER_H
|
||||
#define QEMU_SHADER_H
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
void qemu_gl_run_texture_blit(GLint texture_blit_prog);
|
||||
|
||||
@ -9,3 +9,5 @@ GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src);
|
||||
GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag);
|
||||
GLuint qemu_gl_create_compile_link_program(const GLchar *vert_src,
|
||||
const GLchar *frag_src);
|
||||
|
||||
#endif /* QEMU_SHADER_H */
|
||||
|
@ -30,11 +30,17 @@ sdl.mo-cflags := $(SDL_CFLAGS)
|
||||
ifeq ($(CONFIG_OPENGL),y)
|
||||
common-obj-y += shader.o
|
||||
common-obj-y += console-gl.o
|
||||
common-obj-y += egl-helpers.o
|
||||
common-obj-$(CONFIG_GTK) += gtk-egl.o
|
||||
endif
|
||||
|
||||
gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS)
|
||||
gtk-egl.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-egl.o-libs += $(OPENGL_LIBS)
|
||||
shader.o-libs += $(OPENGL_LIBS)
|
||||
console-gl.o-libs += $(OPENGL_LIBS)
|
||||
egl-helpers.o-libs += $(OPENGL_LIBS)
|
||||
|
148
ui/egl-helpers.c
Normal file
148
ui/egl-helpers.c
Normal file
@ -0,0 +1,148 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <glob.h>
|
||||
|
||||
#include "ui/egl-helpers.h"
|
||||
|
||||
EGLDisplay *qemu_egl_display;
|
||||
EGLConfig qemu_egl_config;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static bool egl_gles;
|
||||
static int egl_debug;
|
||||
|
||||
#define egl_dbg(_x ...) \
|
||||
do { \
|
||||
if (egl_debug) { \
|
||||
fprintf(stderr, "egl: " _x); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
|
||||
{
|
||||
EGLSurface esurface;
|
||||
EGLBoolean b;
|
||||
|
||||
egl_dbg("eglCreateWindowSurface (x11 win id 0x%lx) ...\n",
|
||||
(unsigned long) win);
|
||||
esurface = eglCreateWindowSurface(qemu_egl_display,
|
||||
qemu_egl_config,
|
||||
(EGLNativeWindowType)win, NULL);
|
||||
if (esurface == EGL_NO_SURFACE) {
|
||||
fprintf(stderr, "egl: eglCreateWindowSurface failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b = eglMakeCurrent(qemu_egl_display, esurface, esurface, ectx);
|
||||
if (b == EGL_FALSE) {
|
||||
fprintf(stderr, "egl: eglMakeCurrent failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return esurface;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
|
||||
{
|
||||
static const EGLint conf_att_gl[] = {
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_RED_SIZE, 5,
|
||||
EGL_GREEN_SIZE, 5,
|
||||
EGL_BLUE_SIZE, 5,
|
||||
EGL_ALPHA_SIZE, 0,
|
||||
EGL_NONE,
|
||||
};
|
||||
static const EGLint conf_att_gles[] = {
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_RED_SIZE, 5,
|
||||
EGL_GREEN_SIZE, 5,
|
||||
EGL_BLUE_SIZE, 5,
|
||||
EGL_ALPHA_SIZE, 0,
|
||||
EGL_NONE,
|
||||
};
|
||||
EGLint major, minor;
|
||||
EGLBoolean b;
|
||||
EGLint n;
|
||||
|
||||
if (debug) {
|
||||
egl_debug = 1;
|
||||
setenv("EGL_LOG_LEVEL", "debug", true);
|
||||
setenv("LIBGL_DEBUG", "verbose", true);
|
||||
}
|
||||
|
||||
egl_dbg("eglGetDisplay (dpy %p) ...\n", dpy);
|
||||
qemu_egl_display = eglGetDisplay(dpy);
|
||||
if (qemu_egl_display == EGL_NO_DISPLAY) {
|
||||
fprintf(stderr, "egl: eglGetDisplay failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
egl_dbg("eglInitialize ...\n");
|
||||
b = eglInitialize(qemu_egl_display, &major, &minor);
|
||||
if (b == EGL_FALSE) {
|
||||
fprintf(stderr, "egl: eglInitialize failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
egl_dbg("eglBindAPI ...\n");
|
||||
b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
|
||||
if (b == EGL_FALSE) {
|
||||
fprintf(stderr, "egl: eglBindAPI failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
egl_dbg("eglChooseConfig ...\n");
|
||||
b = eglChooseConfig(qemu_egl_display,
|
||||
gles ? conf_att_gles : conf_att_gl,
|
||||
&qemu_egl_config, 1, &n);
|
||||
if (b == EGL_FALSE || n != 1) {
|
||||
fprintf(stderr, "egl: eglChooseConfig failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
egl_gles = gles;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EGLContext qemu_egl_init_ctx(void)
|
||||
{
|
||||
static const EGLint ctx_att_gl[] = {
|
||||
EGL_NONE
|
||||
};
|
||||
static const EGLint ctx_att_gles[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
EGLContext ectx;
|
||||
EGLBoolean b;
|
||||
|
||||
egl_dbg("eglCreateContext ...\n");
|
||||
ectx = eglCreateContext(qemu_egl_display, qemu_egl_config, EGL_NO_CONTEXT,
|
||||
egl_gles ? ctx_att_gles : ctx_att_gl);
|
||||
if (ectx == EGL_NO_CONTEXT) {
|
||||
fprintf(stderr, "egl: eglCreateContext failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b = eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, ectx);
|
||||
if (b == EGL_FALSE) {
|
||||
fprintf(stderr, "egl: eglMakeCurrent failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ectx;
|
||||
}
|
141
ui/gtk-egl.c
Normal file
141
ui/gtk-egl.c
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* GTK UI -- egl opengl code.
|
||||
*
|
||||
* Note that gtk 3.16+ (released 2015-03-23) has a GtkGLArea widget,
|
||||
* which is GtkDrawingArea like widget with opengl rendering support.
|
||||
*
|
||||
* This code handles opengl support on older gtk versions, using egl
|
||||
* to get a opengl context for the X11 window.
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
|
||||
#include "trace.h"
|
||||
|
||||
#include "ui/console.h"
|
||||
#include "ui/gtk.h"
|
||||
#include "ui/egl-helpers.h"
|
||||
|
||||
#include "sysemu/sysemu.h"
|
||||
|
||||
/** DisplayState Callbacks (opengl version) **/
|
||||
|
||||
void gd_egl_init(VirtualConsole *vc)
|
||||
{
|
||||
GdkWindow *gdk_window = gtk_widget_get_window(vc->gfx.drawing_area);
|
||||
if (!gdk_window) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if GTK_CHECK_VERSION(3, 0, 0)
|
||||
Window x11_window = gdk_x11_window_get_xid(gdk_window);
|
||||
#else
|
||||
Window x11_window = gdk_x11_drawable_get_xid(gdk_window);
|
||||
#endif
|
||||
if (!x11_window) {
|
||||
return;
|
||||
}
|
||||
|
||||
vc->gfx.ectx = qemu_egl_init_ctx();
|
||||
vc->gfx.esurface = qemu_egl_init_surface_x11(vc->gfx.ectx, x11_window);
|
||||
|
||||
assert(vc->gfx.esurface);
|
||||
}
|
||||
|
||||
void gd_egl_draw(VirtualConsole *vc)
|
||||
{
|
||||
GdkWindow *window;
|
||||
int ww, wh;
|
||||
|
||||
if (!vc->gfx.gls || !vc->gfx.ds) {
|
||||
return;
|
||||
}
|
||||
|
||||
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
|
||||
vc->gfx.esurface, vc->gfx.ectx);
|
||||
|
||||
window = gtk_widget_get_window(vc->gfx.drawing_area);
|
||||
gdk_drawable_get_size(window, &ww, &wh);
|
||||
surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
|
||||
surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
|
||||
|
||||
eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
|
||||
}
|
||||
|
||||
void gd_egl_update(DisplayChangeListener *dcl,
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||
|
||||
if (!vc->gfx.gls || !vc->gfx.ds) {
|
||||
return;
|
||||
}
|
||||
|
||||
eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
|
||||
vc->gfx.esurface, vc->gfx.ectx);
|
||||
surface_gl_update_texture(vc->gfx.gls, vc->gfx.ds, x, y, w, h);
|
||||
vc->gfx.glupdates++;
|
||||
}
|
||||
|
||||
void gd_egl_refresh(DisplayChangeListener *dcl)
|
||||
{
|
||||
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||
|
||||
if (!vc->gfx.esurface) {
|
||||
gd_egl_init(vc);
|
||||
if (!vc->gfx.esurface) {
|
||||
return;
|
||||
}
|
||||
vc->gfx.gls = console_gl_init_context();
|
||||
if (vc->gfx.ds) {
|
||||
surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
|
||||
}
|
||||
}
|
||||
|
||||
graphic_hw_update(dcl->con);
|
||||
|
||||
if (vc->gfx.glupdates) {
|
||||
vc->gfx.glupdates = 0;
|
||||
gd_egl_draw(vc);
|
||||
}
|
||||
}
|
||||
|
||||
void gd_egl_switch(DisplayChangeListener *dcl,
|
||||
DisplaySurface *surface)
|
||||
{
|
||||
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||
bool resized = true;
|
||||
|
||||
trace_gd_switch(vc->label, surface_width(surface), surface_height(surface));
|
||||
|
||||
if (vc->gfx.ds &&
|
||||
surface_width(vc->gfx.ds) == surface_width(surface) &&
|
||||
surface_height(vc->gfx.ds) == surface_height(surface)) {
|
||||
resized = false;
|
||||
}
|
||||
|
||||
surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
|
||||
vc->gfx.ds = surface;
|
||||
if (vc->gfx.gls) {
|
||||
surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
|
||||
}
|
||||
|
||||
if (resized) {
|
||||
gd_update_windowsize(vc);
|
||||
}
|
||||
}
|
||||
|
||||
void gtk_egl_init(void)
|
||||
{
|
||||
GdkDisplay *gdk_display = gdk_display_get_default();
|
||||
Display *x11_display = gdk_x11_display_get_xdisplay(gdk_display);
|
||||
|
||||
if (qemu_egl_init_dpy(x11_display, false, false) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
display_opengl = 1;
|
||||
}
|
95
ui/gtk.c
95
ui/gtk.c
@ -339,7 +339,7 @@ static void gd_update_geometry_hints(VirtualConsole *vc)
|
||||
gtk_window_set_geometry_hints(geo_window, geo_widget, &geo, mask);
|
||||
}
|
||||
|
||||
static void gd_update_windowsize(VirtualConsole *vc)
|
||||
void gd_update_windowsize(VirtualConsole *vc)
|
||||
{
|
||||
GtkDisplayState *s = vc->s;
|
||||
|
||||
@ -581,6 +581,33 @@ static void gd_switch(DisplayChangeListener *dcl,
|
||||
}
|
||||
}
|
||||
|
||||
static const DisplayChangeListenerOps dcl_ops = {
|
||||
.dpy_name = "gtk",
|
||||
.dpy_gfx_update = gd_update,
|
||||
.dpy_gfx_switch = gd_switch,
|
||||
.dpy_gfx_check_format = qemu_pixman_check_format,
|
||||
.dpy_refresh = gd_refresh,
|
||||
.dpy_mouse_set = gd_mouse_set,
|
||||
.dpy_cursor_define = gd_cursor_define,
|
||||
};
|
||||
|
||||
|
||||
#if defined(CONFIG_OPENGL)
|
||||
|
||||
/** DisplayState Callbacks (opengl version) **/
|
||||
|
||||
static const DisplayChangeListenerOps dcl_egl_ops = {
|
||||
.dpy_name = "gtk-egl",
|
||||
.dpy_gfx_update = gd_egl_update,
|
||||
.dpy_gfx_switch = gd_egl_switch,
|
||||
.dpy_gfx_check_format = console_gl_check_format,
|
||||
.dpy_refresh = gd_egl_refresh,
|
||||
.dpy_mouse_set = gd_mouse_set,
|
||||
.dpy_cursor_define = gd_cursor_define,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/** QEMU Events **/
|
||||
|
||||
static void gd_change_runstate(void *opaque, int running, RunState state)
|
||||
@ -637,6 +664,13 @@ static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque)
|
||||
int ww, wh;
|
||||
int fbw, fbh;
|
||||
|
||||
#if defined(CONFIG_OPENGL)
|
||||
if (vc->gfx.gls) {
|
||||
gd_egl_draw(vc);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!gtk_widget_get_realized(widget)) {
|
||||
return FALSE;
|
||||
}
|
||||
@ -1676,16 +1710,6 @@ static GtkWidget *gd_create_menu_machine(GtkDisplayState *s)
|
||||
return machine_menu;
|
||||
}
|
||||
|
||||
static const DisplayChangeListenerOps dcl_ops = {
|
||||
.dpy_name = "gtk",
|
||||
.dpy_gfx_update = gd_update,
|
||||
.dpy_gfx_switch = gd_switch,
|
||||
.dpy_gfx_check_format = qemu_pixman_check_format,
|
||||
.dpy_refresh = gd_refresh,
|
||||
.dpy_mouse_set = gd_mouse_set,
|
||||
.dpy_cursor_define = gd_cursor_define,
|
||||
};
|
||||
|
||||
static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
|
||||
QemuConsole *con, int idx,
|
||||
GSList *group, GtkWidget *view_menu)
|
||||
@ -1713,7 +1737,29 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook),
|
||||
vc->tab_item, gtk_label_new(vc->label));
|
||||
|
||||
vc->gfx.dcl.ops = &dcl_ops;
|
||||
#if defined(CONFIG_OPENGL)
|
||||
if (display_opengl) {
|
||||
/*
|
||||
* gtk_widget_set_double_buffered() was deprecated in 3.14.
|
||||
* It is required for opengl rendering on X11 though. A
|
||||
* proper replacement (native opengl support) is only
|
||||
* available in 3.16+. Silence the warning if possible.
|
||||
*/
|
||||
#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);
|
||||
#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
vc->gfx.dcl.ops = &dcl_egl_ops;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
vc->gfx.dcl.ops = &dcl_ops;
|
||||
}
|
||||
|
||||
vc->gfx.dcl.con = con;
|
||||
register_displaychangelistener(&vc->gfx.dcl);
|
||||
|
||||
@ -1875,8 +1921,7 @@ void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
|
||||
{
|
||||
GtkDisplayState *s = g_malloc0(sizeof(*s));
|
||||
char *filename;
|
||||
|
||||
gtk_init(NULL, NULL);
|
||||
GdkDisplay *window_display;
|
||||
|
||||
s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
#if GTK_CHECK_VERSION(3, 2, 0)
|
||||
@ -1893,7 +1938,9 @@ void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
|
||||
bindtextdomain("qemu", CONFIG_QEMU_LOCALEDIR);
|
||||
textdomain("qemu");
|
||||
|
||||
s->null_cursor = gdk_cursor_new(GDK_BLANK_CURSOR);
|
||||
window_display = gtk_widget_get_display(s->window);
|
||||
s->null_cursor = gdk_cursor_new_for_display(window_display,
|
||||
GDK_BLANK_CURSOR);
|
||||
|
||||
s->mouse_mode_notifier.notify = gd_mouse_mode_change;
|
||||
qemu_add_mouse_mode_change_notifier(&s->mouse_mode_notifier);
|
||||
@ -1954,8 +2001,24 @@ void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
|
||||
gd_set_keycode_type(s);
|
||||
}
|
||||
|
||||
void early_gtk_display_init(void)
|
||||
void early_gtk_display_init(int opengl)
|
||||
{
|
||||
gtk_init(NULL, NULL);
|
||||
|
||||
switch (opengl) {
|
||||
case -1: /* default */
|
||||
case 0: /* off */
|
||||
break;
|
||||
case 1: /* on */
|
||||
#if defined(CONFIG_OPENGL)
|
||||
gtk_egl_init();
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_VTE)
|
||||
register_vc_handler(gd_vc_handler);
|
||||
#endif
|
||||
|
11
vl.c
11
vl.c
@ -2047,6 +2047,15 @@ static DisplayType select_display(const char *p)
|
||||
} else {
|
||||
goto invalid_gtk_args;
|
||||
}
|
||||
} else if (strstart(opts, ",gl=", &nextopt)) {
|
||||
opts = nextopt;
|
||||
if (strstart(opts, "on", &nextopt)) {
|
||||
request_opengl = 1;
|
||||
} else if (strstart(opts, "off", &nextopt)) {
|
||||
request_opengl = 0;
|
||||
} else {
|
||||
goto invalid_gtk_args;
|
||||
}
|
||||
} else {
|
||||
invalid_gtk_args:
|
||||
fprintf(stderr, "Invalid GTK option string: %s\n", p);
|
||||
@ -4012,7 +4021,7 @@ int main(int argc, char **argv, char **envp)
|
||||
|
||||
#if defined(CONFIG_GTK)
|
||||
if (display_type == DT_GTK) {
|
||||
early_gtk_display_init();
|
||||
early_gtk_display_init(request_opengl);
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_SDL)
|
||||
|
Loading…
Reference in New Issue
Block a user