[retro-gtk/wip/aplazas/gl-display: 1/2] Add RetroGLDisplay



commit 6858080d065ac22380760b4519b7fb13321f4329
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Sun Oct 15 09:36:05 2017 +0200

    Add RetroGLDisplay

 configure.ac                   |    4 +-
 retro-gtk/Makefile.am          |   53 ++-
 retro-gtk/glarea-fragment.glsl |    9 +
 retro-gtk/glarea-resources.c   | 1146 ++++++++++++++++++++++++++++++++++++++++
 retro-gtk/glarea.gresource.xml |    9 +
 retro-gtk/retro-core-view.c    |   32 +-
 retro-gtk/retro-gl-display.c   |  731 +++++++++++++++++++++++++
 retro-gtk/retro-gl-display.h   |   36 ++
 retro-gtk/retro-gtk-0.14.deps  |    1 +
 9 files changed, 1987 insertions(+), 34 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index d0ba1f1..ce08368 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,6 +10,8 @@ AM_SILENT_RULES([yes])
 
 AC_PROG_CC
 
+AC_PATH_PROG(GLIB_COMPILE_RESOURCES, glib-compile-resources)
+
 AM_PROG_AR
 
 # GResource
@@ -39,7 +41,7 @@ LT_INIT
 # retro-gtk
 ###########
 
-retro_gtk_pkg_modules="gobject-2.0 glib-2.0 gmodule-2.0 gio-2.0 gtk+-3.0 cairo libpulse libpulse-simple"
+retro_gtk_pkg_modules="gobject-2.0 glib-2.0 gmodule-2.0 gio-2.0 gtk+-3.0 cairo epoxy libpulse 
libpulse-simple"
 PKG_CHECK_MODULES(RETRO_GTK, $retro_gtk_pkg_modules)
 AC_SUBST(retro_gtk_pkg_modules)
 
diff --git a/retro-gtk/Makefile.am b/retro-gtk/Makefile.am
index 18da904..4840d5f 100644
--- a/retro-gtk/Makefile.am
+++ b/retro-gtk/Makefile.am
@@ -23,9 +23,25 @@ AM_CFLAGS =\
 
 lib_LTLIBRARIES = libretro-gtk.la
 
-vapidir = $(datadir)/vala/vapi
-vapi_DATA = retro-gtk-0.14.vapi
-dist_vapi_DATA = retro-gtk-0.14.deps
+# vapidir = $(datadir)/vala/vapi
+# vapi_DATA = retro-gtk-0.14.vapi
+# dist_vapi_DATA = retro-gtk-0.14.deps
+
+gresource_file = glarea.gresource.xml
+
+resource_files = $(shell \
+       $(GLIB_COMPILE_RESOURCES) \
+       --generate-dependencies \
+       --sourcedir=$(top_srcdir)/data \
+       $(gresource_file) \
+)
+
+resources.c: $(gresource_file) $(resource_files)
+       $(AM_V_GEN) \
+       $(GLIB_COMPILE_RESOURCES) \
+               --target=$@ \
+               --generate-source \
+               $<
 
 retro_gtk_public_h_sources = \
        retro-analog-id.h \
@@ -59,6 +75,7 @@ retro_gtk_private_h_sources = \
        retro-core-view-controller.h \
        retro-disk-control-callback.h \
        retro-game-info.h \
+       retro-gl-display.h \
        retro-input-descriptor.h \
        retro-keyboard-key.h \
        retro-module.h \
@@ -74,6 +91,7 @@ retro_gtk_private_h_sources = \
        $(NULL)
 
 libretro_gtk_la_SOURCES = \
+       resources.c \
        retro-analog-id.c \
        retro-analog-index.c \
        retro-cairo-display.c \
@@ -84,6 +102,7 @@ libretro_gtk_la_SOURCES = \
        retro-core-view.c \
        retro-core-view-controller.c \
        retro-game-info.c \
+       retro-gl-display.c \
        retro-input-descriptor.c \
        retro-joypad-id.c \
        retro-keyboard-key.c \
@@ -109,7 +128,7 @@ libretro_gtk_la_SOURCES = \
 
 libretro_gtk_la_LDFLAGS =
 
-libretro_gtk_la_LIBADD = $(RETRO_GTK_LIBS)
+libretro_gtk_la_LIBADD = $(RETRO_GTK_LIBS) -lm
 
 retro_gtkincludedir = $(includedir)/retro-gtk-0.14
 retro_gtkinclude_HEADERS = \
@@ -143,19 +162,19 @@ Retro_0_14_gir_LIBS = libretro-gtk.la
 Retro_0_14_gir_FILES = $(introspection_sources)
 Retro_0_14_gir_EXPORT_PACKAGES = retro-gtk-0.14
 
-retro-gtk-0.14.vapi: Retro-0.14.gir
-       vapigen \
-               --library retro-gtk-0.14 \
-               --pkg cairo \
-               --pkg gio-2.0  \
-               --pkg glib-2.0 \
-               --pkg gmodule-2.0 \
-               --pkg gobject-2.0 \
-               --pkg gtk+-3.0 \
-               --pkg libpulse \
-               --pkg libpulse-simple \
-               $< \
-               $(NULL)
+# retro-gtk-0.14.vapi: Retro-0.14.gir
+#      vapigen \
+#              --library retro-gtk-0.14 \
+#              --pkg cairo \
+#              --pkg gio-2.0  \
+#              --pkg glib-2.0 \
+#              --pkg gmodule-2.0 \
+#              --pkg gobject-2.0 \
+#              --pkg gtk+-3.0 \
+#              --pkg libpulse \
+#              --pkg libpulse-simple \
+#              $< \
+#              $(NULL)
 
 CLEANFILES = $(gir_DATA) $(typelib_DATA) $(vapi_DATA)
 
