Skip to content

Commit

Permalink
More changes to make plWinDPI modular
Browse files Browse the repository at this point in the history
  • Loading branch information
colincornaby committed May 6, 2023
1 parent e883331 commit 9e4f3fe
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 78 deletions.
6 changes: 1 addition & 5 deletions Sources/Plasma/Apps/plClient/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,8 @@ set(plClient_TEXT
)

if(WIN32)
list(APPEND plClient_HEADERS
win32/plWinDpi.h
)

list(APPEND plClient_SOURCES
win32/plClient_Win.cpp
win32/plWinDpi.cpp
win32/winmain.cpp
)

Expand Down Expand Up @@ -151,6 +146,7 @@ target_link_libraries(
plStatGather
plStatusLog
plUnifiedTime
$<$<BOOL:${WIN32}>:plWinDpi>
pfAnimation
pfAudio
pfCharacter
Expand Down
2 changes: 1 addition & 1 deletion Sources/Plasma/Apps/plClient/plClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plClient.h"

#ifdef HS_BUILD_FOR_WIN32
# include "win32/plWinDpi.h"
# include "plWinDpi/plWinDpi.h"
#endif

#include "pnDispatch/plDispatch.h"
Expand Down
2 changes: 1 addition & 1 deletion Sources/Plasma/Apps/plClient/win32/plClient_Win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include <shellapi.h>

#include "plClient.h"
#include "win32/plWinDpi.h"
#include "plWinDpi/plWinDpi.h"

#include "pnFactory/plFactory.h"
#include "pnNetCommon/plNetApp.h"
Expand Down
12 changes: 10 additions & 2 deletions Sources/Plasma/Apps/plClient/win32/winmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plClient.h"
#include "plClientLoader.h"
#include "res/resource.h"
#include "plWinDpi.h"

#include "pnEncryption/plChallengeHash.h"

Expand All @@ -68,12 +67,14 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plInputCore/plInputManager.h"
#include "plNetClient/plNetClientMgr.h"
#include "plNetGameLib/plNetGameLib.h"
#include "plMessage/plDisplayScaleChangedMsg.h"
#include "plPhysX/plPXSimulation.h"
#include "plPipeline/hsG3DDeviceSelector.h"
#include "plResMgr/plLocalization.h"
#include "plResMgr/plResManager.h"
#include "plResMgr/plVersion.h"
#include "plStatusLog/plStatusLog.h"
#include "plWinDpi/plWinDpi.h"

#include "pfConsoleCore/pfConsoleEngine.h"
#include "pfCrashHandler/plCrashCli.h"
Expand Down Expand Up @@ -172,14 +173,21 @@ static void AuthFailedStrings (ENetError authError,

void DebugMsgF(const char* format, ...);

void HandleDpiChange(HWND hWnd, UINT dpi, float scale, const RECT& rect)
{
// Inform the engine about the new DPI.
auto* msg = new plDisplayScaleChangedMsg(scale, plDisplayScaleChangedMsg::ConvertRect(rect));
msg->Send();
}

// Handles all the windows messages we might receive
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static bool gDragging = false;
static uint8_t mouse_down = 0;

// DPI Helper can eat messages.
auto result = plWinDpi::Instance().WndProc(hWnd, message, wParam, lParam);
auto result = plWinDpi::Instance().WndProc(hWnd, message, wParam, lParam, HandleDpiChange);
if (result.has_value())
return result.value();

Expand Down
1 change: 1 addition & 0 deletions Sources/Plasma/Apps/plUruLauncher/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ target_link_libraries(
pnNetBase
plNetGameLib
plStatusLog
plWinDpi
pfConsoleCore
pfPatcher
CURL::libcurl
Expand Down
47 changes: 8 additions & 39 deletions Sources/Plasma/Apps/plUruLauncher/winmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ Mead, WA 99021
#include "pfPatcher/plManifests.h"
#include "pfPatcher/pfPatcher.h"

#include "plWinDpi/plWinDpi.h"

#include "plClientLauncher.h"

#include "hsWindows.h"
Expand Down Expand Up @@ -125,6 +127,11 @@ static inline void IShowMarquee(bool marquee=true)

INT_PTR CALLBACK PatcherDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// DPI Helper can eat messages.
auto result = plWinDpi::Instance().WndProc(hwndDlg, uMsg, wParam, lParam, nullptr);
if (result.has_value())
return result.value();

// NT6 Taskbar Majick
if (uMsg == s_taskbarCreated) {
hsRequireCOM();
Expand Down Expand Up @@ -189,44 +196,6 @@ static void PumpMessages()
} while (s_launcher->PumpNetCore());
}

void SetDPIAwareness() const
{
plOptionalWinCall<BOOL(DPI_AWARENESS_CONTEXT)> fSetProcessDpiAwarenessContext(L"user32", "SetProcessDpiAwarenessContext");
plOptionalWinCall<HRESULT(PROCESS_DPI_AWARENESS)> fSetProcessDpiAwareness(L"user32", "SetProcessDpiAwarenessContext");

// There are three different levels of DPI awareness that we can deal with,
// each was added in newer versions of Windows as monitors became more and
// more sexy.
// In Vista, the entire system had an adjustable display scale.
// In Windows 8, each monitor was allowed to have a separate scale.
// In Windows 10, the per-monitor scaling was slowly improved to automatically
// scale dialog boxes and things like that.
// So we need to try to handle all of that. We will assume the baseline is Vista.
// Any API added later than that will need to be called on a provisional basis.
do {
// Per Monitor V2 for Windows 10 v1703.
auto perMonitorV2Result = fSetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
if (perMonitorV2Result.has_value()) {
if (perMonitorV2Result.value() == TRUE) {
break;
}
}

// Per Monitor v1 for Windows 8.1.
auto perMonitorV1Result = fSetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
if (perMonitorV1Result.has_value()) {
if (SUCCEEDED(perMonitorV1Result.value())) {
break;
}
}

// System DPI Awareness.
if (SetProcessDPIAware() != FALSE) {
break;
}
} while (false);
}

// ===================================================

static void IOnDownloadBegin(const plFileName& file)
Expand Down Expand Up @@ -419,7 +388,7 @@ static pfPatcher* IPatcherFactory()

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLink, int nCmdShow)
{
SetProcessDPIAware();
plWinDpi::Instance();

plClientLauncher launcher;
s_launcher = &launcher;
Expand Down
1 change: 1 addition & 0 deletions Sources/Plasma/PubUtilLib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ add_subdirectory(plSurface)
add_subdirectory(plTransform)
add_subdirectory(plUnifiedTime)
add_subdirectory(plVault)
add_subdirectory(plWinDpi)
12 changes: 12 additions & 0 deletions Sources/Plasma/PubUtilLib/plMessage/plDisplayScaleChangedMsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ class plDisplayScaleChangedMsg : public plMessage
public:
float GetScale() const { return fScale; }
std::optional<ClientWindow> GetSuggestedLocation() const { return fNewLocation; }

#if WIN32
static RECT ConvertRect(const plDisplayScaleChangedMsg::ClientWindow& rect)
{
return *((const LPRECT)&rect);
}

static plDisplayScaleChangedMsg::ClientWindow ConvertRect(const RECT& rect)
{
return *((const plDisplayScaleChangedMsg::ClientWindow*)&rect);
}
#endif
};

#endif
22 changes: 22 additions & 0 deletions Sources/Plasma/PubUtilLib/plWinDpi/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
if(WIN32)

list(APPEND plWinDpi_HEADERS
plWinDpi.h
)

list(APPEND plWinDpi_SOURCES
plWinDpi.cpp
)

plasma_library(plWinDpi
SOURCES ${plWinDpi_SOURCES} ${plWinDpi_HEADERS}
)

target_link_libraries(
plWinDpi
PUBLIC
CoreLib
plStatusLog
)

endif()
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include <memory>
#include <type_traits>

#include "hsResMgr.h"

#include "pnKeyedObject/plFixedKey.h"
#include "pnMessage/plClientMsg.h"

#ifndef WM_GETDPISCALEDSIZE
# define WM_GETDPISCALEDSIZE 0x02E4
#endif
Expand Down Expand Up @@ -252,17 +247,7 @@ void plWinDpi::IEnableNCScaling(HWND hWnd) const
}
}

