initial Wayland support #72 #76

Disable OpenGL support under Wayland because wxGLCanvas segfaults, and
fix an issue with drawn frames not appearing.

If the user has opengl as the render method in their config, it will not
be changed, but at runtime will be set to simple under Wayland.

To fix the issue with frames not being drawn, Call Refresh() to queue a
PaintEv from DrawArea(data) instead of calling DrawArea(device_context)
directly.

Also remove the DrawOSD() call from PaintEv, this was causing the OSD to
sometimes show up twice in one frame, because DrawArea(data) draws the
OSD directly on the frame data.

Add new files wayland.cpp and wayland.h with a bool IsItWayland() global
function. This uses a GDK (part of GTK) call to detect Wayland.  This
unfortunately requires linking GTK libs separately.

Add cmake code to detect the version of GTK used by the wx being linked
and link it as well. Add gtk2 and gtk3 dev packages to the code for the
supported linux dists in ./installdeps.
This commit is contained in:
Rafael Kitover 2017-02-20 13:20:09 -08:00
parent 13f5afa9c5
commit 6a7d49419c
10 changed files with 92 additions and 18 deletions

View File

@ -49,6 +49,9 @@ And the following development libraries:
- wxWidgets
- cairo (completely optional)
On Linux and similar, you also need the version of GTK your wxWidgets is linked
to (usuall 2 or 3).
Support for more OSes/distributions for `./installdeps` is planned.
## Cross Compiling for Win32

View File

@ -199,7 +199,7 @@ debian_installdeps() {
if [ -z "$target" ]; then
check sudo apt-get -qq update
check sudo apt-get -qy install build-essential g++ nasm cmake gettext zlib1g-dev libgl1-mesa-dev libavcodec-dev libavformat-dev libswscale-dev libavutil-dev libgettextpo-dev libjpeg-dev libpng-dev libtiff5-dev libsdl2-dev libsfml-dev libopenal-dev libwxgtk3.0-dev
check sudo apt-get -qy install build-essential g++ nasm cmake gettext zlib1g-dev libgl1-mesa-dev libavcodec-dev libavformat-dev libswscale-dev libavutil-dev libgettextpo-dev libjpeg-dev libpng-dev libtiff5-dev libsdl2-dev libsfml-dev libopenal-dev libwxgtk3.0-dev libgtk2.0-dev libgtk-3-dev libcairo2-dev
else
case "$target" in
mingw-w64-i686)
@ -264,7 +264,7 @@ fedora_installdeps() {
# this is sometimes necessary for rawhide
set -- --exclude='glibc32*'
fi
for pkg in zlib-devel mesa-libGL-devel ffmpeg-devel gettext-devel libjpeg-turbo-devel libpng-devel libtiff-devel SDL2-devel SFML-devel openal-soft-devel wxGTK3-devel; do
for pkg in zlib-devel mesa-libGL-devel ffmpeg-devel gettext-devel libjpeg-turbo-devel libpng-devel libtiff-devel SDL2-devel SFML-devel openal-soft-devel wxGTK3-devel gtk2-devel gtk3-devel; do
if [ -n "$amd64" ]; then
set -- "$@" "${pkg}.x86_64" "${pkg}.i686"
else
@ -339,7 +339,7 @@ archlinux_installdeps() {
if [ -z "$target" ]; then
# native build
check $pacman --noconfirm --needed -S base-devel "$gcc_pkg" nasm zlib mesa cairo cmake ffmpeg gettext libpng libtiff pkg-config sdl2 sfml openal wxgtk
check $pacman --noconfirm --needed -S base-devel "$gcc_pkg" nasm zlib mesa cairo cmake ffmpeg gettext libpng libtiff pkg-config sdl2 sfml openal wxgtk gtk2 gtk3
else
# windows cross build
case "$target" in

View File

@ -142,6 +142,48 @@ IF(WIN32 AND ENABLE_DIRECTX)
FIND_PACKGE ( DirectX REQUIRED )
ENDIF(WIN32 AND ENABLE_DIRECTX)
# we make some direct gtk/gdk calls on linux and such
# so need to link the gtk that wx was built with
IF(NOT WIN32 AND NOT APPLE)
FIND_PATH(WX_CONFIG_H NAMES wx/config.h PATHS ${wxWidgets_INCLUDE_DIRS})
IF(NOT WX_CONFIG_H)
MESSAGE(FATAL_ERROR "Could not find wx/config.h in ${wxWidgets_INCLUDE_DIRS}")
ENDIF()
SET(WX_CONFIG_H "${WX_CONFIG_H}/wx/config.h")
INCLUDE(CheckCXXSymbolExists)
CHECK_CXX_SYMBOL_EXISTS(__WXGTK3__ ${WX_CONFIG_H} WX_USING_GTK3)
IF(WX_USING_GTK3)
FIND_PACKAGE(PkgConfig REQUIRED)
PKG_CHECK_MODULES(GTK3 REQUIRED gtk+-3.0)
IF(NOT GTK3_INCLUDE_DIRS)
MESSAGE(FATAL_ERROR "Could not find gtk3")
ENDIF()
INCLUDE_DIRECTORIES(${GTK3_INCLUDE_DIRS})
LINK_DIRECTORIES(${GTK3_LIBRARY_DIRS})
ADD_COMPILE_OPTIONS(${GTK3_CFLAGS_OTHER})
SET(GTK_LIBRARIES ${GTK3_LIBRARIES})
ELSE()
CHECK_CXX_SYMBOL_EXISTS(__WXGTK20__ ${WX_CONFIG_H} WX_USING_GTK2)
IF(WX_USING_GTK2)
FIND_PACKAGE(GTK2 REQUIRED gtk)
IF(NOT GTK2_INCLUDE_DIRS)
MESSAGE(FATAL_ERROR "Could not find gtk2")
ENDIF()
INCLUDE_DIRECTORIES(${GTK2_INCLUDE_DIRS})
ADD_COMPILE_OPTIONS(${GTK2_DEFINITIONS})
SET(GTK_LIBRARIES ${GTK2_LIBRARIES})
ELSE()
FIND_PACKAGE(GTK REQUIRED gtk)
IF(NOT GTK_INCLUDE_DIRS)
MESSAGE(FATAL_ERROR "Could not find gtk")
ENDIF()
INCLUDE_DIRECTORIES(${GTK_INCLUDE_DIRS})
ADD_COMPILE_OPTIONS(${GTK_DEFINITIONS})
ENDIF()
ENDIF()
ENDIF()
# contrib widgets
include_directories(widgets)
@ -247,6 +289,7 @@ SET( SRC_WX
sys.cpp
panel.cpp
viewsupt.cpp
wayland.cpp
widgets/keyedit.cpp
widgets/joyedit.cpp
widgets/sdljoy.cpp
@ -278,6 +321,7 @@ SET( HDR_WX
opts.h
viewsupt.h
wxhead.h
wayland.h
widgets/wx/keyedit.h
widgets/wx/joyedit.h
widgets/wx/sdljoy.h
@ -349,6 +393,7 @@ TARGET_LINK_LIBRARIES (
${FFMPEG_LIBRARIES}
${DIRECTX_LIBRARIES}
${CAIRO_LIBRARIES}
${GTK_LIBRARIES}
)
# Build a console app in debug mode on Windows

View File

@ -3310,6 +3310,12 @@ bool MainFrame::BindControls()
getrbi("OutputOpenGL", gopts.render_method, RND_OPENGL);
#ifdef NO_OGL
rb->Hide();
#endif
#ifdef __WXGTK__
// wxGLCanvas segfaults on Wayland
if (wxGetApp().UsingWayland()) {
rb->Hide();
}
#endif
getrbi("OutputCairo", gopts.render_method, RND_CAIRO);
#ifdef NO_CAIRO

View File

@ -279,16 +279,13 @@ opts_t::opts_t()
frameSkip = -1;
#ifdef __WXMSW__
audio_api = AUD_DIRECTSOUND;
#else
#ifdef __WXMAC__
audio_api = AUD_OPENAL;
#elif !defined(NO_OAL) && (defined(__WXMAC__) || defined(__WXGTK__))
audio_api = AUD_OPENAL;
#endif
#ifndef NO_OGL
render_method = RND_OPENGL;
#endif
#ifdef __WXGTK__
audio_api = AUD_OPENAL;
render_method = RND_OPENGL;
#endif
#endif
video_scale = 3;
retain_aspect = true;
max_threads = wxThread::GetCPUCount();

View File

@ -1414,7 +1414,9 @@ void DrawingPanelBase::PaintEv(wxPaintEvent& ev)
}
DrawArea(dc);
DrawOSD(dc);
// currently we draw the OSD directly on the framebuffer to reduce flickering
//DrawOSD(dc);
}
void DrawingPanelBase::EraseBackground(wxEraseEvent& ev)
@ -1794,14 +1796,12 @@ void DrawingPanelBase::DrawArea(uint8_t** data)
}
}
// next, draw the game
wxClientDC dc(GetWindow());
DrawArea(dc);
// next, draw the frame (queue a PaintEv)
GetWindow()->Refresh();
// finally, draw on-screen text using wx method, if possible
// this method flickers too much right now
if (0)
DrawOSD(dc);
//DrawOSD(dc);
}
void DrawingPanelBase::DrawOSD(wxWindowDC& dc)

