[hidpi] Use wxWidgets 3.2 on Windows
* Remove the custom handling for pre-3.1.4 builds on Windows since both the mingw and msvc builds now use 3.2. * Remove wxDPIChangedEvent handling, since this triggers a resize, which has the same effect. * Implement main/WinMain ourselves, rather than relying on wxWidgets macros. This allows us to initialize the console earlier in the process. * Add an explicit dependency on the manifest file to trigger a link when it is modified.
This commit is contained in:
parent
0d86432a31
commit
297d7c06c4
|
@ -27,7 +27,7 @@ jobs:
|
||||||
mingw-w64-clang-x86_64-FAudio
|
mingw-w64-clang-x86_64-FAudio
|
||||||
mingw-w64-clang-x86_64-cmake
|
mingw-w64-clang-x86_64-cmake
|
||||||
mingw-w64-clang-x86_64-ninja
|
mingw-w64-clang-x86_64-ninja
|
||||||
mingw-w64-clang-x86_64-wxWidgets
|
mingw-w64-clang-x86_64-wxWidgets3.2
|
||||||
mingw-w64-clang-x86_64-sfml
|
mingw-w64-clang-x86_64-sfml
|
||||||
mingw-w64-clang-x86_64-SDL2
|
mingw-w64-clang-x86_64-SDL2
|
||||||
zip
|
zip
|
||||||
|
|
|
@ -1115,7 +1115,7 @@ windows_installdeps() {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
pkgs="$pkgs SDL2 sfml wxWidgets zlib binutils cmake crt-git extra-cmake-modules headers-git make pkgconf tools-git windows-default-manifest libmangle-git ninja gdb ccache"
|
pkgs="$pkgs SDL2 sfml wxWidgets3.2 zlib binutils cmake crt-git extra-cmake-modules headers-git make pkgconf tools-git windows-default-manifest libmangle-git ninja gdb ccache"
|
||||||
|
|
||||||
[ -n "$ENABLE_OPENAL" ] && pkgs="$pkgs openal"
|
[ -n "$ENABLE_OPENAL" ] && pkgs="$pkgs openal"
|
||||||
[ -n "$ENABLE_FFMPEG" ] && pkgs="$pkgs ffmpeg"
|
[ -n "$ENABLE_FFMPEG" ] && pkgs="$pkgs ffmpeg"
|
||||||
|
|
|
@ -759,14 +759,11 @@ set(ALL_SRC_WX ${SRC_WX})
|
||||||
|
|
||||||
list(APPEND ALL_SRC_WX ${CMAKE_CURRENT_SOURCE_DIR}/macsupport.mm)
|
list(APPEND ALL_SRC_WX ${CMAKE_CURRENT_SOURCE_DIR}/macsupport.mm)
|
||||||
list(APPEND ALL_SRC_WX ${CMAKE_CURRENT_SOURCE_DIR}/widgets/dpi-support-mac.mm)
|
list(APPEND ALL_SRC_WX ${CMAKE_CURRENT_SOURCE_DIR}/widgets/dpi-support-mac.mm)
|
||||||
list(APPEND ALL_SRC_WX ${CMAKE_CURRENT_SOURCE_DIR}/widgets/dpi-support-win.cpp)
|
|
||||||
list(APPEND ALL_SRC_WX ${CMAKE_CURRENT_SOURCE_DIR}/widgets/dpi-support.cpp)
|
list(APPEND ALL_SRC_WX ${CMAKE_CURRENT_SOURCE_DIR}/widgets/dpi-support.cpp)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
list(APPEND SRC_WX macsupport.mm)
|
list(APPEND SRC_WX macsupport.mm)
|
||||||
list(APPEND SRC_WX widgets/dpi-support-mac.mm)
|
list(APPEND SRC_WX widgets/dpi-support-mac.mm)
|
||||||
elseif(WIN32)
|
|
||||||
list(APPEND SRC_WX widgets/dpi-support-win.cpp)
|
|
||||||
else()
|
else()
|
||||||
list(APPEND SRC_WX widgets/dpi-support.cpp)
|
list(APPEND SRC_WX widgets/dpi-support.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
@ -989,14 +986,13 @@ if(NOT TRANSLATIONS_ONLY)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
# This is necessary for DPI support and is not included by default in
|
# Force a re-link when the manifest file is modified.
|
||||||
# the msys2 build.
|
set_target_properties(visualboyadvance-m
|
||||||
target_link_libraries(visualboyadvance-m shcore)
|
PROPERTIES
|
||||||
|
LINK_DEPENDS
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/visualboyadvance-m.manifest")
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
# the debug lib libcmtd is linked in debug mode, so don't link the normal version
|
|
||||||
set_target_properties(visualboyadvance-m PROPERTIES LINK_FLAGS_DEBUG "/nodefaultlib:libcmt")
|
|
||||||
|
|
||||||
# Disable the auto-generated manifest from CMake.
|
# Disable the auto-generated manifest from CMake.
|
||||||
target_link_options(visualboyadvance-m PRIVATE "/MANIFEST:NO")
|
target_link_options(visualboyadvance-m PRIVATE "/MANIFEST:NO")
|
||||||
endif()
|
endif()
|
||||||
|
@ -1004,8 +1000,7 @@ if(NOT TRANSLATIONS_ONLY)
|
||||||
|
|
||||||
# link libgcc/libstdc++ statically on mingw
|
# link libgcc/libstdc++ statically on mingw
|
||||||
# and adjust link command when making a static binary
|
# and adjust link command when making a static binary
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_COMPILER_IS_GNUCXX AND VBAM_STATIC)
|
||||||
if(VBAM_STATIC)
|
|
||||||
# some dists don't have a static libpthread
|
# some dists don't have a static libpthread
|
||||||
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread ")
|
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread ")
|
||||||
|
|
||||||
|
@ -1023,7 +1018,6 @@ if(NOT TRANSLATIONS_ONLY)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT WIN32 AND NOT APPLE)
|
if(NOT WIN32 AND NOT APPLE)
|
||||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/visualboyadvance-m.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/visualboyadvance-m.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
|
||||||
|
|
|
@ -54,7 +54,6 @@ GameArea::GameArea()
|
||||||
, basic_width(GBAWidth)
|
, basic_width(GBAWidth)
|
||||||
, basic_height(GBAHeight)
|
, basic_height(GBAHeight)
|
||||||
, fullscreen(false)
|
, fullscreen(false)
|
||||||
, dpi_scale_factor_(widgets::DPIScaleFactorForWindow(this))
|
|
||||||
, paused(false)
|
, paused(false)
|
||||||
, pointer_blanked(false)
|
, pointer_blanked(false)
|
||||||
, mouse_active_time(0)
|
, mouse_active_time(0)
|
||||||
|
@ -746,11 +745,12 @@ void GameArea::DelBorder()
|
||||||
void GameArea::AdjustMinSize()
|
void GameArea::AdjustMinSize()
|
||||||
{
|
{
|
||||||
wxWindow* frame = wxGetApp().frame;
|
wxWindow* frame = wxGetApp().frame;
|
||||||
|
double dpi_scale_factor = widgets::DPIScaleFactorForWindow(this);
|
||||||
|
|
||||||
// note: could safely set min size to 1x or less regardless of video_scale
|
// note: could safely set min size to 1x or less regardless of video_scale
|
||||||
// but setting it to scaled size makes resizing to default easier
|
// but setting it to scaled size makes resizing to default easier
|
||||||
wxSize sz((std::ceil(basic_width * gopts.video_scale) * dpi_scale_factor_),
|
wxSize sz((std::ceil(basic_width * gopts.video_scale) * dpi_scale_factor),
|
||||||
(std::ceil(basic_height * gopts.video_scale) * dpi_scale_factor_));
|
(std::ceil(basic_height * gopts.video_scale) * dpi_scale_factor));
|
||||||
SetMinSize(sz);
|
SetMinSize(sz);
|
||||||
#if wxCHECK_VERSION(2, 8, 8)
|
#if wxCHECK_VERSION(2, 8, 8)
|
||||||
sz = frame->ClientToWindowSize(sz);
|
sz = frame->ClientToWindowSize(sz);
|
||||||
|
@ -763,9 +763,10 @@ void GameArea::AdjustMinSize()
|
||||||
void GameArea::LowerMinSize()
|
void GameArea::LowerMinSize()
|
||||||
{
|
{
|
||||||
wxWindow* frame = wxGetApp().frame;
|
wxWindow* frame = wxGetApp().frame;
|
||||||
|
double dpi_scale_factor = widgets::DPIScaleFactorForWindow(this);
|
||||||
|
|
||||||
wxSize sz(std::ceil(basic_width * dpi_scale_factor_),
|
wxSize sz(std::ceil(basic_width * dpi_scale_factor),
|
||||||
std::ceil(basic_height * dpi_scale_factor_));
|
std::ceil(basic_height * dpi_scale_factor));
|
||||||
|
|
||||||
SetMinSize(sz);
|
SetMinSize(sz);
|
||||||
// do not take decorations into account
|
// do not take decorations into account
|
||||||
|
@ -779,8 +780,10 @@ void GameArea::AdjustSize(bool force)
|
||||||
if (fullscreen)
|
if (fullscreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const wxSize newsz((std::ceil(basic_width * gopts.video_scale) * dpi_scale_factor_),
|
double dpi_scale_factor = widgets::DPIScaleFactorForWindow(this);
|
||||||
(std::ceil(basic_height * gopts.video_scale) * dpi_scale_factor_));
|
const wxSize newsz(
|
||||||
|
(std::ceil(basic_width * gopts.video_scale) * dpi_scale_factor),
|
||||||
|
(std::ceil(basic_height * gopts.video_scale) * dpi_scale_factor));
|
||||||
|
|
||||||
if (!force) {
|
if (!force) {
|
||||||
wxSize sz = GetClientSize();
|
wxSize sz = GetClientSize();
|
||||||
|
@ -959,16 +962,6 @@ void GameArea::OnKillFocus(wxFocusEvent& ev)
|
||||||
ev.Skip();
|
ev.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WX_HAS_NATIVE_HI_DPI_SUPPORT
|
|
||||||
void GameArea::OnDpiChanged(wxDPIChangedEvent&) {
|
|
||||||
if (dpi_scale_factor_ == GetDPIScaleFactor()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dpi_scale_factor_ = GetDPIScaleFactor();
|
|
||||||
AdjustSize(true);
|
|
||||||
}
|
|
||||||
#endif // WX_HAS_NATIVE_HI_DPI_SUPPORT
|
|
||||||
|
|
||||||
void GameArea::Pause()
|
void GameArea::Pause()
|
||||||
{
|
{
|
||||||
if (paused)
|
if (paused)
|
||||||
|
@ -1340,9 +1333,6 @@ void GameArea::OnSDLJoy(wxJoyEvent& ev)
|
||||||
BEGIN_EVENT_TABLE(GameArea, wxPanel)
|
BEGIN_EVENT_TABLE(GameArea, wxPanel)
|
||||||
EVT_IDLE(GameArea::OnIdle)
|
EVT_IDLE(GameArea::OnIdle)
|
||||||
EVT_SDLJOY(GameArea::OnSDLJoy)
|
EVT_SDLJOY(GameArea::OnSDLJoy)
|
||||||
#if WX_HAS_NATIVE_HI_DPI_SUPPORT
|
|
||||||
EVT_DPI_CHANGED(GameArea::OnDpiChanged)
|
|
||||||
#endif // WX_HAS_NATIVE_HI_DPI_SUPPORT
|
|
||||||
// FIXME: wxGTK does not generate motion events in MainFrame (not sure
|
// FIXME: wxGTK does not generate motion events in MainFrame (not sure
|
||||||
// what to do about it)
|
// what to do about it)
|
||||||
EVT_MOUSE_EVENTS(GameArea::MouseEvent)
|
EVT_MOUSE_EVENTS(GameArea::MouseEvent)
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
#include "widgets/dpi-support.h"
|
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
#include <VersionHelpers.h>
|
|
||||||
#include <shellscalingapi.h>
|
|
||||||
|
|
||||||
#include <wx/window.h>
|
|
||||||
|
|
||||||
namespace widgets {
|
|
||||||
|
|
||||||
double DPIScaleFactorForWindow(wxWindow* window) {
|
|
||||||
#if WX_HAS_NATIVE_HI_DPI_SUPPORT
|
|
||||||
return window->GetDPIScaleFactor();
|
|
||||||
#else
|
|
||||||
static constexpr double kStandardDpi = 96.0;
|
|
||||||
HWND wnd = window->GetHWND();
|
|
||||||
if (IsWindows10OrGreater()) {
|
|
||||||
// We can't properly resize on DPI/Monitor change, but neither can
|
|
||||||
// wxWidgets so we're consistent.
|
|
||||||
UINT dpi = GetDpiForWindow(wnd);
|
|
||||||
if (dpi != 0) {
|
|
||||||
return static_cast<int>(dpi) / kStandardDpi;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsWindows8Point1OrGreater()) {
|
|
||||||
HMONITOR monitor = MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST);
|
|
||||||
UINT xdpi;
|
|
||||||
UINT ydpi;
|
|
||||||
HRESULT success =
|
|
||||||
GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
|
||||||
if (success == S_OK) {
|
|
||||||
return static_cast<int>(ydpi) / kStandardDpi;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HDC dc = GetDC(wnd);
|
|
||||||
if (dc == nullptr) {
|
|
||||||
return 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ydpi = GetDeviceCaps(dc, LOGPIXELSY);
|
|
||||||
ReleaseDC(nullptr, dc);
|
|
||||||
|
|
||||||
return ydpi / kStandardDpi;
|
|
||||||
#endif // WX_HAS_NATIVE_HI_DPI_SUPPORT
|
|
||||||
}
|
|
||||||
|
|
||||||
void RequestHighResolutionOpenGlSurfaceForWindow(wxWindow*) {}
|
|
||||||
|
|
||||||
void GetRealPixelClientSize(wxWindow* window, int* x, int* y) {
|
|
||||||
window->GetClientSize(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace widgets
|
|
|
@ -36,7 +36,65 @@
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
#include "wx/gamecontrol.h"
|
#include "wx/gamecontrol.h"
|
||||||
|
|
||||||
IMPLEMENT_APP(wxvbamApp)
|
#ifdef __WXMSW__
|
||||||
|
|
||||||
|
int WinMain(HINSTANCE hInstance,
|
||||||
|
HINSTANCE hPrevInstance,
|
||||||
|
LPSTR lpCmdLine,
|
||||||
|
int nCmdShow) {
|
||||||
|
bool console_attached = AttachConsole(ATTACH_PARENT_PROCESS) != FALSE;
|
||||||
|
#ifdef DEBUG
|
||||||
|
// In debug builds, create a console if none is attached.
|
||||||
|
if (!console_attached) {
|
||||||
|
console_attached = AllocConsole() != FALSE;
|
||||||
|
}
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
// Redirect stdout/stderr to the console if one is attached.
|
||||||
|
// This code was taken from Dolphin.
|
||||||
|
// https://github.com/dolphin-emu/dolphin/blob/6cf99195c645f54d54c72322ad0312a0e56bc985/Source/Core/DolphinQt/Main.cpp#L112
|
||||||
|
HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
if (console_attached && stdout_handle) {
|
||||||
|
freopen("CONOUT$", "w", stdout);
|
||||||
|
freopen("CONOUT$", "w", stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up logging.
|
||||||
|
#ifdef DEBUG
|
||||||
|
wxLog::SetLogLevel(wxLOG_Trace);
|
||||||
|
#else // DEBUG
|
||||||
|
wxLog::SetLogLevel(wxLOG_Info);
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
// Redirect e.g. --help to stderr.
|
||||||
|
wxMessageOutput::Set(new wxMessageOutputStderr());
|
||||||
|
|
||||||
|
// This will be freed on wxEntry exit.
|
||||||
|
wxApp::SetInstance(new wxvbamApp());
|
||||||
|
return wxEntry(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // __WXMSW__
|
||||||
|
|
||||||
|
int main(int argc, char* argv) {
|
||||||
|
// Set up logging.
|
||||||
|
#ifdef DEBUG
|
||||||
|
wxLog::SetLogLevel(wxLOG_Trace);
|
||||||
|
#else // DEBUG
|
||||||
|
wxLog::SetLogLevel(wxLOG_Info);
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
// This will be freed on wxEntry exit.
|
||||||
|
wxApp::SetInstance(new wxvbamApp());
|
||||||
|
return wxEntry(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __WXMSW__
|
||||||
|
|
||||||
|
wxvbamApp& wxGetApp() {
|
||||||
|
return *static_cast<wxvbamApp*>(wxApp::GetInstance());
|
||||||
|
}
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(MainFrame, wxFrame)
|
IMPLEMENT_DYNAMIC_CLASS(MainFrame, wxFrame)
|
||||||
|
|
||||||
#ifndef NO_ONLINEUPDATES
|
#ifndef NO_ONLINEUPDATES
|
||||||
|
@ -194,36 +252,7 @@ wxString wxvbamApp::GetAbsolutePath(wxString path)
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxvbamApp::OnInit()
|
bool wxvbamApp::OnInit() {
|
||||||
{
|
|
||||||
// set up logging
|
|
||||||
#ifndef NDEBUG
|
|
||||||
wxLog::SetLogLevel(wxLOG_Trace);
|
|
||||||
#endif // !NDEBUG
|
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
// in windows console mode debug builds, redirect e.g. --help to stderr
|
|
||||||
#ifndef NDEBUG
|
|
||||||
wxMessageOutput::Set(new wxMessageOutputStderr());
|
|
||||||
#endif // !NDEBUG
|
|
||||||
|
|
||||||
bool console_attached = AttachConsole(ATTACH_PARENT_PROCESS) != FALSE;
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// In debug builds, create a console if none is attached.
|
|
||||||
if (!console_attached) {
|
|
||||||
console_attached = AllocConsole() != FALSE;
|
|
||||||
}
|
|
||||||
#endif // !NDEBUG
|
|
||||||
|
|
||||||
// Redirect stdout/stderr to the console if one is attached.
|
|
||||||
// This code was taken from Dolphin.
|
|
||||||
// https://github.com/dolphin-emu/dolphin/blob/6cf99195c645f54d54c72322ad0312a0e56bc985/Source/Core/DolphinQt/Main.cpp#L112
|
|
||||||
HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
if (console_attached && stdout_handle) {
|
|
||||||
freopen("CONOUT$", "w", stdout);
|
|
||||||
freopen("CONOUT$", "w", stderr);
|
|
||||||
}
|
|
||||||
#endif // __WXMSW__
|
|
||||||
using_wayland = IsItWayland();
|
using_wayland = IsItWayland();
|
||||||
|
|
||||||
// use consistent names for config
|
// use consistent names for config
|
||||||
|
|
|
@ -642,7 +642,6 @@ protected:
|
||||||
|
|
||||||
int basic_width, basic_height;
|
int basic_width, basic_height;
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
double dpi_scale_factor_ = 0;
|
|
||||||
|
|
||||||
bool paused;
|
bool paused;
|
||||||
void OnIdle(wxIdleEvent&);
|
void OnIdle(wxIdleEvent&);
|
||||||
|
@ -653,9 +652,6 @@ protected:
|
||||||
void EraseBackground(wxEraseEvent& ev);
|
void EraseBackground(wxEraseEvent& ev);
|
||||||
void OnSize(wxSizeEvent& ev);
|
void OnSize(wxSizeEvent& ev);
|
||||||
void OnKillFocus(wxFocusEvent& ev);
|
void OnKillFocus(wxFocusEvent& ev);
|
||||||
#if WX_HAS_NATIVE_HI_DPI_SUPPORT
|
|
||||||
void OnDpiChanged(wxDPIChangedEvent& ev);
|
|
||||||
#endif // WX_HAS_NATIVE_HI_DPI_SUPPORT
|
|
||||||
|
|
||||||
#ifndef NO_FFMPEG
|
#ifndef NO_FFMPEG
|
||||||
recording::MediaRecorder snd_rec, vid_rec;
|
recording::MediaRecorder snd_rec, vid_rec;
|
||||||
|
|
Loading…
Reference in New Issue