summaryrefslogtreecommitdiff
path: root/alf/alfcompat.cpp
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2019-01-08 23:13:32 +0100
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2019-01-08 23:13:32 +0100
commiteb706aae8bf5659a8aae37db31f88c3b605b8b1f (patch)
treedf059ce548f6710aa30c32cef8a8ee9f3b4cc783 /alf/alfcompat.cpp
parent6fb581e28e1ede9be7459533d9ca08679324652b (diff)
reingineer compat layer
not totally sure whether that's actually better
Diffstat (limited to 'alf/alfcompat.cpp')
-rw-r--r--alf/alfcompat.cpp272
1 files changed, 205 insertions, 67 deletions
diff --git a/alf/alfcompat.cpp b/alf/alfcompat.cpp
index 9a36d4d..aee27fb 100644
--- a/alf/alfcompat.cpp
+++ b/alf/alfcompat.cpp
@@ -2,6 +2,58 @@
#include <shlwapi.h>
+#if defined(_MSC_VER) && defined(_M_IX86)
+
+# pragma warning(push)
+# pragma warning(disable:4035)
+
+ // HACK: inline assembly for MSVC 6
+ // TODO: add version detection to use intrinsic on newer MSVC versions
+
+ static inline LONG
+ ALF_Compat_InterlockedIncrement(LONG volatile *addend)
+ {
+ __asm {
+ mov eax,1
+ mov edx,addend
+ lock xadd [edx],eax
+ }
+ }
+# ifdef InterlockedIncrement
+# undef InterlockedIncrement
+# endif
+# define InterlockedIncrement(d) ALF_Compat_InterlockedIncrement(d)
+
+ static inline LONG
+ ALF_Compat_InterlockedCompareExchange(volatile LONG *destination, LONG exchange, LONG comparand)
+ {
+ __asm {
+ mov eax,comparand
+ mov ecx,exchange
+ mov edx,destination
+ lock cmpxchg [edx],ecx
+ }
+ }
+
+# ifdef InterlockedCompareExchange
+# undef InterlockedCompareExchange
+# endif
+# define InterlockedCompareExchange(d,e,c) ALF_Compat_InterlockedCompareExchange(d,e,c)
+
+ static inline PVOID
+ ALF_Compat_InterlockedCompareExchangePointer(PVOID volatile *destination, PVOID exchange, PVOID comparand)
+ {
+ return (void*)InterlockedCompareExchange((LONG volatile *)destination, (LONG)exchange, (LONG)comparand);
+ }
+
+# ifdef InterlockedCompareExchangePointer
+# undef InterlockedCompareExchangePointer
+# endif
+# define InterlockedCompareExchangePointer(d,e,c) ALF_Compat_InterlockedCompareExchangePointer(d,e,c)
+
+# pragma warning(pop)
+#endif
+
static
DWORD ALF_DllGetVersion(const char *dll)
{
@@ -29,7 +81,7 @@ DWORD ALF_DllGetVersion(const char *dll)
}
static int WINAPI
-fallbackGetSystemMetricsForDpi(int nIndex, UINT dpi)
+ALF_Compat_fallbackGetSystemMetricsForDpi(int nIndex, UINT dpi)
{
(void)dpi;
if (LOBYTE(LOWORD(GetVersion())) < 4) {
@@ -44,13 +96,13 @@ fallbackGetSystemMetricsForDpi(int nIndex, UINT dpi)
}
static BOOL WINAPI
-fallbackIsAppThemed(void)
+ALF_Compat_fallbackIsAppThemed(void)
{
return FALSE;
}
static UINT WINAPI
-fallbackGetDpiForWindow(HWND win)
+ALF_Compat_fallbackGetDpiForWindow(HWND win)
{
(void)win;
@@ -70,7 +122,7 @@ fallbackGetDpiForWindow(HWND win)
}
static BOOL WINAPI
-fallbackSystemParametersInfoForDpi(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni, UINT dpi)
+ALF_Compat_fallbackSystemParametersInfoForDpi(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni, UINT dpi)
{
(void)dpi;
@@ -78,7 +130,7 @@ fallbackSystemParametersInfoForDpi(UINT uiAction, UINT uiParam, PVOID pvParam, U
}
static BOOL WINAPI
-fallbackAdjustWindowRectExForDpi(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi)
+ALF_Compat_fallbackAdjustWindowRectExForDpi(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi)
{
(void)dpi;
@@ -97,7 +149,7 @@ typedef struct {
} ALFWindowSubclassData;
static LRESULT CALLBACK
-fallbackSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ALF_Compat_fallbackSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
ALFWindowSubclassData *data = (ALFWindowSubclassData *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
@@ -121,7 +173,7 @@ fallbackSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
static BOOL WINAPI
-fallbackSetWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
+ALF_Compat_fallbackSetWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
ALFWindowSubclassData *data = (ALFWindowSubclassData *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ALFWindowSubclassData));
@@ -131,13 +183,13 @@ fallbackSetWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_P
data->orig = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)data);
- SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)fallbackSubclassProc);
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)ALF_Compat_fallbackSubclassProc);
return TRUE;
}
static LRESULT WINAPI
-fallbackDefSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ALF_Compat_fallbackDefSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
ALFWindowSubclassData *data = (ALFWindowSubclassData *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
@@ -145,7 +197,7 @@ fallbackDefSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
static BOOL WINAPI
-fallbackRemoveWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass)
+ALF_Compat_fallbackRemoveWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass)
{
(void)pfnSubclass;
(void)uIdSubclass;
@@ -166,72 +218,158 @@ fallbackRemoveWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UIN
return TRUE;
}
-ALFCompatFunctions *
-ALF_CreateCompatFuncTable(void)
-{
- ALFCompatFunctions *compatfn = (ALFCompatFunctions*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY|HEAP_GENERATE_EXCEPTIONS, sizeof(ALFCompatFunctions));
-
-#define COMPAT(dll, entrypoint, ordinal, fallback) \
- do { \
- FARPROC p = GetProcAddress(GetModuleHandleA(#dll), #entrypoint); \
- if (!p && ordinal) \
- p = GetProcAddress(GetModuleHandleA(#dll), (char*)ordinal); \
- CopyMemory(&compatfn->entrypoint, &p, sizeof(void*)); \
- \
- if (!compatfn->entrypoint) \
- compatfn->entrypoint = fallback; \
- } while (0)
-
- COMPAT(comctl32.dll, SetWindowSubclass, 410, fallbackSetWindowSubclass);
- COMPAT(comctl32.dll, DefSubclassProc, 413, fallbackDefSubclassProc);
- COMPAT(comctl32.dll, RemoveWindowSubclass, 412, fallbackRemoveWindowSubclass);
- COMPAT(user32.dll, GetSystemMetricsForDpi, 0, fallbackGetSystemMetricsForDpi);
- COMPAT(user32.dll, GetDpiForWindow, 0, fallbackGetDpiForWindow);
-
- // FIXME: SystemParametersInfoForDpi is Unicode-Only.
- // Writing a wrapper function would have been The Right Way, but such a function
- // is yet to be written. So the current practical recommendation is to make
- // ANSI builds System DPI aware only.
-#ifdef UNICODE
- COMPAT(user32.dll, SystemParametersInfoForDpi, 0, fallbackSystemParametersInfoForDpi);
-#else
- compatfn->SystemParametersInfoForDpi = fallbackSystemParametersInfoForDpi;
-#endif
+long
+ALF_GetAveCharWidth(HDC hdc)
+{
+ // see: HOWTO: Calculate Dialog Units When Not Using the System Font
+
+ SIZE s;
+ GetTextExtentPoint32A(hdc, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &s);
+
+ return (s.cx / 26 + 1) / 2;
+}
+
+void
+ALF_UniqueCounterValue(LONG_PTR *pCounterId, LONG_PTR *pCounterValue)
+{
+ static LONG counter = 0;
+
+ LONG r = InterlockedIncrement(&counter);
+ *pCounterId = (LONG_PTR)&counter;
+ *pCounterValue = r;
+}
+
+static BOOL WINAPI
+ALF_Compat_loadIsAppThemed(void)
+{
+ HMODULE hUxTheme = GetModuleHandleA("uxtheme.dll");
+ FARPROC p = GetProcAddress(hUxTheme, "IsAppThemed");
+
+ if (!p || ALF_DllGetVersion("comctl32.dll") < 0x60000)
+ p = (FARPROC)ALF_Compat_fallbackIsAppThemed;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_IsAppThemed, (void*)p, (void*)ALF_Compat_loadIsAppThemed);
+
+ return ALF_Compat_IsAppThemed();
+}
+
+static UINT WINAPI
+ALF_Compat_loadGetDpiForWindow(HWND window)
+{
+ FARPROC p = GetProcAddress(GetModuleHandleA("user32.dll"), "GetDpiForWindow");
+
+ if (!p)
+ p = (FARPROC)(void*)ALF_Compat_fallbackGetDpiForWindow;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_GetDpiForWindow, (void*)p, (void*)ALF_Compat_loadGetDpiForWindow);
+
+ return ALF_Compat_GetDpiForWindow(window);
+}
+
+static BOOL WINAPI
+ALF_Compat_loadAdjustWindowRectExForDpi(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi)
+{
+ FARPROC p = GetProcAddress(GetModuleHandleA("user32.dll"), "AdjustWindowRectExForDpi");
+
+ if (!p)
+ p = (FARPROC)(void*)ALF_Compat_fallbackAdjustWindowRectExForDpi;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_AdjustWindowRectExForDpi, (void*)p, (void*)ALF_Compat_loadAdjustWindowRectExForDpi);
+
+ return ALF_Compat_AdjustWindowRectExForDpi(lpRect, dwStyle, bMenu, dwExStyle, dpi);
+}
- COMPAT(user32.dll, AdjustWindowRectExForDpi, 0, fallbackAdjustWindowRectExForDpi);
+static int WINAPI
+ALF_Compat_loadGetSystemMetricsForDpi(int nIndex, UINT dpi)
+{
+ void *p = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetSystemMetricsForDpi");
+
+ if (!p)
+ p = (void*)ALF_Compat_fallbackGetSystemMetricsForDpi;
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_GetSystemMetricsForDpi, p, (void*)ALF_Compat_loadGetSystemMetricsForDpi);
+
+ return ALF_Compat_GetSystemMetricsForDpi(nIndex, dpi);
+}
+
+static BOOL WINAPI
+ALF_Compat_loadSetWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
+{
+ HMODULE comctl32 = GetModuleHandleA("comctl32.dll");
+
+ void *p = (void*)GetProcAddress(comctl32, "SetWindowSubclass");
+ if (!p) {
+ p = (void*)GetProcAddress(comctl32, (char*)410);
+ if (!p) {
+ p = (void*)ALF_Compat_fallbackSetWindowSubclass;
+ }
+ }
+
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_SetWindowSubclass, p, (void*)ALF_Compat_loadSetWindowSubclass);
+
+ return ALF_Compat_SetWindowSubclass(hwnd, pfnSubclass, uIdSubclass, dwRefData);
+}
+
+static BOOL WINAPI
+ALF_Compat_loadRemoveWindowSubclass(HWND hwnd, ALF_COMPAT_SUBCLASSPROC pfnSubclass, UINT_PTR uIdSubclass)
+{
+ HMODULE comctl32 = GetModuleHandleA("comctl32.dll");
- // IsAppThemed would return TRUE even when we're linked against comctl32 v5
- if (ALF_DllGetVersion("comctl32.dll") >= 0x60000) {
- LoadLibraryA("uxtheme.dll");
- COMPAT(uxtheme.dll, IsAppThemed, 0, fallbackIsAppThemed);
- } else {
- compatfn->IsAppThemed = fallbackIsAppThemed;
+ void *p = (void*)GetProcAddress(comctl32, "RemoveWindowSubclass");
+ if (!p) {
+ p = (void*)GetProcAddress(comctl32, (char*)412);
+ if (!p) {
+ p = (void*)ALF_Compat_fallbackRemoveWindowSubclass;
+ }
}
-#undef COMPAT
-
- UINT oldErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX); // stop win32s from barking about rpcrt4
- HMODULE rpc = LoadLibraryA("rpcrt4.dll");
- if (rpc) {
- // NT always has rpcrt4.dll
- compatfn->UuidCreate = (ULONG(WINAPI*)(UUID*))(void*)GetProcAddress(rpc, "UuidCreate");
- } else {
- // Win32s always has OLE32
- HMODULE ole32 = LoadLibraryA("ole32.dll");
- compatfn->UuidCreate = (ULONG(WINAPI*)(UUID*))(void*)GetProcAddress(ole32, "CoCreateGuid");
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_RemoveWindowSubclass, p, (void*)ALF_Compat_loadRemoveWindowSubclass);
+
+ return ALF_Compat_RemoveWindowSubclass(hwnd, pfnSubclass, uIdSubclass);
+}
+
+static LRESULT WINAPI
+ALF_Compat_loadDefSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ HMODULE comctl32 = GetModuleHandleA("comctl32.dll");
+
+ void *p = (void*)GetProcAddress(comctl32, "DefSubclassProc");
+ if (!p) {
+ p = (void*)GetProcAddress(comctl32, (char*)413);
+ if (!p) {
+ p = (void*)ALF_Compat_fallbackDefSubclassProc;
+ }
}
- SetErrorMode(oldErrorMode);
- return compatfn;
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_DefSubclassProc, p, (void*)ALF_Compat_loadDefSubclassProc);
+
+ return ALF_Compat_DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
-long
-ALF_GetAveCharWidth(HDC hdc)
+static BOOL WINAPI
+ALF_Compat_loadSystemParametersInfoForDpi(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni, UINT dpi)
{
- // see: HOWTO: Calculate Dialog Units When Not Using the System Font
+ void *p = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "SystemParametersInfoForDpi");
+ if (!p)
+ p = (void*)ALF_Compat_fallbackSystemParametersInfoForDpi;
- SIZE s;
- GetTextExtentPoint32A(hdc, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &s);
+ InterlockedCompareExchangePointer((void**)&ALF_Compat_SystemParametersInfoForDpi, p, (void*)ALF_Compat_loadSystemParametersInfoForDpi);
- return (s.cx / 26 + 1) / 2;
+ return ALF_Compat_SystemParametersInfoForDpi(uiAction, uiParam, pvParam, fWinIni, dpi);
}
+
+
+BOOL (WINAPI *ALF_Compat_IsAppThemed)(void) = ALF_Compat_loadIsAppThemed;
+UINT (WINAPI *ALF_Compat_GetDpiForWindow)(HWND /*window*/) = ALF_Compat_loadGetDpiForWindow;
+BOOL (WINAPI *ALF_Compat_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT) = ALF_Compat_loadAdjustWindowRectExForDpi;
+int (WINAPI *ALF_Compat_GetSystemMetricsForDpi)(int, UINT) = ALF_Compat_loadGetSystemMetricsForDpi;
+BOOL (WINAPI *ALF_Compat_SetWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR, DWORD_PTR) = ALF_Compat_loadSetWindowSubclass;
+LRESULT (WINAPI *ALF_Compat_DefSubclassProc)(HWND, UINT, WPARAM, LPARAM) = ALF_Compat_loadDefSubclassProc;
+BOOL (WINAPI *ALF_Compat_RemoveWindowSubclass)(HWND, ALF_COMPAT_SUBCLASSPROC, UINT_PTR) = ALF_Compat_loadRemoveWindowSubclass;
+
+// FIXME! do Unicode properly for SystemParametersInfoForDpi
+#ifdef UNICODE
+BOOL (WINAPI *ALF_Compat_SystemParametersInfoForDpi)(UINT,UINT,PVOID,UINT,UINT) = ALF_Compat_loadSystemParametersInfoForDpi;
+#else
+BOOL (WINAPI *ALF_Compat_SystemParametersInfoForDpi)(UINT,UINT,PVOID,UINT,UINT) = ALF_Compat_fallbackSystemParametersInfoForDpi;
+#endif