GUI: new scaling factor detection technique
This commit is contained in:
parent
b545fa7f3c
commit
d96674186e
|
@ -593,6 +593,7 @@ src/gui/piano.cpp
|
||||||
src/gui/presets.cpp
|
src/gui/presets.cpp
|
||||||
src/gui/regView.cpp
|
src/gui/regView.cpp
|
||||||
src/gui/sampleEdit.cpp
|
src/gui/sampleEdit.cpp
|
||||||
|
src/gui/scaling.cpp
|
||||||
src/gui/settings.cpp
|
src/gui/settings.cpp
|
||||||
src/gui/songInfo.cpp
|
src/gui/songInfo.cpp
|
||||||
src/gui/songNotes.cpp
|
src/gui/songNotes.cpp
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||||
|
|
||||||
#define DIV_VERSION "dev121"
|
#define DIV_VERSION "dev122"
|
||||||
#define DIV_ENGINE_VERSION 121
|
#define DIV_ENGINE_VERSION 122
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
|
116
src/gui/gui.cpp
116
src/gui/gui.cpp
|
@ -1,3 +1,5 @@
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
// OK, sorry for inserting the define here but I'm so tired of this extension
|
||||||
/**
|
/**
|
||||||
* Furnace Tracker - multi-system chiptune tracker
|
* Furnace Tracker - multi-system chiptune tracker
|
||||||
* Copyright (C) 2021-2022 tildearrow and contributors
|
* Copyright (C) 2021-2022 tildearrow and contributors
|
||||||
|
@ -20,7 +22,7 @@
|
||||||
// I hate you clangd extension!
|
// I hate you clangd extension!
|
||||||
// how about you DON'T insert random headers before this freaking important
|
// how about you DON'T insert random headers before this freaking important
|
||||||
// define!!!!!!
|
// define!!!!!!
|
||||||
#define _USE_MATH_DEFINES
|
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "icon.h"
|
#include "icon.h"
|
||||||
|
@ -36,17 +38,12 @@
|
||||||
#include "plot_nolerp.h"
|
#include "plot_nolerp.h"
|
||||||
#include "guiConst.h"
|
#include "guiConst.h"
|
||||||
#include "intConst.h"
|
#include "intConst.h"
|
||||||
|
#include "scaling.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include <fmt/printf.h>
|
#include <fmt/printf.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
extern "C" {
|
|
||||||
#include "macstuff.h"
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
@ -4898,9 +4895,7 @@ bool FurnaceGUI::loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FurnaceGUI::init() {
|
bool FurnaceGUI::init() {
|
||||||
#ifndef __APPLE__
|
logI("initializing GUI.");
|
||||||
float dpiScaleF;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
String homeDir=getHomeDir();
|
String homeDir=getHomeDir();
|
||||||
workingDir=e->getConfString("lastDir",homeDir);
|
workingDir=e->getConfString("lastDir",homeDir);
|
||||||
|
@ -5004,10 +4999,6 @@ bool FurnaceGUI::init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.dpiScale>=0.5f) {
|
|
||||||
dpiScale=settings.dpiScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
initSystemPresets();
|
initSystemPresets();
|
||||||
|
|
||||||
e->setAutoNotePoly(noteInputPoly);
|
e->setAutoNotePoly(noteInputPoly);
|
||||||
|
@ -5017,6 +5008,7 @@ bool FurnaceGUI::init() {
|
||||||
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS,"0");
|
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS,"0");
|
||||||
// don't disable compositing on KWin
|
// don't disable compositing on KWin
|
||||||
#if SDL_VERSION_ATLEAST(2,0,22)
|
#if SDL_VERSION_ATLEAST(2,0,22)
|
||||||
|
logV("setting window type to NORMAL.");
|
||||||
SDL_SetHint(SDL_HINT_X11_WINDOW_TYPE,"_NET_WM_WINDOW_TYPE_NORMAL");
|
SDL_SetHint(SDL_HINT_X11_WINDOW_TYPE,"_NET_WM_WINDOW_TYPE_NORMAL");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -5025,14 +5017,28 @@ bool FurnaceGUI::init() {
|
||||||
|
|
||||||
const char* videoBackend=SDL_GetCurrentVideoDriver();
|
const char* videoBackend=SDL_GetCurrentVideoDriver();
|
||||||
if (videoBackend!=NULL) {
|
if (videoBackend!=NULL) {
|
||||||
|
logV("video backend: %s",videoBackend);
|
||||||
if (strcmp(videoBackend,"wayland")==0 ||
|
if (strcmp(videoBackend,"wayland")==0 ||
|
||||||
strcmp(videoBackend,"cocoa")==0 ||
|
strcmp(videoBackend,"cocoa")==0 ||
|
||||||
strcmp(videoBackend,"uikit")==0) {
|
strcmp(videoBackend,"uikit")==0) {
|
||||||
sysManagedScale=true;
|
sysManagedScale=true;
|
||||||
|
logV("scaling managed by system.");
|
||||||
|
} else {
|
||||||
|
logV("scaling managed by application.");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
logV("could not get video backend name!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get scaling factor
|
// get scale factor
|
||||||
|
if (settings.dpiScale>=0.5f) {
|
||||||
|
logD("setting UI scale factor from config (%f).",settings.dpiScale);
|
||||||
|
dpiScale=settings.dpiScale;
|
||||||
|
} else {
|
||||||
|
logD("auto-detecting UI scale factor.");
|
||||||
|
dpiScale=getScaleFactor(videoBackend);
|
||||||
|
logD("scale factor: %f",dpiScale);
|
||||||
|
}
|
||||||
|
|
||||||
#if !(defined(__APPLE__) || defined(_WIN32))
|
#if !(defined(__APPLE__) || defined(_WIN32))
|
||||||
// get the icon (on macOS and Windows the icon is bundled with the app)
|
// get the icon (on macOS and Windows the icon is bundled with the app)
|
||||||
|
@ -5046,10 +5052,8 @@ bool FurnaceGUI::init() {
|
||||||
scrX=0;
|
scrX=0;
|
||||||
scrY=0;
|
scrY=0;
|
||||||
#else
|
#else
|
||||||
double defaultW=1280*(sysManagedScale?1.0:dpiScale);
|
scrW=scrConfW=e->getConfInt("lastWindowWidth",1280);
|
||||||
double defaultH=800*(sysManagedScale?1.0:dpiScale);
|
scrH=scrConfH=e->getConfInt("lastWindowHeight",800);
|
||||||
scrW=scrConfW=e->getConfInt("lastWindowWidth",(int)defaultW);
|
|
||||||
scrH=scrConfH=e->getConfInt("lastWindowHeight",(int)defaultH);
|
|
||||||
scrX=scrConfX=e->getConfInt("lastWindowX",SDL_WINDOWPOS_CENTERED);
|
scrX=scrConfX=e->getConfInt("lastWindowX",SDL_WINDOWPOS_CENTERED);
|
||||||
scrY=scrConfY=e->getConfInt("lastWindowY",SDL_WINDOWPOS_CENTERED);
|
scrY=scrConfY=e->getConfInt("lastWindowY",SDL_WINDOWPOS_CENTERED);
|
||||||
scrMax=e->getConfBool("lastWindowMax",false);
|
scrMax=e->getConfBool("lastWindowMax",false);
|
||||||
|
@ -5057,6 +5061,22 @@ bool FurnaceGUI::init() {
|
||||||
portrait=(scrW<scrH);
|
portrait=(scrW<scrH);
|
||||||
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
||||||
|
|
||||||
|
// if old config, scale size as it was stored unscaled before
|
||||||
|
if (e->getConfInt("configVersion",0)<122 && !sysManagedScale) {
|
||||||
|
logD("scaling window size to scale factor because configVersion is not present.");
|
||||||
|
scrW*=dpiScale;
|
||||||
|
scrH*=dpiScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// predict the canvas size
|
||||||
|
if (sysManagedScale) {
|
||||||
|
canvasW=scrW*dpiScale;
|
||||||
|
canvasH=scrH*dpiScale;
|
||||||
|
} else {
|
||||||
|
canvasW=scrW;
|
||||||
|
canvasH=scrH;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(IS_MOBILE)
|
#if !defined(__APPLE__) && !defined(IS_MOBILE)
|
||||||
SDL_Rect displaySize;
|
SDL_Rect displaySize;
|
||||||
#endif
|
#endif
|
||||||
|
@ -5070,47 +5090,41 @@ bool FurnaceGUI::init() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
logV("window size: %dx%d",scrW,scrH);
|
||||||
|
|
||||||
sdlWin=SDL_CreateWindow("Furnace",scrX,scrY,scrW,scrH,SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI|(scrMax?SDL_WINDOW_MAXIMIZED:0)|(fullScreen?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
sdlWin=SDL_CreateWindow("Furnace",scrX,scrY,scrW,scrH,SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI|(scrMax?SDL_WINDOW_MAXIMIZED:0)|(fullScreen?SDL_WINDOW_FULLSCREEN_DESKTOP:0));
|
||||||
if (sdlWin==NULL) {
|
if (sdlWin==NULL) {
|
||||||
lastError=fmt::sprintf("could not open window! %s",SDL_GetError());
|
lastError=fmt::sprintf("could not open window! %s",SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove this
|
|
||||||
#ifndef __APPLE__
|
|
||||||
if (settings.dpiScale<0.5f) {
|
|
||||||
// TODO: replace with a function to actually detect the display scaling factor as it's unreliable.
|
|
||||||
SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(sdlWin),&dpiScaleF,NULL,NULL);
|
|
||||||
dpiScale=round(dpiScaleF/96.0f);
|
|
||||||
if (dpiScale<1) dpiScale=1;
|
|
||||||
#ifndef IS_MOBILE
|
|
||||||
if (dpiScale!=1) {
|
|
||||||
if (!fullScreen) {
|
|
||||||
SDL_SetWindowSize(sdlWin,scrW*dpiScale,scrH*dpiScale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(sdlWin),&displaySize)==0) {
|
if (SDL_GetDisplayUsableBounds(SDL_GetWindowDisplayIndex(sdlWin),&displaySize)==0) {
|
||||||
if (scrW>((displaySize.w/dpiScale)-48) && scrH>((displaySize.h/dpiScale)-64)) {
|
bool mustChange=false;
|
||||||
|
if (scrW>((displaySize.w)-48) && scrH>((displaySize.h)-64)) {
|
||||||
// maximize
|
// maximize
|
||||||
SDL_MaximizeWindow(sdlWin);
|
SDL_MaximizeWindow(sdlWin);
|
||||||
|
logD("maximizing as it doesn't fit (%dx%d+%d+%d).",displaySize.w,displaySize.h,displaySize.x,displaySize.y);
|
||||||
}
|
}
|
||||||
if (scrW>displaySize.w/dpiScale) scrW=(displaySize.w/dpiScale)-32;
|
if (scrW>displaySize.w) {
|
||||||
if (scrH>displaySize.h/dpiScale) scrH=(displaySize.h/dpiScale)-32;
|
scrW=(displaySize.w)-32;
|
||||||
|
mustChange=true;
|
||||||
|
}
|
||||||
|
if (scrH>displaySize.h) {
|
||||||
|
scrH=(displaySize.h)-32;
|
||||||
|
mustChange=true;
|
||||||
|
}
|
||||||
|
if (mustChange) {
|
||||||
portrait=(scrW<scrH);
|
portrait=(scrW<scrH);
|
||||||
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
||||||
if (!fullScreen) {
|
if (!fullScreen) {
|
||||||
SDL_SetWindowSize(sdlWin,scrW*dpiScale,scrH*dpiScale);
|
logD("setting window size to %dx%d as it goes off bounds (%dx%d+%d+%d).",scrW,scrH,displaySize.w,displaySize.h,displaySize.x,displaySize.y);
|
||||||
|
SDL_SetWindowSize(sdlWin,scrW,scrH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IS_MOBILE
|
#ifdef IS_MOBILE
|
||||||
SDL_GetWindowSize(sdlWin,&scrW,&scrH);
|
SDL_GetWindowSize(sdlWin,&scrW,&scrH);
|
||||||
scrW/=dpiScale;
|
|
||||||
scrH/=dpiScale;
|
|
||||||
portrait=(scrW<scrH);
|
portrait=(scrW<scrH);
|
||||||
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
logV("portrait: %d (%dx%d)",portrait,scrW,scrH);
|
||||||
#endif
|
#endif
|
||||||
|
@ -5132,9 +5146,19 @@ bool FurnaceGUI::init() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
// try acquiring the canvas size
|
||||||
dpiScale=getMacDPIScale();
|
if (SDL_GetRendererOutputSize(sdlRend,&canvasW,&canvasH)!=0) {
|
||||||
#endif
|
logW("could not get renderer output size! %s",SDL_GetError());
|
||||||
|
} else {
|
||||||
|
logV("canvas size: %dx%d",canvasW,canvasH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// special consideration for Wayland
|
||||||
|
if (settings.dpiScale<0.5f) {
|
||||||
|
if (strcmp(videoBackend,"wayland")==0) {
|
||||||
|
dpiScale=(double)canvasW/(double)scrW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
|
@ -5198,6 +5222,8 @@ bool FurnaceGUI::finish() {
|
||||||
SDL_DestroyRenderer(sdlRend);
|
SDL_DestroyRenderer(sdlRend);
|
||||||
SDL_DestroyWindow(sdlWin);
|
SDL_DestroyWindow(sdlWin);
|
||||||
|
|
||||||
|
e->setConf("configVersion",(int)DIV_ENGINE_VERSION);
|
||||||
|
|
||||||
e->setConf("lastDir",workingDir);
|
e->setConf("lastDir",workingDir);
|
||||||
e->setConf("lastDirSong",workingDirSong);
|
e->setConf("lastDirSong",workingDirSong);
|
||||||
e->setConf("lastDirIns",workingDirIns);
|
e->setConf("lastDirIns",workingDirIns);
|
||||||
|
@ -5369,6 +5395,8 @@ FurnaceGUI::FurnaceGUI():
|
||||||
scrH(800),
|
scrH(800),
|
||||||
scrConfW(1280),
|
scrConfW(1280),
|
||||||
scrConfH(800),
|
scrConfH(800),
|
||||||
|
canvasW(1280),
|
||||||
|
canvasH(800),
|
||||||
scrX(SDL_WINDOWPOS_CENTERED),
|
scrX(SDL_WINDOWPOS_CENTERED),
|
||||||
scrY(SDL_WINDOWPOS_CENTERED),
|
scrY(SDL_WINDOWPOS_CENTERED),
|
||||||
scrConfX(SDL_WINDOWPOS_CENTERED),
|
scrConfX(SDL_WINDOWPOS_CENTERED),
|
||||||
|
|
|
@ -1062,7 +1062,7 @@ class FurnaceGUI {
|
||||||
|
|
||||||
FurnaceGUIFileDialog* fileDialog;
|
FurnaceGUIFileDialog* fileDialog;
|
||||||
|
|
||||||
int scrW, scrH, scrConfW, scrConfH;
|
int scrW, scrH, scrConfW, scrConfH, canvasW, canvasH;
|
||||||
int scrX, scrY, scrConfX, scrConfY;
|
int scrX, scrY, scrConfX, scrConfY;
|
||||||
bool scrMax, sysManagedScale;
|
bool scrMax, sysManagedScale;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,207 @@
|
||||||
|
/**
|
||||||
|
* Furnace Tracker - multi-system chiptune tracker
|
||||||
|
* Copyright (C) 2021-2022 tildearrow and contributors
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "scaling.h"
|
||||||
|
#include "../ta-log.h"
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
typedef HRESULT (*GDFM)(HMONITOR,int,UINT*,UINT*);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
extern "C" {
|
||||||
|
#include "macstuff.h"
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__unix__) || defined(ANDROID)
|
||||||
|
#include <dlfcn.h>
|
||||||
|
typedef void* (*XOD)(const char*);
|
||||||
|
typedef int (*XCD)(void*);
|
||||||
|
typedef int (*XDS)(void*);
|
||||||
|
typedef int (*XDW)(void*,int);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
double getScaleFactor(const char* driverHint) {
|
||||||
|
double ret=1.0;
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
#ifdef _WIN32
|
||||||
|
POINT nullPoint;
|
||||||
|
nullPoint.x=-1;
|
||||||
|
nullPoint.y=-1;
|
||||||
|
HMONITOR disp=MonitorFromPoint(nullPoint,MONITOR_DEFAULTTOPRIMARY);
|
||||||
|
|
||||||
|
if (disp==NULL) {
|
||||||
|
logW("could not find a monitor - no scaling detection available!");
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HMODULE shcore=LoadLibraryW(L"shcore.dll");
|
||||||
|
if (shcore==NULL) {
|
||||||
|
logW("could not find shcore.dll (%.8x) - no scaling detection available!",GetLastError());
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
GDFM ta_GetDpiForMonitor=(GDFM)GetProcAddress(shcore,"GetDpiForMonitor");
|
||||||
|
if (ta_GetDpiForMonitor==NULL) {
|
||||||
|
logW("GetDpiForMonitor not found (%.8x) - no scaling detection available!",GetLastError());
|
||||||
|
|
||||||
|
if (!FreeLibrary(shcore)) {
|
||||||
|
logE("could not free shcore.dll (%.8x)!",GetLastError());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int dpiX=96;
|
||||||
|
unsigned int dpiY=96;
|
||||||
|
HRESULT result=ta_GetDpiForMonitor(disp,0,&dpiX,&dpiY);
|
||||||
|
if (result!=S_OK) {
|
||||||
|
logW("GetDpiForMonitor failure (%.8x) - no scaling detection available!",result);
|
||||||
|
|
||||||
|
if (!FreeLibrary(shcore)) {
|
||||||
|
logE("could not free shcore.dll (%.8x)!",GetLastError());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret=(double)(dpiX+dpiY)/192.0;
|
||||||
|
|
||||||
|
if (!FreeLibrary(shcore)) {
|
||||||
|
logE("could not free shcore.dll (%.8x)!",GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// macOS - backingScaleFactor
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (driverHint==NULL) {
|
||||||
|
return getMacDPIScale();
|
||||||
|
} else if (strcmp(driverHint,"cocoa")==0 || strcmp(driverHint,"uikit")==0) {
|
||||||
|
return getMacDPIScale();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__unix__) || defined(ANDROID)
|
||||||
|
if (driverHint==NULL) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// X11
|
||||||
|
if (strcmp(driverHint,"x11")==0) {
|
||||||
|
void* libX11=dlopen("libX11.so",RTLD_LAZY|RTLD_LOCAL);
|
||||||
|
if (libX11==NULL) {
|
||||||
|
logW("could not load libX11.so (%s) - no scaling detection available!",dlerror());
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XOD ta_XOpenDisplay=(XOD)dlsym(libX11,"XOpenDisplay");
|
||||||
|
if (ta_XOpenDisplay==NULL) {
|
||||||
|
logW("XOpenDisplay not found (%s) - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XCD ta_XCloseDisplay=(XCD)dlsym(libX11,"XCloseDisplay");
|
||||||
|
if (ta_XCloseDisplay==NULL) {
|
||||||
|
logW("XCloseDisplay not found (%s) - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XDS ta_XDefaultScreen=(XDS)dlsym(libX11,"XDefaultScreen");
|
||||||
|
if (ta_XDefaultScreen==NULL) {
|
||||||
|
logW("XDefaultScreen not found (%s) - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XDW ta_XDisplayWidth=(XDW)dlsym(libX11,"XDisplayWidth");
|
||||||
|
if (ta_XDisplayWidth==NULL) {
|
||||||
|
logW("XDisplayWidth not found (%s) - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
XDW ta_XDisplayWidthMM=(XDW)dlsym(libX11,"XDisplayWidthMM");
|
||||||
|
if (ta_XDisplayWidthMM==NULL) {
|
||||||
|
logW("XDisplayWidthMM not found (%s) - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dl mess
|
||||||
|
void* disp=NULL;
|
||||||
|
int screen=0;
|
||||||
|
int dpi=96;
|
||||||
|
|
||||||
|
disp=ta_XOpenDisplay(NULL);
|
||||||
|
if (disp==NULL) {
|
||||||
|
logW("couldn't open X display - no scaling detection available!",dlerror());
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
screen=ta_XDefaultScreen(disp);
|
||||||
|
|
||||||
|
dpi=(int)(0.5+(25.4*(double)ta_XDisplayWidth(disp,screen)/(double)ta_XDisplayWidthMM(disp,screen)));
|
||||||
|
|
||||||
|
ta_XCloseDisplay(disp);
|
||||||
|
|
||||||
|
ret=round(dpi/96.0);
|
||||||
|
|
||||||
|
if (dlclose(libX11)!=0) {
|
||||||
|
logE("could not free libX11.so (%s)!",dlerror());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wayland
|
||||||
|
if (strcmp(driverHint,"wayland")==0) {
|
||||||
|
// give up (we handle scaling factor detection after window creation)
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// SDL fallback
|
||||||
|
float dpiScaleF=96.0f;
|
||||||
|
if (SDL_GetDisplayDPI(0,&dpiScaleF,NULL,NULL)==0) {
|
||||||
|
ret=round(dpiScaleF/96.0f);
|
||||||
|
if (ret<1) ret=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// couldn't detect scaling factor :<
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/**
|
||||||
|
* Furnace Tracker - multi-system chiptune tracker
|
||||||
|
* Copyright (C) 2021-2022 tildearrow and contributors
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
double getScaleFactor(const char* driverHint);
|
Loading…
Reference in New Issue