[hidpi] Implement full HiDPI support
This converts the HiDPIAware into a series of helper functions, using wxWidgets native support starting with wxWidgets 3.1.4. Custom implementations are provided for Mac and Windows. In addition, this fixes a few issues with the Windows build: * Use the same defines variables in the MSVC and MinGW builds, with g++ and Clang. * Add a custom manifest for the application, indicating full DPI support and support for recent Windows versions so the application will no longer run in compatibility mode by default. * Manually spawn a console in debug builds if none is attached and always use the parent console if it is available otherwise, even in release builds. This also removes the /subsystem:console linker argument.
This commit is contained in:
parent
95337da558
commit
0d86432a31
|
@ -89,6 +89,11 @@ if(NOT WIN32 AND NOT APPLE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Win32 definitions common to all toolchains.
|
||||||
|
if (WIN32)
|
||||||
|
add_definitions(-D_UNICODE -DUNICODE -DwxUSE_GUI=1 -D__WXMSW__ -DWINVER=0x0A00 -DNTDDI_VERSION=0x0A000007)
|
||||||
|
endif()
|
||||||
|
|
||||||
# on VS with vcpkg we can't use FindwxWidgets, we have to set everything up
|
# on VS with vcpkg we can't use FindwxWidgets, we have to set everything up
|
||||||
# manually because the package is broken
|
# manually because the package is broken
|
||||||
if(WIN32 AND CMAKE_TOOLCHAIN_FILE MATCHES vcpkg AND (X86_32 OR X86_64))
|
if(WIN32 AND CMAKE_TOOLCHAIN_FILE MATCHES vcpkg AND (X86_32 OR X86_64))
|
||||||
|
@ -120,8 +125,6 @@ if(WIN32 AND CMAKE_TOOLCHAIN_FILE MATCHES vcpkg AND (X86_32 OR X86_64))
|
||||||
add_definitions(-DWXUSINGDLL)
|
add_definitions(-DWXUSINGDLL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_definitions(-D_UNICODE -DUNICODE -DwxUSE_GUI=1 -D__WXMSW__ -DwxUSE_RC_MANIFEST -DwxUSE_DPI_AWARE_MANIFEST=2)
|
|
||||||
|
|
||||||
set(common_prefix ${_VCPKG_INSTALLED_DIR}/${WINARCH}-windows${arch_suffix})
|
set(common_prefix ${_VCPKG_INSTALLED_DIR}/${WINARCH}-windows${arch_suffix})
|
||||||
set(dbg_prefix ${_VCPKG_INSTALLED_DIR}/${WINARCH}-windows${arch_suffix}/debug)
|
set(dbg_prefix ${_VCPKG_INSTALLED_DIR}/${WINARCH}-windows${arch_suffix}/debug)
|
||||||
set(installed_prefix ${_VCPKG_INSTALLED_DIR}/${WINARCH}-windows${arch_suffix}/${path_prefix})
|
set(installed_prefix ${_VCPKG_INSTALLED_DIR}/${WINARCH}-windows${arch_suffix}/${path_prefix})
|
||||||
|
@ -755,9 +758,17 @@ set(
|
||||||
set(ALL_SRC_WX ${SRC_WX})
|
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-win.cpp)
|
||||||
|
list(APPEND ALL_SRC_WX ${CMAKE_CURRENT_SOURCE_DIR}/widgets/dpi-support.cpp)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
list(APPEND SRC_WX ${CMAKE_CURRENT_SOURCE_DIR}/macsupport.mm)
|
list(APPEND SRC_WX macsupport.mm)
|
||||||
|
list(APPEND SRC_WX widgets/dpi-support-mac.mm)
|
||||||
|
elseif(WIN32)
|
||||||
|
list(APPEND SRC_WX widgets/dpi-support-win.cpp)
|
||||||
|
else()
|
||||||
|
list(APPEND SRC_WX widgets/dpi-support.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(
|
set(
|
||||||
|
@ -776,6 +787,7 @@ set(
|
||||||
wayland.h
|
wayland.h
|
||||||
wxutil.h
|
wxutil.h
|
||||||
config/user-input.h
|
config/user-input.h
|
||||||
|
widgets/dpi-support.h
|
||||||
widgets/wx/gamecontrol.h
|
widgets/wx/gamecontrol.h
|
||||||
widgets/wx/keyedit.h
|
widgets/wx/keyedit.h
|
||||||
widgets/wx/joyedit.h
|
widgets/wx/joyedit.h
|
||||||
|
@ -976,18 +988,23 @@ if(NOT TRANSLATIONS_ONLY)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# link libgcc/libstdc++ statically on mingw
|
|
||||||
# and adjust link command when making a static binary
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
# Build a console app in debug mode on Windows
|
# This is necessary for DPI support and is not included by default in
|
||||||
if(CMAKE_BUILD_TYPE MATCHES "^(Debug|RelWithDebInfo)$")
|
# the msys2 build.
|
||||||
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -Wl,--subsystem,console")
|
target_link_libraries(visualboyadvance-m shcore)
|
||||||
else()
|
|
||||||
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -Wl,--subsystem,windows")
|
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.
|
||||||
|
target_link_options(visualboyadvance-m PRIVATE "/MANIFEST:NO")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# link libgcc/libstdc++ statically on mingw
|
||||||
|
# and adjust link command when making a static binary
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
if(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 ")
|
||||||
|
@ -1006,20 +1023,8 @@ if(NOT TRANSLATIONS_ONLY)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
elseif(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 /subsystem:console")
|
|
||||||
|
|
||||||
# Disable the auto-generated manifest from CMake.
|
|
||||||
target_link_options(visualboyadvance-m PRIVATE "/MANIFEST:NO")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Make the app a console app in debug mode to get log messages.
|
|
||||||
if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL Debug)
|
|
||||||
target_compile_definitions(visualboyadvance-m PRIVATE -DWIN32_CONSOLE_APP)
|
|
||||||
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)
|
||||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/visualboyadvance-m.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/appdata)
|
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/visualboyadvance-m.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/appdata)
|
||||||
|
|
|
@ -7,41 +7,6 @@
|
||||||
#include "wxvbam.h"
|
#include "wxvbam.h"
|
||||||
#include "drawing.h"
|
#include "drawing.h"
|
||||||
|
|
||||||
double HiDPIAware::HiDPIScaleFactor()
|
|
||||||
{
|
|
||||||
if (hidpi_scale_factor == 0) {
|
|
||||||
NSWindow* window = [(NSView*)GetWindow()->GetHandle() window];
|
|
||||||
|
|
||||||
if ([window respondsToSelector:@selector(backingScaleFactor)]) {
|
|
||||||
hidpi_scale_factor = [window backingScaleFactor];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hidpi_scale_factor = 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hidpi_scale_factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HiDPIAware::RequestHighResolutionOpenGLSurface()
|
|
||||||
{
|
|
||||||
NSView* view = (NSView*)(GetWindow()->GetHandle());
|
|
||||||
|
|
||||||
if ([view respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) {
|
|
||||||
[view setWantsBestResolutionOpenGLSurface:YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HiDPIAware::GetRealPixelClientSize(int* x, int* y)
|
|
||||||
{
|
|
||||||
NSView* view = (NSView*)(GetWindow()->GetHandle());
|
|
||||||
|
|
||||||
NSSize backing_size = [view convertSizeToBacking:view.bounds.size];
|
|
||||||
|
|
||||||
*x = backing_size.width;
|
|
||||||
*y = backing_size.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
Quartz2DDrawingPanel::Quartz2DDrawingPanel(wxWindow* parent, int _width, int _height)
|
Quartz2DDrawingPanel::Quartz2DDrawingPanel(wxWindow* parent, int _width, int _height)
|
||||||
: BasicDrawingPanel(parent, _width, _height)
|
: BasicDrawingPanel(parent, _width, _height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,6 +54,7 @@ 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)
|
||||||
|
@ -745,12 +746,11 @@ void GameArea::DelBorder()
|
||||||
void GameArea::AdjustMinSize()
|
void GameArea::AdjustMinSize()
|
||||||
{
|
{
|
||||||
wxWindow* frame = wxGetApp().frame;
|
wxWindow* frame = wxGetApp().frame;
|
||||||
double hidpi_scale_factor = HiDPIScaleFactor();
|
|
||||||
|
|
||||||
// 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) / hidpi_scale_factor),
|
wxSize sz((std::ceil(basic_width * gopts.video_scale) * dpi_scale_factor_),
|
||||||
(std::ceil(basic_height * gopts.video_scale) / hidpi_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,10 +763,9 @@ void GameArea::AdjustMinSize()
|
||||||
void GameArea::LowerMinSize()
|
void GameArea::LowerMinSize()
|
||||||
{
|
{
|
||||||
wxWindow* frame = wxGetApp().frame;
|
wxWindow* frame = wxGetApp().frame;
|
||||||
double hidpi_scale_factor = HiDPIScaleFactor();
|
|
||||||
|
|
||||||
wxSize sz(std::ceil(basic_width / hidpi_scale_factor),
|
wxSize sz(std::ceil(basic_width * dpi_scale_factor_),
|
||||||
std::ceil(basic_height / hidpi_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
|
||||||
|
@ -780,9 +779,8 @@ void GameArea::AdjustSize(bool force)
|
||||||
if (fullscreen)
|
if (fullscreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double hidpi_scale_factor = HiDPIScaleFactor();
|
const wxSize newsz((std::ceil(basic_width * gopts.video_scale) * dpi_scale_factor_),
|
||||||
const wxSize newsz((std::ceil(basic_width * gopts.video_scale) / hidpi_scale_factor),
|
(std::ceil(basic_height * gopts.video_scale) * dpi_scale_factor_));
|
||||||
(std::ceil(basic_height * gopts.video_scale) / hidpi_scale_factor));
|
|
||||||
|
|
||||||
if (!force) {
|
if (!force) {
|
||||||
wxSize sz = GetClientSize();
|
wxSize sz = GetClientSize();
|
||||||
|
@ -961,6 +959,16 @@ 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)
|
||||||
|
@ -1332,6 +1340,9 @@ 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)
|
||||||
|
@ -2086,7 +2097,7 @@ GLDrawingPanel::GLDrawingPanel(wxWindow* parent, int _width, int _height)
|
||||||
, wxglc(parent, wxID_ANY, glopts, wxPoint(0, 0), parent->GetClientSize(),
|
, wxglc(parent, wxID_ANY, glopts, wxPoint(0, 0), parent->GetClientSize(),
|
||||||
wxFULL_REPAINT_ON_RESIZE | wxWANTS_CHARS)
|
wxFULL_REPAINT_ON_RESIZE | wxWANTS_CHARS)
|
||||||
{
|
{
|
||||||
RequestHighResolutionOpenGLSurface();
|
widgets::RequestHighResolutionOpenGlSurfaceForWindow(this);
|
||||||
#ifndef wxGL_IMPLICIT_CONTEXT
|
#ifndef wxGL_IMPLICIT_CONTEXT
|
||||||
ctx = new wxGLContext(this);
|
ctx = new wxGLContext(this);
|
||||||
SetCurrent(*ctx);
|
SetCurrent(*ctx);
|
||||||
|
@ -2251,7 +2262,7 @@ void GLDrawingPanel::AdjustViewport()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
GetRealPixelClientSize(&x, &y);
|
widgets::GetRealPixelClientSize(this, &x, &y);
|
||||||
glViewport(0, 0, x, y);
|
glViewport(0, 0, x, y);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -2514,24 +2525,3 @@ void GameArea::ShowMenuBar()
|
||||||
menu_bar_hidden = false;
|
menu_bar_hidden = false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// stub HiDPI methods, see macsupport.mm for the Mac support
|
|
||||||
#ifndef __WXMAC__
|
|
||||||
double HiDPIAware::HiDPIScaleFactor()
|
|
||||||
{
|
|
||||||
if (hidpi_scale_factor == 0) {
|
|
||||||
hidpi_scale_factor = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hidpi_scale_factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HiDPIAware::RequestHighResolutionOpenGLSurface()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void HiDPIAware::GetRealPixelClientSize(int* x, int* y)
|
|
||||||
{
|
|
||||||
GetWindow()->GetClientSize(x, y);
|
|
||||||
}
|
|
||||||
#endif // HiDPI stubs
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<dependency>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity
|
||||||
|
type="win32"
|
||||||
|
name="Microsoft.Windows.Common-Controls"
|
||||||
|
version="6.0.0.0"
|
||||||
|
processorArchitecture="*"
|
||||||
|
publicKeyToken="6595b64144ccf1df"
|
||||||
|
language="*"
|
||||||
|
/>
|
||||||
|
</dependentAssembly>
|
||||||
|
</dependency>
|
||||||
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<security>
|
||||||
|
<requestedPrivileges>
|
||||||
|
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||||
|
</requestedPrivileges>
|
||||||
|
</security>
|
||||||
|
</trustInfo>
|
||||||
|
<asmv3:application>
|
||||||
|
<asmv3:windowsSettings>
|
||||||
|
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, system</dpiAwareness>
|
||||||
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||||
|
</asmv3:windowsSettings>
|
||||||
|
</asmv3:application>
|
||||||
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
|
<application>
|
||||||
|
<!-- Windows Vista -->
|
||||||
|
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
|
||||||
|
<!-- Windows 7 -->
|
||||||
|
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||||
|
<!-- Windows 8 -->
|
||||||
|
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
|
||||||
|
<!-- Windows 8.1 -->
|
||||||
|
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
||||||
|
<!-- Windows 10 -->
|
||||||
|
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||||
|
</application>
|
||||||
|
</compatibility>
|
||||||
|
</assembly>
|
|
@ -0,0 +1,47 @@
|
||||||
|
#include "widgets/dpi-support.h"
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#include <wx/window.h>
|
||||||
|
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
double DPIScaleFactorForWindow(wxWindow* window) {
|
||||||
|
#if WX_HAS_NATIVE_HI_DPI_SUPPORT
|
||||||
|
return window->GetDPIScaleFactor();
|
||||||
|
#else
|
||||||
|
NSWindow* ns_window = [(NSView*)window->GetHandle() window];
|
||||||
|
|
||||||
|
if ([ns_window respondsToSelector:@selector(backingScaleFactor)]) {
|
||||||
|
return [ns_window backingScaleFactor];
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
#endif // WX_HAS_NATIVE_HI_DPI_SUPPORT
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestHighResolutionOpenGlSurfaceForWindow(wxWindow* window) {
|
||||||
|
#if !WX_HAS_NATIVE_HI_DPI_SUPPORT
|
||||||
|
NSView* view = (NSView*)(window->GetHandle());
|
||||||
|
|
||||||
|
if ([view respondsToSelector:@selector
|
||||||
|
(setWantsBestResolutionOpenGLSurface:)]) {
|
||||||
|
[view setWantsBestResolutionOpenGLSurface:YES];
|
||||||
|
}
|
||||||
|
#endif // !WX_HAS_NATIVE_HI_DPI_SUPPORT
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetRealPixelClientSize(wxWindow* window, int* x, int* y) {
|
||||||
|
#if WX_HAS_NATIVE_HI_DPI_SUPPORT
|
||||||
|
window->GetClientSize(x, y);
|
||||||
|
#else
|
||||||
|
NSView* view = (NSView*)(window->GetHandle());
|
||||||
|
|
||||||
|
NSSize backing_size = [view convertSizeToBacking:view.bounds.size];
|
||||||
|
|
||||||
|
*x = backing_size.width;
|
||||||
|
*y = backing_size.height;
|
||||||
|
#endif // WX_HAS_NATIVE_HI_DPI_SUPPORT
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace widgets
|
|
@ -0,0 +1,55 @@
|
||||||
|
#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
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "widgets/dpi-support.h"
|
||||||
|
|
||||||
|
#include <wx/window.h>
|
||||||
|
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
double DPIScaleFactorForWindow(wxWindow* window) {
|
||||||
|
#if WX_HAS_NATIVE_HI_DPI_SUPPORT
|
||||||
|
return window->GetDPIScaleFactor();
|
||||||
|
#else
|
||||||
|
return window->GetContentScaleFactor();
|
||||||
|
#endif // WX_HAS_NATIVE_HI_DPI_SUPPORT
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestHighResolutionOpenGlSurfaceForWindow(wxWindow*) {}
|
||||||
|
|
||||||
|
void GetRealPixelClientSize(wxWindow* window, int* x, int* y) {
|
||||||
|
window->GetClientSize(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace widgets
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef VBAM_WX_WIDGETS_DPI_SUPPORT_
|
||||||
|
#define VBAM_WX_WIDGETS_DPI_SUPPORT_
|
||||||
|
|
||||||
|
#include <wx/version.h>
|
||||||
|
|
||||||
|
#if wxCHECK_VERSION(3, 1, 4)
|
||||||
|
#define WX_HAS_NATIVE_HI_DPI_SUPPORT 1
|
||||||
|
#else
|
||||||
|
#define WX_HAS_NATIVE_HI_DPI_SUPPORT 0
|
||||||
|
#endif // wxCHECK_VERSION(3,1,4)
|
||||||
|
|
||||||
|
// Forward declaration.
|
||||||
|
class wxWindow;
|
||||||
|
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
double DPIScaleFactorForWindow(wxWindow* window);
|
||||||
|
void RequestHighResolutionOpenGlSurfaceForWindow(wxWindow* window);
|
||||||
|
void GetRealPixelClientSize(wxWindow* window, int* x, int* y);
|
||||||
|
|
||||||
|
} // namespace widgets
|
||||||
|
|
||||||
|
#endif // VBAM_WX_WIDGETS_DPI_SUPPORT_
|
|
@ -5,6 +5,10 @@
|
||||||
|
|
||||||
#include "wxvbam.h"
|
#include "wxvbam.h"
|
||||||
|
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <wx/cmdline.h>
|
#include <wx/cmdline.h>
|
||||||
#include <wx/file.h>
|
#include <wx/file.h>
|
||||||
|
@ -35,15 +39,6 @@
|
||||||
IMPLEMENT_APP(wxvbamApp)
|
IMPLEMENT_APP(wxvbamApp)
|
||||||
IMPLEMENT_DYNAMIC_CLASS(MainFrame, wxFrame)
|
IMPLEMENT_DYNAMIC_CLASS(MainFrame, wxFrame)
|
||||||
|
|
||||||
#ifdef WIN32_CONSOLE_APP
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
return WinMain(::GetModuleHandle(NULL), 0, 0, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NO_ONLINEUPDATES
|
#ifndef NO_ONLINEUPDATES
|
||||||
#include "autoupdater/autoupdater.h"
|
#include "autoupdater/autoupdater.h"
|
||||||
#endif // NO_ONLINEUPDATES
|
#endif // NO_ONLINEUPDATES
|
||||||
|
@ -199,28 +194,36 @@ wxString wxvbamApp::GetAbsolutePath(wxString path)
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
#include <wx/msw/private.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool wxvbamApp::OnInit()
|
bool wxvbamApp::OnInit()
|
||||||
{
|
{
|
||||||
// set up logging
|
// set up logging
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
wxLog::SetLogLevel(wxLOG_Trace);
|
wxLog::SetLogLevel(wxLOG_Trace);
|
||||||
#endif
|
#endif // !NDEBUG
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
// in windows console mode debug builds, redirect e.g. --help to stderr
|
// in windows console mode debug builds, redirect e.g. --help to stderr
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
wxMessageOutput::Set(new wxMessageOutputStderr());
|
wxMessageOutput::Set(new wxMessageOutputStderr());
|
||||||
#endif
|
#endif // !NDEBUG
|
||||||
// turn off output buffering to support windows consoles
|
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
bool console_attached = AttachConsole(ATTACH_PARENT_PROCESS) != FALSE;
|
||||||
setvbuf(stderr, NULL, _IONBF, 0);
|
#ifndef NDEBUG
|
||||||
// redirect stderr to stdout
|
// In debug builds, create a console if none is attached.
|
||||||
dup2(1, 2);
|
if (!console_attached) {
|
||||||
#endif
|
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
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <wx/propdlg.h>
|
#include <wx/propdlg.h>
|
||||||
#include <wx/datetime.h>
|
#include <wx/datetime.h>
|
||||||
|
|
||||||
|
#include "widgets/dpi-support.h"
|
||||||
#include "wx/joyedit.h"
|
#include "wx/joyedit.h"
|
||||||
#include "wx/keyedit.h"
|
#include "wx/keyedit.h"
|
||||||
#include "wx/sdljoy.h"
|
#include "wx/sdljoy.h"
|
||||||
|
@ -388,18 +389,6 @@ private:
|
||||||
#include "cmdhandlers.h"
|
#include "cmdhandlers.h"
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper class to add HiDPI awareness (mostly for Mac OS X)
|
|
||||||
class HiDPIAware {
|
|
||||||
public:
|
|
||||||
HiDPIAware() { hidpi_scale_factor = 0; }
|
|
||||||
virtual double HiDPIScaleFactor();
|
|
||||||
virtual void RequestHighResolutionOpenGLSurface();
|
|
||||||
virtual void GetRealPixelClientSize(int* x, int* y);
|
|
||||||
virtual wxWindow* GetWindow() = 0;
|
|
||||||
private:
|
|
||||||
double hidpi_scale_factor;
|
|
||||||
};
|
|
||||||
|
|
||||||
// a class for polling joystick keys
|
// a class for polling joystick keys
|
||||||
class JoystickPoller : public wxTimer {
|
class JoystickPoller : public wxTimer {
|
||||||
public:
|
public:
|
||||||
|
@ -519,7 +508,7 @@ class DrawingPanelBase;
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class GameArea : public wxPanel, public HiDPIAware {
|
class GameArea : public wxPanel {
|
||||||
public:
|
public:
|
||||||
GameArea();
|
GameArea();
|
||||||
virtual ~GameArea();
|
virtual ~GameArea();
|
||||||
|
@ -641,8 +630,6 @@ public:
|
||||||
void StartGamePlayback(const wxString& fname);
|
void StartGamePlayback(const wxString& fname);
|
||||||
void StopGamePlayback();
|
void StopGamePlayback();
|
||||||
|
|
||||||
virtual wxWindow* GetWindow() { return this; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MainFrame* main_frame;
|
MainFrame* main_frame;
|
||||||
|
|
||||||
|
@ -655,6 +642,7 @@ 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&);
|
||||||
|
@ -665,6 +653,9 @@ 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;
|
||||||
|
@ -716,7 +707,7 @@ extern bool cmditem_lt(const struct cmditem& cmd1, const struct cmditem& cmd2);
|
||||||
|
|
||||||
class FilterThread;
|
class FilterThread;
|
||||||
|
|
||||||
class DrawingPanelBase : public HiDPIAware {
|
class DrawingPanelBase {
|
||||||
public:
|
public:
|
||||||
DrawingPanelBase(int _width, int _height);
|
DrawingPanelBase(int _width, int _height);
|
||||||
~DrawingPanelBase();
|
~DrawingPanelBase();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
AAAAA_MAINICON ICON "icons/visualboyadvance-m.ico"
|
AAAAA_MAINICON ICON "icons/visualboyadvance-m.ico"
|
||||||
|
|
||||||
|
#define wxUSE_NO_MANIFEST 1
|
||||||
#include "wx/msw/wx.rc"
|
#include "wx/msw/wx.rc"
|
||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
@ -23,6 +24,8 @@ WINSPARKLE_DLL_RC RCDATA WINSPARKLE_DLL_PATH
|
||||||
|
|
||||||
#endif /* NO_ONLINEUPDATES */
|
#endif /* NO_ONLINEUPDATES */
|
||||||
|
|
||||||
|
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "visualboyadvance-m.manifest"
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION VER_FILEVERSION
|
FILEVERSION VER_FILEVERSION
|
||||||
PRODUCTVERSION VER_PRODUCTVERSION
|
PRODUCTVERSION VER_PRODUCTVERSION
|
||||||
|
|
Loading…
Reference in New Issue