11
src/wx/wayland.cpp Normal file
View File

@ -0,0 +1,11 @@
#ifdef __WXGTK__
#include <gdk/gdk.h>
#ifdef GDK_WINDOWING_WAYLAND
#include <gdk/gdkwayland.h>
bool IsItWayland() { return GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default()); }
#else
bool IsItWayland() { return false; }
#endif
#else
bool IsItWayland() { return false; }
#endif

1
src/wx/wayland.h Normal file
View File

@ -0,0 +1 @@
bool IsItWayland();

View File

@ -1,4 +1,3 @@
// mainline:
// parse cmd line
// load xrc file (guiinit.cpp does most of instantiation)
@ -21,6 +20,8 @@
#include <wx/wfstream.h>
#include <wx/zipstrm.h>
#include "wayland.h"
// The built-in xrc file
#include "builtin-xrc.h"
@ -158,6 +159,7 @@ bool wxvbamApp::OnInit()
setvbuf(stderr, NULL, _IONBF, 0);
dup2(1, 2); // redirect stderr to stdout
#endif
using_wayland = IsItWayland();
// use consistent names for config
SetAppName(_("vbam"));
@ -252,6 +254,11 @@ bool wxvbamApp::OnInit()
load_opts();
// wxGLCanvas segfaults under wayland
if (UsingWayland() && gopts.render_method == RND_OPENGL) {
gopts.render_method = RND_SIMPLE;
}
// process command-line options
for (int i = 0; i < pending_optset.size(); i++) {
wxString p = pending_optset[i];

View File

@ -79,9 +79,11 @@ public:
wxvbamApp()
: wxApp()
, pending_fullscreen(false)
, using_wayland(false)
{
}
virtual bool OnInit();
virtual bool UsingWayland() { return using_wayland; }
virtual void OnInitCmdLine(wxCmdLineParser&);
virtual bool OnCmdLineParsed(wxCmdLineParser&);
wxString GetConfigurationPath();
@ -132,6 +134,8 @@ public:
return false;
}
}
protected:
bool using_wayland;
private:
wxPathList config_path;