void plWinDpi::IHandleDpiChange(HWND hWnd, UINT dpi, const RECT& rect) const
{
float scale = float(dpi) / 96.0f;
LogWhite("Window DPI changed to {} (scale factor: {.02f})", dpi, scale);

// Inform the engine about the new DPI.
auto* msg = new plDisplayScaleChangedMsg(scale, ConvertRect(rect));
msg->Send();
}

std::optional<LRESULT> plWinDpi::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) const
std::optional<LRESULT> plWinDpi::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, const std::function <void (HWND, UINT, FLOAT, RECT&)>& dpiChangedCallback) const
{
switch (msg) {
case WM_NCCREATE:
Expand All @@ -272,7 +257,13 @@ std::optional<LRESULT> plWinDpi::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPA
// For Windows 8.1 and higher. Allows us to handle DPI changes while the game is running,
// eg by moving the game window to another monitor with a different scale factor or
// the user changed the scale factor while the game is running.
IHandleDpiChange(hWnd, LOWORD(wParam), *((LPRECT)lParam));
if (dpiChangedCallback) {
UINT dpi = LOWORD(wParam);
float scale = float(dpi) / 96.0f;
LogWhite("Window DPI changed to {} (scale factor: {.02f})", dpi, scale);

dpiChangedCallback(hWnd, dpi, scale, *((LPRECT)lParam));
}
return 0;
case WM_GETDPISCALEDSIZE:
// For Windows 10 v1703 and higher. This window message allows us to tell the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "hsWindows.h"
#include <ShellScalingApi.h>

#include "plMessage/plDisplayScaleChangedMsg.h"
#include "plStatusLog/plStatusLog.h"

class plWinDpi
Expand Down Expand Up @@ -114,23 +113,12 @@ class plWinDpi
public:
float GetScale(HWND hWnd = nullptr) const { return float(GetDpi(hWnd)) / 96.0f; }

static RECT ConvertRect(const plDisplayScaleChangedMsg::ClientWindow& rect)
{
return *((const LPRECT)&rect);
}

static plDisplayScaleChangedMsg::ClientWindow ConvertRect(const RECT& rect)
{
return *((const plDisplayScaleChangedMsg::ClientWindow*)&rect);
}

private:
BOOL ICalcWinSize(HWND hWnd, UINT dpi, SIZE& hWndSize) const;
void IEnableNCScaling(HWND hWnd) const;
void IHandleDpiChange(HWND hWnd, UINT dpi, const RECT& rect) const;

public:
std::optional<LRESULT> WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) const;
std::optional<LRESULT> WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, const std::function <void(HWND, UINT, FLOAT, RECT&)>& dpiChangedCallback) const;
};

#endif

0 comments on commit 9e4f3fe

Please sign in to comment.