diff --git a/retro-gtk/glarea-fragment.glsl b/retro-gtk/glarea-fragment.glsl
new file mode 100644
index 0000000..c331ad2
--- /dev/null
+++ b/retro-gtk/glarea-fragment.glsl
@@ -0,0 +1,9 @@
+#version 130
+
+smooth in vec4 vertexColor;
+
+out vec4 outputColor;
+
+void main() {
+  outputColor = vertexColor;
+}
diff --git a/retro-gtk/glarea-resources.c b/retro-gtk/glarea-resources.c
new file mode 100644
index 0000000..268a486
--- /dev/null
+++ b/retro-gtk/glarea-resources.c
@@ -0,0 +1,1146 @@
+#include <gio/gio.h>
+
+#if defined (__ELF__) && ( __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6))
+# define SECTION __attribute__ ((section (".gresource.glarea"), aligned (8)))
+#else
+# define SECTION
+#endif
+
+static const SECTION union { const guint8 data[7868]; const double alignment; void * const ptr;}  
glarea_resource_data = { {
+  0x47, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x18, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 
+  0x00, 0x00, 0x00, 0x28, 0x08, 0x00, 0x00, 0x00, 
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+  0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 
+  0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+  0xa2, 0x63, 0x10, 0xb4, 0x07, 0x00, 0x00, 0x00, 
+  0x00, 0x01, 0x00, 0x00, 0x14, 0x00, 0x76, 0x00, 
+  0x18, 0x01, 0x00, 0x00, 0xaa, 0x1b, 0x00, 0x00, 
+  0x7b, 0xa2, 0x78, 0x7c, 0x02, 0x00, 0x00, 0x00, 
+  0xaa, 0x1b, 0x00, 0x00, 0x03, 0x00, 0x4c, 0x00, 
+  0xb0, 0x1b, 0x00, 0x00, 0xb4, 0x1b, 0x00, 0x00, 
+  0xd4, 0xb5, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 
+  0xb4, 0x1b, 0x00, 0x00, 0x01, 0x00, 0x4c, 0x00, 
+  0xb8, 0x1b, 0x00, 0x00, 0xbc, 0x1b, 0x00, 0x00, 
+  0xbc, 0x2f, 0xdb, 0x38, 0x01, 0x00, 0x00, 0x00, 
+  0xbc, 0x1b, 0x00, 0x00, 0x06, 0x00, 0x4c, 0x00, 
+  0xc4, 0x1b, 0x00, 0x00, 0xc8, 0x1b, 0x00, 0x00, 
+  0xc4, 0x65, 0x97, 0x9f, 0x07, 0x00, 0x00, 0x00, 
+  0xc8, 0x1b, 0x00, 0x00, 0x14, 0x00, 0x76, 0x00, 
+  0xe0, 0x1b, 0x00, 0x00, 0x5f, 0x1c, 0x00, 0x00, 
+  0x2e, 0x1d, 0x27, 0x4f, 0x07, 0x00, 0x00, 0x00, 
+  0x5f, 0x1c, 0x00, 0x00, 0x12, 0x00, 0x76, 0x00, 
+  0x78, 0x1c, 0x00, 0x00, 0x46, 0x1d, 0x00, 0x00, 
+  0xff, 0x36, 0xd2, 0x5b, 0x07, 0x00, 0x00, 0x00, 
+  0x46, 0x1d, 0x00, 0x00, 0x12, 0x00, 0x76, 0x00, 
+  0x58, 0x1d, 0x00, 0x00, 0xa3, 0x1e, 0x00, 0x00, 
+  0x37, 0xc0, 0x9f, 0xe6, 0x03, 0x00, 0x00, 0x00, 
+  0xa3, 0x1e, 0x00, 0x00, 0x07, 0x00, 0x4c, 0x00, 
+  0xac, 0x1e, 0x00, 0x00, 0xbc, 0x1e, 0x00, 0x00, 
+  0x67, 0x6c, 0x61, 0x72, 0x65, 0x61, 0x2d, 0x61, 
+  0x70, 0x70, 0x2d, 0x77, 0x69, 0x6e, 0x64, 0x6f, 
+  0x77, 0x2e, 0x75, 0x69, 0x00, 0x00, 0x00, 0x00, 
+  0x82, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x3c, 0x3f, 0x78, 0x6d, 0x6c, 0x20, 0x76, 0x65, 
+  0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 
+  0x2e, 0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 
+  0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x55, 0x54, 
+  0x46, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x0a, 0x3c, 
+  0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 
+  0x65, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x69, 
+  0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 
+  0x2d, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 
+  0x73, 0x20, 0x67, 0x74, 0x6b, 0x2b, 0x20, 0x33, 
+  0x2e, 0x31, 0x36, 0x20, 0x2d, 0x2d, 0x3e, 0x3c, 
+  0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 
+  0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 
+  0x6b, 0x41, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x6d, 
+  0x65, 0x6e, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3d, 
+  0x22, 0x78, 0x5f, 0x61, 0x64, 0x6a, 0x75, 0x73, 
+  0x74, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x75, 
+  0x70, 0x70, 0x65, 0x72, 0x22, 0x3e, 0x33, 0x36, 
+  0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 
+  0x6d, 0x65, 0x3d, 0x22, 0x73, 0x74, 0x65, 0x70, 
+  0x5f, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 
+  0x6e, 0x74, 0x22, 0x3e, 0x31, 0x3c, 0x2f, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 
+  0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 
+  0x70, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x63, 
+  0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x3e, 
+  0x31, 0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x73, 0x69, 
+  0x67, 0x6e, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 
+  0x2d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 
+  0x22, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 
+  0x72, 0x3d, 0x22, 0x61, 0x64, 0x6a, 0x75, 0x73, 
+  0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x68, 
+  0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, 0x20, 0x6f, 
+  0x62, 0x6a, 0x65, 0x63, 0x74, 0x3d, 0x22, 0x47, 
+  0x6c, 0x61, 0x72, 0x65, 0x61, 0x41, 0x70, 0x70, 
+  0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 0x20, 
+  0x73, 0x77, 0x61, 0x70, 0x70, 0x65, 0x64, 0x3d, 
+  0x22, 0x79, 0x65, 0x73, 0x22, 0x2f, 0x3e, 0x3c, 
+  0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 
+  0x3c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 
+  0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x47, 
+  0x74, 0x6b, 0x41, 0x64, 0x6a, 0x75, 0x73, 0x74, 
+  0x6d, 0x65, 0x6e, 0x74, 0x22, 0x20, 0x69, 0x64, 
+  0x3d, 0x22, 0x79, 0x5f, 0x61, 0x64, 0x6a, 0x75, 
+  0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x3e, 
+  0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 
+  0x75, 0x70, 0x70, 0x65, 0x72, 0x22, 0x3e, 0x33, 
+  0x36, 0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 
+  0x61, 0x6d, 0x65, 0x3d, 0x22, 0x73, 0x74, 0x65, 
+  0x70, 0x5f, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 
+  0x65, 0x6e, 0x74, 0x22, 0x3e, 0x31, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 
+  0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x22, 
+  0x3e, 0x31, 0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x73, 
+  0x69, 0x67, 0x6e, 0x61, 0x6c, 0x20, 0x6e, 0x61, 
+  0x6d, 0x65, 0x3d, 0x22, 0x76, 0x61, 0x6c, 0x75, 
+  0x65, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 
+  0x64, 0x22, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 
+  0x65, 0x72, 0x3d, 0x22, 0x61, 0x64, 0x6a, 0x75, 
+  0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 
+  0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, 0x20, 
+  0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3d, 0x22, 
+  0x47, 0x6c, 0x61, 0x72, 0x65, 0x61, 0x41, 0x70, 
+  0x70, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 
+  0x20, 0x73, 0x77, 0x61, 0x70, 0x70, 0x65, 0x64, 
+  0x3d, 0x22, 0x79, 0x65, 0x73, 0x22, 0x2f, 0x3e, 
+  0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 
+  0x3e, 0x3c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 
+  0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 
+  0x47, 0x74, 0x6b, 0x41, 0x64, 0x6a, 0x75, 0x73, 
+  0x74, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x20, 0x69, 
+  0x64, 0x3d, 0x22, 0x7a, 0x5f, 0x61, 0x64, 0x6a, 
+  0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x22, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x75, 0x70, 0x70, 0x65, 0x72, 0x22, 0x3e, 
+  0x33, 0x36, 0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x73, 0x74, 
+  0x65, 0x70, 0x5f, 0x69, 0x6e, 0x63, 0x72, 0x65, 
+  0x6d, 0x65, 0x6e, 0x74, 0x22, 0x3e, 0x31, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x69, 
+  0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 
+  0x22, 0x3e, 0x31, 0x30, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x20, 0x6e, 
+  0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 0x61, 0x6c, 
+  0x75, 0x65, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x67, 
+  0x65, 0x64, 0x22, 0x20, 0x68, 0x61, 0x6e, 0x64, 
+  0x6c, 0x65, 0x72, 0x3d, 0x22, 0x61, 0x64, 0x6a, 
+  0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 
+  0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, 
+  0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3d, 
+  0x22, 0x47, 0x6c, 0x61, 0x72, 0x65, 0x61, 0x41, 
+  0x70, 0x70, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 
+  0x22, 0x20, 0x73, 0x77, 0x61, 0x70, 0x70, 0x65, 
+  0x64, 0x3d, 0x22, 0x79, 0x65, 0x73, 0x22, 0x2f, 
+  0x3e, 0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 
+  0x74, 0x3e, 0x3c, 0x74, 0x65, 0x6d, 0x70, 0x6c, 
+  0x61, 0x74, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 
+  0x73, 0x3d, 0x22, 0x47, 0x6c, 0x61, 0x72, 0x65, 
+  0x61, 0x41, 0x70, 0x70, 0x57, 0x69, 0x6e, 0x64, 
+  0x6f, 0x77, 0x22, 0x20, 0x70, 0x61, 0x72, 0x65, 
+  0x6e, 0x74, 0x3d, 0x22, 0x47, 0x74, 0x6b, 0x41, 
+  0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 
+  0x6f, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 
+  0x22, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x63, 0x61, 0x6e, 0x5f, 0x66, 0x6f, 
+  0x63, 0x75, 0x73, 0x22, 0x3e, 0x46, 0x61, 0x6c, 
+  0x73, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 
+  0x61, 0x6d, 0x65, 0x3d, 0x22, 0x62, 0x6f, 0x72, 
+  0x64, 0x65, 0x72, 0x5f, 0x77, 0x69, 0x64, 0x74, 
+  0x68, 0x22, 0x3e, 0x36, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x64, 
+  0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x77, 
+  0x69, 0x64, 0x74, 0x68, 0x22, 0x3e, 0x34, 0x30, 
+  0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 
+  0x6d, 0x65, 0x3d, 0x22, 0x64, 0x65, 0x66, 0x61, 
+  0x75, 0x6c, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 
+  0x68, 0x74, 0x22, 0x3e, 0x36, 0x30, 0x30, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x63, 0x68, 0x69, 0x6c, 0x64, 
+  0x3e, 0x3c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 
+  0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 
+  0x47, 0x74, 0x6b, 0x42, 0x6f, 0x78, 0x22, 0x20, 
+  0x69, 0x64, 0x3d, 0x22, 0x6d, 0x61, 0x69, 0x6e, 
+  0x5f, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 0x69, 
+  0x73, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x3e, 0x54, 
+  0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x63, 0x61, 
+  0x6e, 0x5f, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x22, 
+  0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 
+  0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3e, 0x76, 0x65, 
+  0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 
+  0x22, 0x3e, 0x36, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x63, 
+  0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x6f, 0x62, 
+  0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 0x6c, 0x61, 
+  0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 0x6b, 0x47, 
+  0x4c, 0x41, 0x72, 0x65, 0x61, 0x22, 0x20, 0x69, 
+  0x64, 0x3d, 0x22, 0x67, 0x6c, 0x5f, 0x64, 0x72, 
+  0x61, 0x77, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x72, 
+  0x65, 0x61, 0x22, 0x3e, 0x3c, 0x73, 0x69, 0x67, 
+  0x6e, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x72, 0x65, 0x61, 0x6c, 0x69, 0x7a, 
+  0x65, 0x22, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 
+  0x65, 0x72, 0x3d, 0x22, 0x67, 0x6c, 0x5f, 0x69, 
+  0x6e, 0x69, 0x74, 0x22, 0x20, 0x6f, 0x62, 0x6a, 
+  0x65, 0x63, 0x74, 0x3d, 0x22, 0x47, 0x6c, 0x61, 
+  0x72, 0x65, 0x61, 0x41, 0x70, 0x70, 0x57, 0x69, 
+  0x6e, 0x64, 0x6f, 0x77, 0x22, 0x20, 0x73, 0x77, 
+  0x61, 0x70, 0x70, 0x65, 0x64, 0x3d, 0x22, 0x79, 
+  0x65, 0x73, 0x22, 0x2f, 0x3e, 0x3c, 0x73, 0x69, 
+  0x67, 0x6e, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x75, 0x6e, 0x72, 0x65, 0x61, 
+  0x6c, 0x69, 0x7a, 0x65, 0x22, 0x20, 0x68, 0x61, 
+  0x6e, 0x64, 0x6c, 0x65, 0x72, 0x3d, 0x22, 0x67, 
+  0x6c, 0x5f, 0x66, 0x69, 0x6e, 0x69, 0x22, 0x20, 
+  0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3d, 0x22, 
+  0x47, 0x6c, 0x61, 0x72, 0x65, 0x61, 0x41, 0x70, 
+  0x70, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 
+  0x20, 0x73, 0x77, 0x61, 0x70, 0x70, 0x65, 0x64, 
+  0x3d, 0x22, 0x79, 0x65, 0x73, 0x22, 0x2f, 0x3e, 
+  0x3c, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x72, 0x65, 
+  0x6e, 0x64, 0x65, 0x72, 0x22, 0x20, 0x68, 0x61, 
+  0x6e, 0x64, 0x6c, 0x65, 0x72, 0x3d, 0x22, 0x67, 
+  0x6c, 0x5f, 0x64, 0x72, 0x61, 0x77, 0x22, 0x20, 
+  0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3d, 0x22, 
+  0x47, 0x6c, 0x61, 0x72, 0x65, 0x61, 0x41, 0x70, 
+  0x70, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 
+  0x20, 0x73, 0x77, 0x61, 0x70, 0x70, 0x65, 0x64, 
+  0x3d, 0x22, 0x79, 0x65, 0x73, 0x22, 0x2f, 0x3e, 
+  0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 
+  0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x22, 
+  0x3e, 0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 
+  0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 
+  0x63, 0x61, 0x6e, 0x5f, 0x66, 0x6f, 0x63, 0x75, 
+  0x73, 0x22, 0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x68, 0x65, 0x78, 0x70, 0x61, 
+  0x6e, 0x64, 0x22, 0x3e, 0x54, 0x72, 0x75, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x76, 0x65, 0x78, 0x70, 0x61, 
+  0x6e, 0x64, 0x22, 0x3e, 0x54, 0x72, 0x75, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x2f, 0x6f, 0x62, 0x6a, 
+  0x65, 0x63, 0x74, 0x3e, 0x3c, 0x2f, 0x63, 0x68, 
+  0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x63, 0x68, 0x69, 
+  0x6c, 0x64, 0x3e, 0x3c, 0x6f, 0x62, 0x6a, 0x65, 
+  0x63, 0x74, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 
+  0x3d, 0x22, 0x47, 0x74, 0x6b, 0x42, 0x6f, 0x78, 
+  0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x63, 0x6f, 
+  0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x73, 0x5f, 0x62, 
+  0x6f, 0x78, 0x22, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 
+  0x6d, 0x65, 0x3d, 0x22, 0x76, 0x69, 0x73, 0x69, 
+  0x62, 0x6c, 0x65, 0x22, 0x3e, 0x54, 0x72, 0x75, 
+  0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 
+  0x6d, 0x65, 0x3d, 0x22, 0x63, 0x61, 0x6e, 0x5f, 
+  0x66, 0x6f, 0x63, 0x75, 0x73, 0x22, 0x3e, 0x46, 
+  0x61, 0x6c, 0x73, 0x65, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x62, 
+  0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x77, 0x69, 
+  0x64, 0x74, 0x68, 0x22, 0x3e, 0x32, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 
+  0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3e, 0x76, 0x65, 
+  0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 
+  0x22, 0x3e, 0x36, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x63, 
+  0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x6f, 0x62, 
+  0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 0x6c, 0x61, 
+  0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 0x6b, 0x42, 
+  0x6f, 0x78, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 
+  0x78, 0x5f, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 
+  0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x3e, 
+  0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x63, 
+  0x61, 0x6e, 0x5f, 0x66, 0x6f, 0x63, 0x75, 0x73, 
+  0x22, 0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 
+  0x67, 0x22, 0x3e, 0x36, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x6f, 
+  0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 0x6c, 
+  0x61, 0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 0x6b, 
+  0x4c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x20, 0x69, 
+  0x64, 0x3d, 0x22, 0x6c, 0x61, 0x62, 0x65, 0x6c, 
+  0x31, 0x22, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x76, 0x69, 0x73, 0x69, 0x62, 
+  0x6c, 0x65, 0x22, 0x3e, 0x54, 0x72, 0x75, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x63, 0x61, 0x6e, 0x5f, 0x66, 
+  0x6f, 0x63, 0x75, 0x73, 0x22, 0x3e, 0x46, 0x61, 
+  0x6c, 0x73, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6c, 0x61, 
+  0x62, 0x65, 0x6c, 0x22, 0x20, 0x74, 0x72, 0x61, 
+  0x6e, 0x73, 0x6c, 0x61, 0x74, 0x61, 0x62, 0x6c, 
+  0x65, 0x3d, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3e, 
+  0x58, 0x20, 0x41, 0x78, 0x69, 0x73, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 
+  0x74, 0x3e, 0x3c, 0x70, 0x61, 0x63, 0x6b, 0x69, 
+  0x6e, 0x67, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x65, 0x78, 0x70, 0x61, 0x6e, 
+  0x64, 0x22, 0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x6c, 0x22, 
+  0x3e, 0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 
+  0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 
+  0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 
+  0x22, 0x3e, 0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 
+  0x70, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 
+  0x3c, 0x2f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 
+  0x3c, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 
+  0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 
+  0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 
+  0x6b, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x22, 0x20, 
+  0x69, 0x64, 0x3d, 0x22, 0x78, 0x5f, 0x73, 0x63, 
+  0x61, 0x6c, 0x65, 0x22, 0x3e, 0x3c, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 
+  0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 0x69, 0x73, 
+  0x69, 0x62, 0x6c, 0x65, 0x22, 0x3e, 0x54, 0x72, 
+  0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 
+  0x61, 0x6d, 0x65, 0x3d, 0x22, 0x63, 0x61, 0x6e, 
+  0x5f, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x22, 0x3e, 
+  0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 
+  0x64, 0x6a, 0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 
+  0x74, 0x22, 0x3e, 0x78, 0x5f, 0x61, 0x64, 0x6a, 
+  0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x66, 0x69, 0x6c, 0x6c, 0x5f, 0x6c, 
+  0x65, 0x76, 0x65, 0x6c, 0x22, 0x3e, 0x33, 0x36, 
+  0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 
+  0x6d, 0x65, 0x3d, 0x22, 0x72, 0x6f, 0x75, 0x6e, 
+  0x64, 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x73, 
+  0x22, 0x3e, 0x31, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 0x61, 
+  0x6c, 0x75, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x22, 
+  0x3e, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 
+  0x74, 0x3e, 0x3c, 0x70, 0x61, 0x63, 0x6b, 0x69, 
+  0x6e, 0x67, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x65, 0x78, 0x70, 0x61, 0x6e, 
+  0x64, 0x22, 0x3e, 0x54, 0x72, 0x75, 0x65, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x66, 0x69, 0x6c, 0x6c, 0x22, 0x3e, 
+  0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x70, 
+  0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 
+  0x3e, 0x31, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 0x70, 
+  0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 0x3c, 
+  0x2f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 
+  0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 
+  0x3c, 0x70, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x22, 
+  0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x66, 0x69, 0x6c, 0x6c, 0x22, 0x3e, 0x54, 
+  0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x70, 0x6f, 
+  0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3e, 
+  0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 0x70, 0x61, 
+  0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 0x3c, 0x2f, 
+  0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x63, 
+  0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x6f, 0x62, 
+  0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 0x6c, 0x61, 
+  0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 0x6b, 0x42, 
+  0x6f, 0x78, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 
+  0x79, 0x5f, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 
+  0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x3e, 
+  0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x63, 
+  0x61, 0x6e, 0x5f, 0x66, 0x6f, 0x63, 0x75, 0x73, 
+  0x22, 0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 
+  0x67, 0x22, 0x3e, 0x36, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x6f, 
+  0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 0x6c, 
+  0x61, 0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 0x6b, 
+  0x4c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x20, 0x69, 
+  0x64, 0x3d, 0x22, 0x6c, 0x61, 0x62, 0x65, 0x6c, 
+  0x32, 0x22, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x76, 0x69, 0x73, 0x69, 0x62, 
+  0x6c, 0x65, 0x22, 0x3e, 0x54, 0x72, 0x75, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x63, 0x61, 0x6e, 0x5f, 0x66, 
+  0x6f, 0x63, 0x75, 0x73, 0x22, 0x3e, 0x46, 0x61, 
+  0x6c, 0x73, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6c, 0x61, 
+  0x62, 0x65, 0x6c, 0x22, 0x20, 0x74, 0x72, 0x61, 
+  0x6e, 0x73, 0x6c, 0x61, 0x74, 0x61, 0x62, 0x6c, 
+  0x65, 0x3d, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3e, 
+  0x59, 0x20, 0x41, 0x78, 0x69, 0x73, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 
+  0x74, 0x3e, 0x3c, 0x70, 0x61, 0x63, 0x6b, 0x69, 
+  0x6e, 0x67, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x65, 0x78, 0x70, 0x61, 0x6e, 
+  0x64, 0x22, 0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x6c, 0x22, 
+  0x3e, 0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 
+  0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 
+  0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 
+  0x22, 0x3e, 0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 
+  0x70, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 
+  0x3c, 0x2f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 
+  0x3c, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 
+  0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 
+  0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 
+  0x6b, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x22, 0x20, 
+  0x69, 0x64, 0x3d, 0x22, 0x79, 0x5f, 0x73, 0x63, 
+  0x61, 0x6c, 0x65, 0x22, 0x3e, 0x3c, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 
+  0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 0x69, 0x73, 
+  0x69, 0x62, 0x6c, 0x65, 0x22, 0x3e, 0x54, 0x72, 
+  0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 
+  0x61, 0x6d, 0x65, 0x3d, 0x22, 0x63, 0x61, 0x6e, 
+  0x5f, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x22, 0x3e, 
+  0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 
+  0x64, 0x6a, 0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 
+  0x74, 0x22, 0x3e, 0x79, 0x5f, 0x61, 0x64, 0x6a, 
+  0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x66, 0x69, 0x6c, 0x6c, 0x5f, 0x6c, 
+  0x65, 0x76, 0x65, 0x6c, 0x22, 0x3e, 0x33, 0x36, 
+  0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 
+  0x6d, 0x65, 0x3d, 0x22, 0x72, 0x6f, 0x75, 0x6e, 
+  0x64, 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 0x73, 
+  0x22, 0x3e, 0x31, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 0x61, 
+  0x6c, 0x75, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x22, 
+  0x3e, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 
+  0x74, 0x3e, 0x3c, 0x70, 0x61, 0x63, 0x6b, 0x69, 
+  0x6e, 0x67, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x65, 0x78, 0x70, 0x61, 0x6e, 
+  0x64, 0x22, 0x3e, 0x54, 0x72, 0x75, 0x65, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x66, 0x69, 0x6c, 0x6c, 0x22, 0x3e, 
+  0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x70, 
+  0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 
+  0x3e, 0x31, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 0x70, 
+  0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 0x3c, 
+  0x2f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 
+  0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 
+  0x3c, 0x70, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x22, 
+  0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x66, 0x69, 0x6c, 0x6c, 0x22, 0x3e, 0x54, 
+  0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x70, 0x6f, 
+  0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3e, 
+  0x31, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 0x70, 0x61, 
+  0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 0x3c, 0x2f, 
+  0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x63, 
+  0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x6f, 0x62, 
+  0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 0x6c, 0x61, 
+  0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 0x6b, 0x42, 
+  0x6f, 0x78, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 
+  0x7a, 0x5f, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 
+  0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x3e, 
+  0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x63, 
+  0x61, 0x6e, 0x5f, 0x66, 0x6f, 0x63, 0x75, 0x73, 
+  0x22, 0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 
+  0x67, 0x22, 0x3e, 0x36, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x6f, 
+  0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 0x6c, 
+  0x61, 0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 0x6b, 
+  0x4c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x20, 0x69, 
+  0x64, 0x3d, 0x22, 0x6c, 0x61, 0x62, 0x65, 0x6c, 
+  0x33, 0x22, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x76, 0x69, 0x73, 0x69, 0x62, 
+  0x6c, 0x65, 0x22, 0x3e, 0x54, 0x72, 0x75, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x63, 0x61, 0x6e, 0x5f, 0x66, 
+  0x6f, 0x63, 0x75, 0x73, 0x22, 0x3e, 0x46, 0x61, 
+  0x6c, 0x73, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6c, 0x61, 
+  0x62, 0x65, 0x6c, 0x22, 0x20, 0x74, 0x72, 0x61, 
+  0x6e, 0x73, 0x6c, 0x61, 0x74, 0x61, 0x62, 0x6c, 
+  0x65, 0x3d, 0x22, 0x79, 0x65, 0x73, 0x22, 0x3e, 
+  0x5a, 0x20, 0x41, 0x78, 0x69, 0x73, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 
+  0x74, 0x3e, 0x3c, 0x70, 0x61, 0x63, 0x6b, 0x69, 
+  0x6e, 0x67, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x65, 0x78, 0x70, 0x61, 0x6e, 
+  0x64, 0x22, 0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x6c, 0x22, 
+  0x3e, 0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 
+  0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 
+  0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 
+  0x22, 0x3e, 0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 
+  0x70, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 
+  0x3c, 0x2f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 
+  0x3c, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 
+  0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 
+  0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 
+  0x6b, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x22, 0x20, 
+  0x69, 0x64, 0x3d, 0x22, 0x78, 0x5f, 0x73, 0x63, 
+  0x61, 0x6c, 0x65, 0x31, 0x22, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 0x69, 
+  0x73, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x3e, 0x54, 
+  0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x63, 0x61, 
+  0x6e, 0x5f, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x22, 
+  0x3e, 0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 
+  0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 
+  0x61, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x6d, 0x65, 
+  0x6e, 0x74, 0x22, 0x3e, 0x7a, 0x5f, 0x61, 0x64, 
+  0x6a, 0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x6c, 0x5f, 
+  0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x3e, 0x33, 
+  0x36, 0x30, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 
+  0x61, 0x6d, 0x65, 0x3d, 0x22, 0x72, 0x6f, 0x75, 
+  0x6e, 0x64, 0x5f, 0x64, 0x69, 0x67, 0x69, 0x74, 
+  0x73, 0x22, 0x3e, 0x31, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 
+  0x61, 0x6c, 0x75, 0x65, 0x5f, 0x70, 0x6f, 0x73, 
+  0x22, 0x3e, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 
+  0x63, 0x74, 0x3e, 0x3c, 0x70, 0x61, 0x63, 0x6b, 
+  0x69, 0x6e, 0x67, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 
+  0x6d, 0x65, 0x3d, 0x22, 0x65, 0x78, 0x70, 0x61, 
+  0x6e, 0x64, 0x22, 0x3e, 0x54, 0x72, 0x75, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x6c, 0x22, 
+  0x3e, 0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 
+  0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 
+  0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 
+  0x22, 0x3e, 0x31, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 
+  0x70, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 
+  0x3c, 0x2f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 
+  0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 
+  0x3e, 0x3c, 0x70, 0x61, 0x63, 0x6b, 0x69, 0x6e, 
+  0x67, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 
+  0x22, 0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x66, 0x69, 0x6c, 0x6c, 0x22, 0x3e, 
+  0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x70, 
+  0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 
+  0x3e, 0x32, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 0x70, 
+  0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 0x3c, 
+  0x2f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 
+  0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 
+  0x3c, 0x70, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x22, 
+  0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x66, 0x69, 0x6c, 0x6c, 0x22, 0x3e, 0x54, 
+  0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x70, 0x6f, 
+  0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3e, 
+  0x31, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 0x70, 0x61, 
+  0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 0x3c, 0x2f, 
+  0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x63, 
+  0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x6f, 0x62, 
+  0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 0x6c, 0x61, 
+  0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 0x6b, 0x54, 
+  0x6f, 0x67, 0x67, 0x6c, 0x65, 0x42, 0x75, 0x74, 
+  0x74, 0x6f, 0x6e, 0x22, 0x20, 0x69, 0x64, 0x3d, 
+  0x22, 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x74, 0x65, 
+  0x5f, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x20, 
+  0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 
+  0x61, 0x62, 0x6c, 0x65, 0x3d, 0x22, 0x79, 0x65, 
+  0x73, 0x22, 0x3e, 0x5f, 0x41, 0x6e, 0x69, 0x6d, 
+  0x61, 0x74, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 0x69, 
+  0x73, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x3e, 0x54, 
+  0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x63, 0x61, 
+  0x6e, 0x5f, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x22, 
+  0x3e, 0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 
+  0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 
+  0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x73, 
+  0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 
+  0x22, 0x3e, 0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x75, 0x73, 0x65, 0x5f, 0x75, 0x6e, 0x64, 
+  0x65, 0x72, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x3e, 
+  0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x20, 0x6e, 
+  0x61, 0x6d, 0x65, 0x3d, 0x22, 0x74, 0x6f, 0x67, 
+  0x67, 0x6c, 0x65, 0x64, 0x22, 0x20, 0x68, 0x61, 
+  0x6e, 0x64, 0x6c, 0x65, 0x72, 0x3d, 0x22, 0x61, 
+  0x6e, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x5f, 0x74, 
+  0x6f, 0x67, 0x67, 0x6c, 0x65, 0x64, 0x22, 0x20, 
+  0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3d, 0x22, 
+  0x47, 0x6c, 0x61, 0x72, 0x65, 0x61, 0x41, 0x70, 
+  0x70, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 
+  0x20, 0x73, 0x77, 0x61, 0x70, 0x70, 0x65, 0x64, 
+  0x3d, 0x22, 0x79, 0x65, 0x73, 0x22, 0x2f, 0x3e, 
+  0x3c, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 
+  0x3e, 0x3c, 0x70, 0x61, 0x63, 0x6b, 0x69, 0x6e, 
+  0x67, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 
+  0x22, 0x3e, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x3c, 
+  0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 
+  0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x66, 0x69, 0x6c, 0x6c, 0x22, 0x3e, 
+  0x54, 0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x70, 
+  0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 
+  0x3e, 0x32, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 0x70, 
+  0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 0x3c, 
+  0x2f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 
+  0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x6f, 
+  0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 0x6c, 
+  0x61, 0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 0x6b, 
+  0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x20, 
+  0x69, 0x64, 0x3d, 0x22, 0x71, 0x75, 0x69, 0x74, 
+  0x5f, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 
+  0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x20, 
+  0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 
+  0x61, 0x62, 0x6c, 0x65, 0x3d, 0x22, 0x79, 0x65, 
+  0x73, 0x22, 0x3e, 0x5f, 0x51, 0x75, 0x69, 0x74, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x76, 0x69, 0x73, 0x69, 0x62, 
+  0x6c, 0x65, 0x22, 0x3e, 0x54, 0x72, 0x75, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x63, 0x61, 0x6e, 0x5f, 0x66, 
+  0x6f, 0x63, 0x75, 0x73, 0x22, 0x3e, 0x54, 0x72, 
+  0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 
+  0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 
+  0x61, 0x6d, 0x65, 0x3d, 0x22, 0x72, 0x65, 0x63, 
+  0x65, 0x69, 0x76, 0x65, 0x73, 0x5f, 0x64, 0x65, 
+  0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x3e, 0x54, 
+  0x72, 0x75, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x75, 0x73, 
+  0x65, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x6c, 
+  0x69, 0x6e, 0x65, 0x22, 0x3e, 0x54, 0x72, 0x75, 
+  0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 
+  0x6d, 0x65, 0x3d, 0x22, 0x61, 0x63, 0x74, 0x69, 
+  0x6f, 0x6e, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x22, 
+  0x3e, 0x61, 0x70, 0x70, 0x2e, 0x71, 0x75, 0x69, 
+  0x74, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 
+  0x72, 0x74, 0x79, 0x3e, 0x3c, 0x2f, 0x6f, 0x62, 
+  0x6a, 0x65, 0x63, 0x74, 0x3e, 0x3c, 0x70, 0x61, 
+  0x63, 0x6b, 0x69, 0x6e, 0x67, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x65, 0x78, 
+  0x70, 0x61, 0x6e, 0x64, 0x22, 0x3e, 0x46, 0x61, 
+  0x6c, 0x73, 0x65, 0x3c, 0x2f, 0x70, 0x72, 0x6f, 
+  0x70, 0x65, 0x72, 0x74, 0x79, 0x3e, 0x3c, 0x70, 
+  0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x66, 0x69, 
+  0x6c, 0x6c, 0x22, 0x3e, 0x54, 0x72, 0x75, 0x65, 
+  0x3c, 0x2f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 
+  0x74, 0x79, 0x3e, 0x3c, 0x70, 0x72, 0x6f, 0x70, 
+  0x65, 0x72, 0x74, 0x79, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x70, 0x6f, 0x73, 0x69, 0x74, 
+  0x69, 0x6f, 0x6e, 0x22, 0x3e, 0x33, 0x3c, 0x2f, 
+  0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 
+  0x3e, 0x3c, 0x2f, 0x70, 0x61, 0x63, 0x6b, 0x69, 
+  0x6e, 0x67, 0x3e, 0x3c, 0x2f, 0x63, 0x68, 0x69, 
+  0x6c, 0x64, 0x3e, 0x3c, 0x2f, 0x6f, 0x62, 0x6a, 
+  0x65, 0x63, 0x74, 0x3e, 0x3c, 0x2f, 0x63, 0x68, 
+  0x69, 0x6c, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x65, 
+  0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x3e, 0x3c, 
+  0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x63, 
+  0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x47, 0x74, 
+  0x6b, 0x53, 0x69, 0x7a, 0x65, 0x47, 0x72, 0x6f, 
+  0x75, 0x70, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 
+  0x73, 0x69, 0x7a, 0x65, 0x67, 0x72, 0x6f, 0x75, 
+  0x70, 0x31, 0x22, 0x3e, 0x3c, 0x77, 0x69, 0x64, 
+  0x67, 0x65, 0x74, 0x73, 0x3e, 0x3c, 0x77, 0x69, 
+  0x64, 0x67, 0x65, 0x74, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x6c, 0x61, 0x62, 0x65, 0x6c, 
+  0x31, 0x22, 0x2f, 0x3e, 0x3c, 0x77, 0x69, 0x64, 
+  0x67, 0x65, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x32, 
+  0x22, 0x2f, 0x3e, 0x3c, 0x77, 0x69, 0x64, 0x67, 
+  0x65, 0x74, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 
+  0x22, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x33, 0x22, 
+  0x2f, 0x3e, 0x3c, 0x2f, 0x77, 0x69, 0x64, 0x67, 
+  0x65, 0x74, 0x73, 0x3e, 0x3c, 0x2f, 0x6f, 0x62, 
+  0x6a, 0x65, 0x63, 0x74, 0x3e, 0x3c, 0x2f, 0x69, 
+  0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 
+  0x3e, 0x0a, 0x00, 0x00, 0x28, 0x75, 0x75, 0x61, 
+  0x79, 0x29, 0x69, 0x6f, 0x2f, 0x00, 0x00, 0x00, 
+  0x03, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 
+  0x01, 0x00, 0x00, 0x00, 0x62, 0x61, 0x73, 0x73, 
+  0x69, 0x2f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 
+  0x67, 0x6c, 0x61, 0x72, 0x65, 0x61, 0x2d, 0x66, 
+  0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 
+  0x67, 0x6c, 0x73, 0x6c, 0x00, 0x00, 0x00, 0x00, 
+  0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 
+  0x20, 0x31, 0x33, 0x30, 0x0a, 0x0a, 0x73, 0x6d, 
+  0x6f, 0x6f, 0x74, 0x68, 0x20, 0x69, 0x6e, 0x20, 
+  0x76, 0x65, 0x63, 0x34, 0x20, 0x76, 0x65, 0x72, 
+  0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 
+  0x3b, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76, 
+  0x65, 0x63, 0x34, 0x20, 0x6f, 0x75, 0x74, 0x70, 
+  0x75, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 
+  0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 
+  0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 
+  0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 
+  0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 
+  0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x43, 0x6f, 
+  0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x7d, 0x0a, 0x00, 
+  0x00, 0x28, 0x75, 0x75, 0x61, 0x79, 0x29, 0x67, 
+  0x6c, 0x61, 0x72, 0x65, 0x61, 0x2d, 0x76, 0x65, 
+  0x72, 0x74, 0x65, 0x78, 0x2e, 0x67, 0x6c, 0x73, 
+  0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 
+  0x20, 0x31, 0x33, 0x30, 0x0a, 0x0a, 0x69, 0x6e, 
+  0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x70, 0x6f, 
+  0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 
+  0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 
+  0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x0a, 
+  0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 
+  0x6d, 0x61, 0x74, 0x34, 0x20, 0x6d, 0x76, 0x70, 
+  0x3b, 0x0a, 0x0a, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 
+  0x68, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 
+  0x63, 0x34, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 
+  0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 
+  0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 
+  0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x20, 
+  0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 
+  0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x6d, 
+  0x76, 0x70, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 
+  0x34, 0x28, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 
+  0x6f, 0x6e, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 
+  0x3b, 0x0a, 0x20, 0x20, 0x76, 0x65, 0x72, 0x74, 
+  0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 
+  0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x63, 
+  0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x31, 0x2e, 
+  0x30, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x00, 0x00, 
+  0x28, 0x75, 0x75, 0x61, 0x79, 0x29, 0x67, 0x6c, 
+  0x61, 0x72, 0x65, 0x61, 0x2d, 0x61, 0x70, 0x70, 
+  0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x2e, 0x75, 0x69, 
+  0x3b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x3c, 0x3f, 0x78, 0x6d, 0x6c, 0x20, 0x76, 0x65, 
+  0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 
+  0x2e, 0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 
+  0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x55, 0x54, 
+  0x46, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x0a, 0x3c, 
+  0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 
+  0x65, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x69, 
+  0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 
+  0x2d, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 
+  0x73, 0x20, 0x67, 0x74, 0x6b, 0x2b, 0x20, 0x33, 
+  0x2e, 0x31, 0x30, 0x20, 0x2d, 0x2d, 0x3e, 0x3c, 
+  0x6d, 0x65, 0x6e, 0x75, 0x20, 0x69, 0x64, 0x3d, 
+  0x22, 0x61, 0x70, 0x70, 0x6d, 0x65, 0x6e, 0x75, 
+  0x22, 0x3e, 0x3c, 0x73, 0x65, 0x63, 0x74, 0x69, 
+  0x6f, 0x6e, 0x3e, 0x3c, 0x69, 0x74, 0x65, 0x6d, 
+  0x3e, 0x3c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 
+  0x75, 0x74, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 
+  0x3d, 0x22, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 
+  0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 
+  0x74, 0x61, 0x62, 0x6c, 0x65, 0x3d, 0x22, 0x79, 
+  0x65, 0x73, 0x22, 0x3e, 0x5f, 0x51, 0x75, 0x69, 
+  0x74, 0x3c, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 
+  0x62, 0x75, 0x74, 0x65, 0x3e, 0x3c, 0x61, 0x74, 
+  0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 
+  0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x63, 
+  0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3e, 0x61, 0x70, 
+  0x70, 0x2e, 0x71, 0x75, 0x69, 0x74, 0x3c, 0x2f, 
+  0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 
+  0x65, 0x3e, 0x3c, 0x61, 0x74, 0x74, 0x72, 0x69, 
+  0x62, 0x75, 0x74, 0x65, 0x20, 0x6e, 0x61, 0x6d, 
+  0x65, 0x3d, 0x22, 0x61, 0x63, 0x63, 0x65, 0x6c, 
+  0x22, 0x3e, 0x26, 0x6c, 0x74, 0x3b, 0x50, 0x72, 
+  0x69, 0x6d, 0x61, 0x72, 0x79, 0x26, 0x67, 0x74, 
+  0x3b, 0x71, 0x3c, 0x2f, 0x61, 0x74, 0x74, 0x72, 
+  0x69, 0x62, 0x75, 0x74, 0x65, 0x3e, 0x3c, 0x2f, 
+  0x69, 0x74, 0x65, 0x6d, 0x3e, 0x3c, 0x2f, 0x73, 
+  0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x3c, 
+  0x2f, 0x6d, 0x65, 0x6e, 0x75, 0x3e, 0x3c, 0x2f, 
+  0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 
+  0x65, 0x3e, 0x0a, 0x00, 0x00, 0x28, 0x75, 0x75, 
+  0x61, 0x79, 0x29, 0x67, 0x6c, 0x61, 0x72, 0x65, 
+  0x61, 0x2f, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 
+  0x05, 0x00, 0x00, 0x00
+} };
+
+static GStaticResource static_resource = { glarea_resource_data.data, sizeof (glarea_resource_data.data), 
NULL, NULL, NULL };
+extern GResource *glarea_get_resource (void);
+GResource *glarea_get_resource (void)
+{
+  return g_static_resource_get_resource (&static_resource);
+}
+/*
+  If G_HAS_CONSTRUCTORS is true then the compiler support *both* constructors and
+  destructors, in a sane way, including e.g. on library unload. If not you're on
+  your own.
+
+  Some compilers need #pragma to handle this, which does not work with macros,
+  so the way you need to use this is (for constructors):
+
+  #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
+  #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(my_constructor)
+  #endif
+  G_DEFINE_CONSTRUCTOR(my_constructor)
+  static void my_constructor(void) {
+   ...
+  }
+
+*/
+
+#ifndef __GTK_DOC_IGNORE__
+
+#if  __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+
+#define G_HAS_CONSTRUCTORS 1
+
+#define G_DEFINE_CONSTRUCTOR(_func) static void __attribute__((constructor)) _func (void);
+#define G_DEFINE_DESTRUCTOR(_func) static void __attribute__((destructor)) _func (void);
+
+#elif defined (_MSC_VER) && (_MSC_VER >= 1500)
+/* Visual studio 2008 and later has _Pragma */
+
+#define G_HAS_CONSTRUCTORS 1
+
+/* We do some weird things to avoid the constructors being optimized
+ * away on VS2015 if WholeProgramOptimization is enabled. First we
+ * make a reference to the array from the wrapper to make sure its
+ * references. Then we use a pragma to make sure the wrapper function
+ * symbol is always included at the link stage. Also, the symbols
+ * need to be extern (but not dllexport), even though they are not
+ * really used from another object file.
+ */
+
+/* We need to account for differences between the mangling of symbols
+ * for Win32 (x86) and x64 programs, as symbols on Win32 are prefixed
+ * with an underscore but symbols on x64 are not.
+ */
+#ifdef _WIN64
+#define G_MSVC_SYMBOL_PREFIX ""
+#else
+#define G_MSVC_SYMBOL_PREFIX "_"
+#endif
+
+#define G_DEFINE_CONSTRUCTOR(_func) G_MSVC_CTOR (_func, G_MSVC_SYMBOL_PREFIX)
+#define G_DEFINE_DESTRUCTOR(_func) G_MSVC_DTOR (_func, G_MSVC_SYMBOL_PREFIX)
+
+#define G_MSVC_CTOR(_func,_sym_prefix) \
+  static void _func(void); \
+  extern int (* _array ## _func)(void);              \
+  int _func ## _wrapper(void) { _func(); g_slist_find (NULL,  _array ## _func); return 0; } \
+  __pragma(comment(linker,"/include:" _sym_prefix # _func "_wrapper")) \
+  __pragma(section(".CRT$XCU",read)) \
+  __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _wrapper;
+
+#define G_MSVC_DTOR(_func,_sym_prefix) \
+  static void _func(void); \
+  extern int (* _array ## _func)(void);              \
+  int _func ## _constructor(void) { atexit (_func); g_slist_find (NULL,  _array ## _func); return 0; } \
+   __pragma(comment(linker,"/include:" _sym_prefix # _func "_constructor")) \
+  __pragma(section(".CRT$XCU",read)) \
+  __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _constructor;
+
+#elif defined (_MSC_VER)
+
+#define G_HAS_CONSTRUCTORS 1
+
+/* Pre Visual studio 2008 must use #pragma section */
+#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1
+#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1
+
+#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \
+  section(".CRT$XCU",read)
+#define G_DEFINE_CONSTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _wrapper(void) { _func(); return 0; } \
+  __declspec(allocate(".CRT$XCU")) static int (*p)(void) = _func ## _wrapper;
+
+#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \
+  section(".CRT$XCU",read)
+#define G_DEFINE_DESTRUCTOR(_func) \
+  static void _func(void); \
+  static int _func ## _constructor(void) { atexit (_func); return 0; } \
+  __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor;
+
+#elif defined(__SUNPRO_C)
+
+/* This is not tested, but i believe it should work, based on:
+ * http://opensource.apple.com/source/OpenSSL098/OpenSSL098-35/src/fips/fips_premain.c
+ */
+
+#define G_HAS_CONSTRUCTORS 1
+
+#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1
+#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1
+
+#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \
+  init(_func)
+#define G_DEFINE_CONSTRUCTOR(_func) \
+  static void _func(void);
+
+#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \
+  fini(_func)
+#define G_DEFINE_DESTRUCTOR(_func) \
+  static void _func(void);
+
+#else
+
+/* constructors not supported for this compiler */
+
+#endif
+
+#endif /* __GTK_DOC_IGNORE__ */
+
+#ifdef G_HAS_CONSTRUCTORS
+
+#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
+#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(resource_constructor)
+#endif
+G_DEFINE_CONSTRUCTOR(resource_constructor)
+#ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA
+#pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(resource_destructor)
+#endif
+G_DEFINE_DESTRUCTOR(resource_destructor)
+
+#else
+#warning "Constructor not supported on this compiler, linking in resources will not work"
+#endif
+
+static void resource_constructor (void)
+{
+  g_static_resource_init (&static_resource);
+}
+
+static void resource_destructor (void)
+{
+  g_static_resource_fini (&static_resource);
+}
diff --git a/retro-gtk/glarea.gresource.xml b/retro-gtk/glarea.gresource.xml
new file mode 100644
index 0000000..d6c29c6
--- /dev/null
+++ b/retro-gtk/glarea.gresource.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/io/bassi/glarea">
+    <file preprocess="xml-stripblanks">glarea-app-window.ui</file>
+    <file preprocess="xml-stripblanks">glarea-app-menu.ui</file>
+    <file>glarea-fragment.glsl</file>
+    <file>glarea-vertex.glsl</file>
+  </gresource>
+</gresources>
diff --git a/retro-gtk/retro-core-view.c b/retro-gtk/retro-core-view.c
index f285db6..6ad95f2 100644
--- a/retro-gtk/retro-core-view.c
+++ b/retro-gtk/retro-core-view.c
@@ -3,7 +3,7 @@
 #include "retro-core-view.h"
 
 #include <linux/input-event-codes.h>
-#include "retro-cairo-display.h"
+#include "retro-gl-display.h"
 #include "retro-core-view-controller.h"
 #include "retro-joypad-id.h"
 #include "retro-mouse-id.h"
@@ -33,7 +33,7 @@ struct _RetroCoreView
 {
   GtkEventBox parent_instance;
   RetroCore *core;
-  RetroCairoDisplay *display;
+  RetroGLDisplay *display;
   GBinding *pixbuf_binding;
   GBinding *sensitive_binding;
   GdkPixbuf *pixbuf;
@@ -249,11 +249,11 @@ retro_core_view_on_button_press_event (GtkWidget      *source,
   else {
     set_input_pressed (self->mouse_button_state, event->button);
     self->pointer_is_on_display =
-      retro_cairo_display_get_coordinates_on_display (self->display,
-                                                      event->x,
-                                                      event->y,
-                                                      &self->pointer_x,
-                                                      &self->pointer_y);
+      retro_gl_display_get_coordinates_on_display (self->display,
+                                                   event->x,
+                                                   event->y,
+                                                   &self->pointer_x,
+                                                   &self->pointer_y);
   }
 
   return FALSE;
@@ -314,11 +314,11 @@ retro_core_view_on_motion_notify_event (GtkWidget      *source,
   }
   else {
     self->pointer_is_on_display =
-      retro_cairo_display_get_coordinates_on_display (self->display,
-                                                      event->x,
-                                                      event->y,
-                                                      &self->pointer_x,
-                                                      &self->pointer_y);
+      retro_gl_display_get_coordinates_on_display (self->display,
+                                                   event->x,
+                                                   event->y,
+                                                   &self->pointer_x,
+                                                   &self->pointer_y);
 
   }
 
@@ -490,7 +490,7 @@ retro_core_view_init (RetroCoreView *self)
 {
   g_object_set ((GtkWidget*) self, "can-focus", TRUE, NULL);
 
-  self->display = g_object_ref_sink (retro_cairo_display_new ());
+  self->display = g_object_ref_sink (retro_gl_display_new ());
   gtk_widget_set_visible (GTK_WIDGET (self->display), TRUE);
   g_object_set (GTK_WIDGET (self->display), "can-focus", FALSE, NULL);
   gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->display));
@@ -539,13 +539,13 @@ retro_core_view_set_core (RetroCoreView *self,
 
   if (self->core != NULL) {
     g_clear_object (&self->core);
-    retro_cairo_display_set_core (self->display, NULL);
+    retro_gl_display_set_core (self->display, NULL);
     retro_pa_player_set_core (self->audio_player, NULL);
   }
 
   if (core != NULL) {
     self->core = g_object_ref (core);
-    retro_cairo_display_set_core (self->display, core);
+    retro_gl_display_set_core (self->display, core);
     retro_pa_player_set_core (self->audio_player, core);
   }
 }
@@ -597,7 +597,7 @@ retro_core_view_set_filter (RetroCoreView    *self,
 {
   g_return_if_fail (RETRO_IS_CORE_VIEW (self));
 
-  retro_cairo_display_set_filter (self->display, filter);
+  retro_gl_display_set_filter (self->display, filter);
 }
 
 /**
diff --git a/retro-gtk/retro-gl-display.c b/retro-gtk/retro-gl-display.c
new file mode 100644
index 0000000..6d88299
--- /dev/null
+++ b/retro-gtk/retro-gl-display.c
@@ -0,0 +1,731 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#include "retro-gl-display.h"
+
+#include <epoxy/gl.h>
+#include "retro-pixdata.h"
+
+struct _RetroGLDisplay
+{
+  GtkGLArea parent_instance;
+  RetroCore *core;
+  GdkPixbuf *pixbuf;
+  RetroVideoFilter filter;
+  gfloat aspect_ratio;
+  gulong on_video_output_id;
+
+  /* model-view-projection matrix */
+  float mvp[16];
+
+  /* GL objects */
+  guint vao;
+  guint program;
+  guint mvp_location;
+  guint position_index;
+  guint color_index;
+};
+
+G_DEFINE_TYPE (RetroGLDisplay, retro_gl_display, GTK_TYPE_GL_AREA)
+
+enum {
+  PROP_PIXBUF = 1,
+  N_PROPS,
+};
+
+static GParamSpec *properties [N_PROPS];
+
+#define GLAREA_ERROR (glarea_error_quark ())
+
+typedef enum {
+  GLAREA_ERROR_SHADER_COMPILATION,
+  GLAREA_ERROR_SHADER_LINK
+} GlareaError;
+
+G_DEFINE_QUARK (glarea-error, glarea_error)
+
+/* Private */
+
+static void
+retro_gl_display_get_video_box (RetroGLDisplay *self,
+                                gdouble        *width,
+                                gdouble        *height,
+                                gdouble        *x,
+                                gdouble        *y)
+{
+  gdouble w;
+  gdouble h;
+  gdouble display_ratio;
+  gdouble allocated_ratio;
+
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (width != NULL);
+  g_return_if_fail (height != NULL);
+  g_return_if_fail (x != NULL);
+  g_return_if_fail (y != NULL);
+
+  w = (gdouble) gtk_widget_get_allocated_width (GTK_WIDGET (self));
+  h = (gdouble) gtk_widget_get_allocated_height (GTK_WIDGET (self));
+
+  // Set the size of the display.
+  display_ratio = (gdouble) self->aspect_ratio;
+  allocated_ratio = w / h;
+
+  // If the screen is wider than the video…
+  if (allocated_ratio > display_ratio) {
+    *height = h;
+    *width = (gdouble) (h * display_ratio);
+  }
+  else {
+    *width = w;
+    *height = (gdouble) (w / display_ratio);
+  }
+
+  // Set the position of the display.
+  *x = (w - *width) / 2;
+  *y = (h - *height) / 2;
+}
+
+/* static void */
+/* retro_gl_display_draw_background (RetroGLDisplay *self, */
+/*                                   gl_t           *cr) */
+/* { */
+/*   g_return_if_fail (self != NULL); */
+/*   g_return_if_fail (cr != NULL); */
+
+/*   gl_set_source_rgb (cr, (gdouble) 0, (gdouble) 0, (gdouble) 0); */
+/*   gl_paint (cr); */
+/* } */
+
+/* static gboolean */
+/* retro_gl_display_real_draw (GtkWidget *base, */
+/*                             gl_t      *cr) */
+/* { */
+/*   RetroGLDisplay *self = RETRO_GL_DISPLAY (base); */
+/*   GdkPixbuf *to_draw; */
+/*   gboolean has_alpha; */
+/*   gint width; */
+/*   gint height; */
+
+/*   gl_surface_t *surface; */
+/*   gdouble w = 0.0; */
+/*   gdouble h = 0.0; */
+/*   gdouble x = 0.0; */
+/*   gdouble y = 0.0; */
+/*   gdouble xs; */
+/*   gdouble ys; */
+/*   gl_pattern_t *source; */
+
+/*   g_return_val_if_fail (self != NULL, FALSE); */
+/*   g_return_val_if_fail (cr != NULL, FALSE); */
+
+/*   retro_gl_display_draw_background (self, cr); */
+
+/*   if (self->pixbuf == NULL) */
+/*     return FALSE; */
+
+/*   if (gtk_widget_get_sensitive (GTK_WIDGET (self))) */
+/*     to_draw = g_object_ref (self->pixbuf); */
+/*   else { */
+/*     has_alpha = gdk_pixbuf_get_has_alpha (self->pixbuf); */
+/*     width = gdk_pixbuf_get_width (self->pixbuf); */
+/*     height = gdk_pixbuf_get_height (self->pixbuf); */
+/*     to_draw = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 8, width, height); */
+/*     gdk_pixbuf_saturate_and_pixelate (self->pixbuf, to_draw, 0.0f, FALSE); */
+/*   } */
+
+/*   surface = gdk_gl_surface_create_from_pixbuf (to_draw, 1, NULL); */
+/*   retro_gl_display_get_video_box (self, &w, &h, &x, &y); */
+/*   xs = w / gdk_pixbuf_get_width (to_draw); */
+/*   ys = h / gdk_pixbuf_get_height (to_draw); */
+
+/*   gl_scale (cr, xs, ys); */
+/*   gl_set_source_surface (cr, surface, x / xs, y / ys); */
+/*   source = gl_get_source (cr); */
+/*   switch (self->filter) { */
+/*   case RETRO_VIDEO_FILTER_SHARP: */
+/*     gl_pattern_set_filter (source, GL_FILTER_NEAREST); */
+
+/*     break; */
+/*   default: */
+/*   case RETRO_VIDEO_FILTER_SMOOTH: */
+/*     gl_pattern_set_filter (source, GL_FILTER_BILINEAR); */
+
+/*     break; */
+/*   } */
+/*   gl_paint (cr); */
+
+/*   gl_surface_destroy (surface); */
+/*   g_object_unref (to_draw); */
+
+/*   return TRUE; */
+/* } */
+
+/* position and color information for each vertex */
+struct vertex_info {
+  float position[3];
+  float color[3];
+};
+
+/* the vertex data is constant */
+static const struct vertex_info vertex_data[] = {
+  { {  0.0f,  0.500f, 0.0f }, { 1.f, 0.f, 0.f } },
+  { {  0.5f, -0.366f, 0.0f }, { 0.f, 1.f, 0.f } },
+  { { -0.5f, -0.366f, 0.0f }, { 0.f, 0.f, 1.f } },
+};
+
+static void
+init_buffers (guint  position_index,
+              guint  color_index,
+              guint *vao_out)
+{
+  guint vao, buffer;
+
+  /* we need to create a VAO to store the other buffers */
+  glGenVertexArrays (1, &vao);
+  glBindVertexArray (vao);
+
+  /* this is the VBO that holds the vertex data */
+  glGenBuffers (1, &buffer);
+  glBindBuffer (GL_ARRAY_BUFFER, buffer);
+  glBufferData (GL_ARRAY_BUFFER, sizeof (vertex_data), vertex_data, GL_STATIC_DRAW);
+
+  /* enable and set the position attribute */
+  glEnableVertexAttribArray (position_index);
+  glVertexAttribPointer (position_index, 3, GL_FLOAT, GL_FALSE,
+                         sizeof (struct vertex_info),
+                         (GLvoid *) (G_STRUCT_OFFSET (struct vertex_info, position)));
+
+  /* enable and set the color attribute */
+  glEnableVertexAttribArray (color_index);
+  glVertexAttribPointer (color_index, 3, GL_FLOAT, GL_FALSE,
+                         sizeof (struct vertex_info),
+                         (GLvoid *) (G_STRUCT_OFFSET (struct vertex_info, color)));
+
+  /* reset the state; we will re-enable the VAO when needed */
+  glBindBuffer (GL_ARRAY_BUFFER, 0);
+  glBindVertexArray (0);
+
+  /* the VBO is referenced by the VAO */
+  glDeleteBuffers (1, &buffer);
+
+  if (vao_out != NULL)
+    *vao_out = vao;
+}
+
+static guint
+create_shader (int          shader_type,
+               const char  *source,
+               GError     **error,
+               guint       *shader_out)
+{
+  guint shader = glCreateShader (shader_type);
+  glShaderSource (shader, 1, &source, NULL);
+  glCompileShader (shader);
+
+  int status;
+  glGetShaderiv (shader, GL_COMPILE_STATUS, &status);
+  if (status == GL_FALSE)
+    {
+      int log_len;
+      glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &log_len);
+
+      char *buffer = g_malloc (log_len + 1);
+      glGetShaderInfoLog (shader, log_len, NULL, buffer);
+
+      g_set_error (error, GLAREA_ERROR, GLAREA_ERROR_SHADER_COMPILATION,
+                   "Compilation failure in %s shader: %s",
+                   shader_type == GL_VERTEX_SHADER ? "vertex" : "fragment",
+                   buffer);
+
+      g_free (buffer);
+
+      glDeleteShader (shader);
+      shader = 0;
+    }
+
+  if (shader_out != NULL)
+    *shader_out = shader;
+
+  return shader != 0;
+}
+
+static gboolean
+init_shaders (guint   *program_out,
+              guint   *mvp_location_out,
+              guint   *position_location_out,
+              guint   *color_location_out,
+              GError **error)
+{
+  GBytes *source;
+  guint program = 0;
+  guint mvp_location = 0;
+  guint vertex = 0, fragment = 0;
+  guint position_location = 0;
+  guint color_location = 0;
+
+  /* load the vertex shader */
+  source = g_resources_lookup_data ("/io/bassi/glarea/glarea-vertex.glsl", 0, NULL);
+  create_shader (GL_VERTEX_SHADER, g_bytes_get_data (source, NULL), error, &vertex);
+  g_bytes_unref (source);
+  if (vertex == 0)
+    goto out;
+
+  /* load the fragment shader */
+  source = g_resources_lookup_data ("/io/bassi/glarea/glarea-fragment.glsl", 0, NULL);
+  create_shader (GL_FRAGMENT_SHADER, g_bytes_get_data (source, NULL), error, &fragment);
+  g_bytes_unref (source);
+  if (fragment == 0)
+    goto out;
+
+  /* link the vertex and fragment shaders together */
+  program = glCreateProgram ();
+  glAttachShader (program, vertex);
+  glAttachShader (program, fragment);
+  glLinkProgram (program);
+
+  int status = 0;
+  glGetProgramiv (program, GL_LINK_STATUS, &status);
+  if (status == GL_FALSE)
+    {
+      int log_len = 0;
+      glGetProgramiv (program, GL_INFO_LOG_LENGTH, &log_len);
+
+      char *buffer = g_malloc (log_len + 1);
+      glGetProgramInfoLog (program, log_len, NULL, buffer);
+
+      g_set_error (error, GLAREA_ERROR, GLAREA_ERROR_SHADER_LINK,
+                   "Linking failure in program: %s", buffer);
+
+      g_free (buffer);
+
+      glDeleteProgram (program);
+      program = 0;
+
+      goto out;
+    }
+
+  /* get the location of the "mvp" uniform */
+  mvp_location = glGetUniformLocation (program, "mvp");
+
+  /* get the location of the "position" and "color" attributes */
+  position_location = glGetAttribLocation (program, "position");
+  color_location = glGetAttribLocation (program, "color");
+
+  /* the individual shaders can be detached and destroyed */
+  glDetachShader (program, vertex);
+  glDetachShader (program, fragment);
+
+out:
+  if (vertex != 0)
+    glDeleteShader (vertex);
+  if (fragment != 0)
+    glDeleteShader (fragment);
+
+  if (program_out != NULL)
+    *program_out = program;
+  if (mvp_location_out != NULL)
+    *mvp_location_out = mvp_location;
+  if (position_location_out != NULL)
+    *position_location_out = position_location;
+  if (color_location_out != NULL)
+    *color_location_out = color_location;
+
+  return program != 0;
+}
+
+static void
+gl_init (RetroGLDisplay *self)
+{
+  /* we need to ensure that the GdkGLContext is set before calling GL API */
+  gtk_gl_area_make_current (GTK_GL_AREA (self));
+
+  /* initialize the shaders and retrieve the program data */
+  GError *error = NULL;
+  if (!init_shaders (&self->program,
+                     &self->mvp_location,
+                     &self->position_index,
+                     &self->color_index,
+                     &error))
+    {
+      gtk_gl_area_set_error (GTK_GL_AREA (self), error);
+      g_error_free (error);
+      return;
+    }
+
+  /* initialize the vertex buffers */
+  init_buffers (self->position_index, self->color_index, &self->vao);
+}
+
+static void
+gl_fini (RetroGLDisplay *self)
+{
+  /* we need to ensure that the GdkGLContext is set before calling GL API */
+  gtk_gl_area_make_current (GTK_GL_AREA (self));
+
+  /* destroy all the resources we created */
+  glDeleteVertexArrays (1, &self->vao);
+  glDeleteProgram (self->program);
+}
+
+static void
+draw_triangle (RetroGLDisplay *self)
+{
+  if (self->program == 0 || self->vao == 0)
+    return;
+
+  /* load our program */
+  glUseProgram (self->program);
+
+  /* update the "mvp" matrix we use in the shader */
+  glUniformMatrix4fv (self->mvp_location, 1, GL_FALSE, &(self->mvp[0]));
+
+  /* use the buffers in the VAO */
+  glBindVertexArray (self->vao);
+
+  /* draw the three vertices as a triangle */
+  glDrawArrays (GL_TRIANGLES, 0, 3);
+
+  /* we finished using the buffers and program */
+  glBindVertexArray (0);
+  glUseProgram (0);
+}
+
+static gboolean
+gl_draw (RetroGLDisplay *self)
+{
+  /* clear the viewport; the viewport is automatically resized when
+   * the GtkGLArea gets an allocation
+   */
+  glClearColor (0.5, 0.5, 0.5, 1.0);
+  glClear (GL_COLOR_BUFFER_BIT);
+
+  /* draw our object */
+  draw_triangle (self);
+
+  /* flush the contents of the pipeline */
+  glFlush ();
+
+  return FALSE;
+}
+
+static void
+init_mvp (float *res)
+{
+  /* initialize a matrix as an identity matrix */
+  res[0] = 1.f; res[4] = 0.f;  res[8] = 0.f; res[12] = 0.f;
+  res[1] = 0.f; res[5] = 1.f;  res[9] = 0.f; res[13] = 0.f;
+  res[2] = 0.f; res[6] = 0.f; res[10] = 1.f; res[14] = 0.f;
+  res[3] = 0.f; res[7] = 0.f; res[11] = 0.f; res[15] = 1.f;
+}
+
+static void
+compute_mvp (float *res,
+             float  phi,
+             float  theta,
+             float  psi)
+{
+  float x = phi * (G_PI / 180.f);
+  float y = theta * (G_PI / 180.f);
+  float z = psi * (G_PI / 180.f);
+  float c1 = cosf (x), s1 = sinf (x);
+  float c2 = cosf (y), s2 = sinf (y);
+  float c3 = cosf (z), s3 = sinf (z);
+  float c3c2 = c3 * c2;
+  float s3c1 = s3 * c1;
+  float c3s2s1 = c3 * s2 * s1;
+  float s3s1 = s3 * s1;
+  float c3s2c1 = c3 * s2 * c1;
+  float s3c2 = s3 * c2;
+  float c3c1 = c3 * c1;
+  float s3s2s1 = s3 * s2 * s1;
+  float c3s1 = c3 * s1;
+  float s3s2c1 = s3 * s2 * c1;
+  float c2s1 = c2 * s1;
+  float c2c1 = c2 * c1;
+
+  /* apply all three Euler angles rotations using the three matrices:
+   *
+   * ⎡  c3 s3 0 ⎤ ⎡ c2  0 -s2 ⎤ ⎡ 1   0  0 ⎤
+   * ⎢ -s3 c3 0 ⎥ ⎢  0  1   0 ⎥ ⎢ 0  c1 s1 ⎥
+   * ⎣   0  0 1 ⎦ ⎣ s2  0  c2 ⎦ ⎣ 0 -s1 c1 ⎦
+   */
+  res[0] = c3c2;  res[4] = s3c1 + c3s2s1;  res[8] = s3s1 - c3s2c1; res[12] = 0.f;
+  res[1] = -s3c2; res[5] = c3c1 - s3s2s1;  res[9] = c3s1 + s3s2c1; res[13] = 0.f;
+  res[2] = s2;    res[6] = -c2s1;         res[10] = c2c1;          res[14] = 0.f;
+  res[3] = 0.f;   res[7] = 0.f;           res[11] = 0.f;           res[15] = 1.f;
+}
+
+static void
+retro_gl_display_finalize (GObject *object)
+{
+  RetroGLDisplay *self = (RetroGLDisplay *) object;
+
+  if (self->core != NULL)
+    g_object_unref (self->core);
+  if (self->pixbuf != NULL)
+    g_object_unref (self->pixbuf);
+
+  G_OBJECT_CLASS (retro_gl_display_parent_class)->finalize (object);
+}
+
+static void
+retro_gl_display_get_property (GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  RetroGLDisplay *self = RETRO_GL_DISPLAY (object);
+
+  switch (prop_id) {
+  case PROP_PIXBUF:
+    g_value_set_object (value, retro_gl_display_get_pixbuf (self));
+
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+
+    break;
+  }
+}
+
+static void
+retro_gl_display_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  RetroGLDisplay *self = RETRO_GL_DISPLAY (object);
+
+  switch (prop_id) {
+  case PROP_PIXBUF:
+    retro_gl_display_set_pixbuf (self, g_value_get_object (value));
+
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+
+    break;
+  }
+}
+
+static void
+retro_gl_display_class_init (RetroGLDisplayClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = retro_gl_display_finalize;
+  object_class->get_property = retro_gl_display_get_property;
+  object_class->set_property = retro_gl_display_set_property;
+
+  properties[PROP_PIXBUF] =
+    g_param_spec_object ("pixbuf",
+                         "Pixbuf",
+                         "The displayed pixbuf",
+                         gdk_pixbuf_get_type (),
+                         G_PARAM_READWRITE |
+                         G_PARAM_STATIC_NAME |
+                         G_PARAM_STATIC_NICK |
+                         G_PARAM_STATIC_BLURB);
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PIXBUF, properties[PROP_PIXBUF]);
+}
+
+static void
+queue_draw (GObject    *sender,
+            GParamSpec *pspec,
+            gpointer    self)
+{
+  gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+static void
+retro_gl_display_init (RetroGLDisplay *self)
+{
+  g_signal_connect_object (G_OBJECT (self),
+                           "realize",
+                           (GCallback) gl_init,
+                           GTK_WIDGET (self),
+                           0);
+
+  g_signal_connect_object (G_OBJECT (self),
+                           "unrealize",
+                           (GCallback) gl_fini,
+                           GTK_WIDGET (self),
+                           0);
+
+  g_signal_connect_object (G_OBJECT (self),
+                           "render",
+                           (GCallback) gl_draw,
+                           GTK_WIDGET (self),
+                           0);
+
+  self->filter = RETRO_VIDEO_FILTER_SMOOTH;
+
+  g_signal_connect_object (G_OBJECT (self),
+                           "notify::sensitive",
+                           (GCallback) queue_draw,
+                           GTK_WIDGET (self),
+                           0);
+
+  g_signal_connect_object (G_OBJECT (self),
+                           "notify::pixbuf",
+                           (GCallback) queue_draw,
+                           GTK_WIDGET (self),
+                           0);
+}
+
+static void
+retro_gl_display_on_video_output (RetroCore    *sender,
+                                  RetroPixdata *pixdata,
+                                  gpointer      user_data)
+{
+  RetroGLDisplay *self = RETRO_GL_DISPLAY (user_data);
+
+  GdkPixbuf *pixbuf;
+
+  g_return_if_fail (self != NULL);
+
+  self->aspect_ratio = retro_pixdata_get_aspect_ratio (pixdata);
+  pixbuf = retro_pixdata_to_pixbuf (pixdata);
+  retro_gl_display_set_pixbuf (self, pixbuf);
+
+  if (pixbuf != NULL)
+    g_object_unref (pixbuf);
+}
+
+/* Public */
+
+/**
+ * retro_gl_display_set_core:
+ * @self: a #RetroGLDisplay
+ * @core: (nullable): a #RetroCore, or %NULL
+ *
+ * Sets @core as the #RetroCore displayed by @self.
+ */
+void
+retro_gl_display_set_core (RetroGLDisplay *self,
+                           RetroCore      *core)
+{
+  g_return_if_fail (self != NULL);
+
+  if (self->core == core)
+    return;
+
+  if (self->core != NULL) {
+    g_signal_handler_disconnect (G_OBJECT (self->core), self->on_video_output_id);
+    g_clear_object (&self->core);
+  }
+
+  if (core != NULL) {
+    self->core = g_object_ref (core);
+    self->on_video_output_id = g_signal_connect_object (core, "video-output", (GCallback) 
retro_gl_display_on_video_output, self, 0);
+  }
+}
+
+/**
+ * retro_gl_display_get_pixbuf:
+ * @self: a #RetroGLDisplay
+ *
+ * Gets the currently displayed video frame.
+ *
+ * Returns: (transfer none): a #GdkPixbuf
+ */
+GdkPixbuf *
+retro_gl_display_get_pixbuf (RetroGLDisplay *self)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+
+  return self->pixbuf;
+}
+
+/**
+ * retro_gl_display_set_pixbuf:
+ * @self: a #RetroGLDisplay
+ * @pixbuf: a #GdkPixbuf
+ *
+ * Sets @pixbuf as the currently displayed video frame.
+ */
+void
+retro_gl_display_set_pixbuf (RetroGLDisplay *self,
+                             GdkPixbuf      *pixbuf)
+{
+  g_return_if_fail (self != NULL);
+
+  if (self->pixbuf == pixbuf)
+    return;
+
+  g_clear_object (&self->pixbuf);
+
+  if (pixbuf != NULL)
+    self->pixbuf = g_object_ref (pixbuf);
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PIXBUF]);
+}
+
+/**
+ * retro_gl_display_set_filter:
+ * @self: a #RetroGLDisplay
+ * @filter: a #RetroVideoFilter
+ *
+ * Sets the video filter to use to render the core's video on @self.
+ */
+void
+retro_gl_display_set_filter (RetroGLDisplay   *self,
+                             RetroVideoFilter  filter)
+{
+  g_return_if_fail (self != NULL);
+
+  self->filter = filter;
+  gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+/**
+ * retro_gl_display_get_coordinates_on_display:
+ * @self: a #RetroGLDisplay
+ * @widget_x: the abscissa on @self
+ * @widget_y: the ordinate on @self
+ * @display_x: return location for a the abscissa on the core's video display
+ * @display_y: return location for a the ordinate on the core's video display
+ *
+ * Gets coordinates on the core's video output from coordinates on @self, and
+ * whether the point is inside the core's video display.
+ *
+ * Returns: whether the coordinates are on the core's video display
+ */
+gboolean
+retro_gl_display_get_coordinates_on_display (RetroGLDisplay *self,
+                                             gdouble         widget_x,
+                                             gdouble         widget_y,
+                                             gdouble        *display_x,
+                                             gdouble        *display_y)
+{
+  gdouble w = 0.0;
+  gdouble h = 0.0;
+  gdouble x = 0.0;
+  gdouble y = 0.0;
+
+  g_return_val_if_fail (self != NULL, FALSE);
+  g_return_val_if_fail (display_x != NULL, FALSE);
+  g_return_val_if_fail (display_y != NULL, FALSE);
+
+  retro_gl_display_get_video_box (self, &w, &h, &x, &y);
+
+  // Return coordinates as a [-1.0, 1.0] scale, (0.0, 0.0) is the center.
+  *display_x = ((widget_x - x) * 2.0 - w) / w;
+  *display_y = ((widget_y - y) * 2.0 - h) / h;
+
+  return (-1.0 <= *display_x) && (*display_x <= 1.0) &&
+         (-1.0 <= *display_y) && (*display_y <= 1.0);
+}
+
+/**
+ * retro_gl_display_new:
+ *
+ * Creates a new #RetroGLDisplay.
+ *
+ * Returns: (transfer full): a new #RetroGLDisplay
+ */
+RetroGLDisplay *
+retro_gl_display_new (void)
+{
+  return g_object_new (RETRO_TYPE_GL_DISPLAY, NULL);
+}
diff --git a/retro-gtk/retro-gl-display.h b/retro-gtk/retro-gl-display.h
new file mode 100644
index 0000000..2a0b1c7
--- /dev/null
+++ b/retro-gtk/retro-gl-display.h
@@ -0,0 +1,36 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#ifndef RETRO_GL_DISPLAY_H
+#define RETRO_GL_DISPLAY_H
+
+#if !defined(__RETRO_GTK_INSIDE__) && !defined(RETRO_GTK_COMPILATION)
+# error "Only <retro-gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtk.h>
+#include "retro-core.h"
+#include "retro-video-filter.h"
+
+G_BEGIN_DECLS
+
+#define RETRO_TYPE_GL_DISPLAY (retro_gl_display_get_type())
+
+G_DECLARE_FINAL_TYPE (RetroGLDisplay, retro_gl_display, RETRO, GL_DISPLAY, GtkGLArea)
+
+RetroGLDisplay *retro_gl_display_new (void);
+GdkPixbuf *retro_gl_display_get_pixbuf (RetroGLDisplay *self);
+void retro_gl_display_set_pixbuf (RetroGLDisplay *self,
+                                  GdkPixbuf      *pixbuf);
+void retro_gl_display_set_core (RetroGLDisplay *self,
+                                RetroCore      *core);
+void retro_gl_display_set_filter (RetroGLDisplay   *self,
+                                  RetroVideoFilter  filter);
+gboolean retro_gl_display_get_coordinates_on_display (RetroGLDisplay *self,
+                                                      gdouble         widget_x,
+                                                      gdouble         widget_y,
+                                                      gdouble        *display_x,
+                                                      gdouble        *display_y);
+
+G_END_DECLS
+
+#endif /* RETRO_GL_DISPLAY_H */
diff --git a/retro-gtk/retro-gtk-0.14.deps b/retro-gtk/retro-gtk-0.14.deps
index ec2cb16..2fc8f4c 100644
--- a/retro-gtk/retro-gtk-0.14.deps
+++ b/retro-gtk/retro-gtk-0.14.deps
@@ -1,5 +1,6 @@
 
 cairo
+epoxy
 gio-2.0
 glib-2.0
 gmodule-2.0



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]