Get latest tely changes, w/ new OS primitives from internal project

This commit is contained in:
2026-09-29 22:28:31 +10:00
parent e9c25bae9c
commit d85b66d1da
9 changed files with 4631 additions and 2045 deletions
+184
View File
@@ -1057,6 +1057,36 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs
return result;
}
DN_API void DN_OS_W32Init(DN_OSW32Core *w32)
{
InitializeCriticalSection(&w32->sync_primitive_free_list_mutex);
QueryPerformanceFrequency(&w32->qpc_frequency);
// NOTE: DPI
HMODULE user32 = LoadLibraryA("user32.dll");
if (user32) {
w32->get_dpi_for_window = (DN_OSW32GetDpiForWindowFunc* )GetProcAddress(user32, "GetDpiForWindow");
w32->get_dpi_for_monitor = (DN_OSW32GetDpiForMonitorFunc * )GetProcAddress(user32, "GetDpiForMonitor");
w32->get_system_metrics_for_dpi = (DN_OSW32GetSystemMetricsForDpiFunc *)GetProcAddress(user32, "GetSystemMetricsForDpi");
FreeLibrary(user32);
}
// NOTE: SetThreadDesc
HMODULE kernel32 = LoadLibraryA("kernel32.dll");
if (kernel32) {
w32->set_thread_description = DN_Cast(DN_OSW32SetThreadDescriptionFunc *) GetProcAddress(kernel32, "SetThreadDescription");
FreeLibrary(kernel32);
}
// NOTE: win32 bcrypt
wchar_t const BCRYPT_ALGORITHM[] = L"RNG";
long /*NTSTATUS*/ init_status = BCryptOpenAlgorithmProvider(&w32->bcrypt_rng_handle, BCRYPT_ALGORITHM, nullptr /*implementation*/, 0 /*flags*/);
if (w32->bcrypt_rng_handle && init_status == 0)
w32->bcrypt_init_success = true;
else
DN_LogErrorF("Failed to initialise Windows secure random number generator, error: %d", init_status);
}
DN_API DN_OSW32Core *DN_OS_W32GetCore()
{
DN_Core *dn = DN_Get();
@@ -1456,6 +1486,160 @@ DN_API void DN_OS_W32ThreadSetName(DN_Str8 name)
DN_TcScratchEnd(&scratch);
}
DN_API DN_OSW32Window* DN_OS_W32WindowFromHwndMaybeAlloc(DN_OSW32Core *w32, HWND hwnd, DN_Arena *arena)
{
DN_OSW32Window *result = nullptr;
for (DN_OSW32Window *check = w32->windows; !result && check; check = check->next) {
if (check->hwnd == hwnd)
result = check;
}
if (!result && arena) {
result = DN_ArenaNewZ(arena, DN_OSW32Window);
if (result) {
result->hwnd = hwnd;
if (w32->windows)
w32->windows->next = result;
result->next = w32->windows;
w32->windows = result;
}
}
return result;
}
DN_API LRESULT __stdcall DN_OS_W32WindowProcCustomTitlebar(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
{
DN_OSW32Core *w32 = DN_OS_W32GetCore();
DN_AssertF(w32, "Using this window proc requires that DN's OS layer has been initialised");
LRESULT result = 0;
bool handled = true;
switch (msg) {
// NOTE: Sent when the size and position of a window's client area must be calculated. By
// processing this message, an application can control the content of the window's client area
// when the size or position of the window changes.
case WM_NCCALCSIZE: {
DN_OSW32Window *w32_window = DN_OS_W32WindowFromHwndMaybeAlloc(w32, hwnd, nullptr);
if (w32_window && w32_window->custom_title_bar) {
// NOTE: Code adapted from raddebugger
// https://github.com/EpicGames/raddebugger/blob/7a5a649b89f6a06abdbaee61540468fca9db58f9/src/win32/window_manager/win32_window_manager.c#L668
//
// The goal here is to subtract away the title bar from the window and restore the pixel
// border that native Windows renders windows with. Note that on Windows 11 a non-maximised
// window has rounded corners which eats into the available client space that is normally
// otherwise eaten into from the native titlebar.
DWORD window_style = GetWindowLongW(hwnd, GWL_STYLE);
bool is_fullscreen = !(window_style & WS_OVERLAPPEDWINDOW);
if (is_fullscreen) {
handled = false;
} else {
DN_UInt dpi = w32->get_dpi_for_window ? w32->get_dpi_for_window(hwnd) : 96;
int frame_x = w32->get_system_metrics_for_dpi ? w32->get_system_metrics_for_dpi(SM_CXFRAME, dpi) : GetSystemMetrics(SM_CXFRAME);
int frame_y = w32->get_system_metrics_for_dpi ? w32->get_system_metrics_for_dpi(SM_CYFRAME, dpi) : GetSystemMetrics(SM_CYFRAME);
int padding = w32->get_system_metrics_for_dpi ? w32->get_system_metrics_for_dpi(SM_CXPADDEDBORDER, dpi) : GetSystemMetrics(SM_CXPADDEDBORDER);
RECT *rect = w_param == 0 ? DN_Cast(RECT *)l_param : (DN_Cast(NCCALCSIZE_PARAMS *)l_param)->rgrc;
rect->right -= frame_x + padding;
rect->left += frame_x + padding;
rect->bottom -= frame_y + padding;
bool is_maximised = IsZoomed(hwnd) != 0;
if (is_maximised) {
rect->top += frame_y + padding;
// If we do not do this hidden taskbar can not be unhidden on mouse hover
// Unfortunately it can create an ugly bottom border when maximized...
rect->bottom -= 1;
} else {
int edge_height = w32->get_system_metrics_for_dpi ? w32->get_system_metrics_for_dpi(SM_CYEDGE, dpi) : GetSystemMetrics(SM_CYEDGE);
rect->top += edge_height;
}
}
} else {
handled = false;
}
} break;
// NOTE: Sent to a window in order to determine what part of the window corresponds to a
// particular screen coordinate. This can happen, for example, when the cursor moves, when a
// mouse button is pressed or released, or in response to a call to a function such as
// WindowFromPoint. If the mouse is not captured, the message is sent to the window beneath
// the cursor. Otherwise, the message is sent to the window that has captured the mouse.
case WM_NCHITTEST: {
DN_OSW32Window *w32_window = DN_OS_W32WindowFromHwndMaybeAlloc(w32, hwnd, nullptr);
if (w32_window && w32_window->custom_title_bar) {
// NOTE: Code adapted from raddebugger
// https://github.com/EpicGames/raddebugger/blob/7a5a649b89f6a06abdbaee61540468fca9db58f9/src/win32/window_manager/win32_window_manager.c#L668
//
// Since we removed the titlebar from the window, the resize handlers/grabbers at the top of
// the window are no longer functional. We have to reimplement it ourselves.
DWORD window_style = GetWindowLongW(hwnd, GWL_STYLE);
bool is_fullscreen = !(window_style & WS_OVERLAPPEDWINDOW);
handled = false;
if (!is_fullscreen) {
// Let the default procedure handle resizing areas
if (w32->fallback_wnd_proc)
result = CallWindowProcW(w32->fallback_wnd_proc, hwnd, msg, w_param, l_param);
else
result = DefWindowProcW(hwnd, msg, w_param, l_param);
switch (result) {
case HTNOWHERE:
case HTRIGHT:
case HTLEFT:
case HTTOPLEFT:
case HTTOPRIGHT:
case HTBOTTOMRIGHT:
case HTBOTTOM:
case HTBOTTOMLEFT: {
handled = true;
} break;
}
if (!handled) {
POINT pos_monitor = {};
pos_monitor.x = GET_X_LPARAM(l_param);
pos_monitor.y = GET_Y_LPARAM(l_param);
handled = true;
POINT pos_client = pos_monitor;
ScreenToClient(hwnd, &pos_client);
DN_V2F32 title_bar_min = w32_window->custom_title_bar_rect_that_is_draggable.pos;
DN_V2F32 title_bar_max = title_bar_min + w32_window->custom_title_bar_rect_that_is_draggable.size;
DN_UInt dpi = w32->get_dpi_for_window ? w32->get_dpi_for_window(hwnd) : 96;
int frame_y = w32->get_system_metrics_for_dpi ? w32->get_system_metrics_for_dpi(SM_CYFRAME, dpi) : GetSystemMetrics(SM_CYFRAME);
int padding = w32->get_system_metrics_for_dpi ? w32->get_system_metrics_for_dpi(SM_CXPADDEDBORDER, dpi) : GetSystemMetrics(SM_CXPADDEDBORDER);
bool is_over_top_resize = pos_client.y >= 0 && pos_client.y < (frame_y + padding);
bool is_over_title_bar = pos_client.x >= title_bar_min.x && pos_client.x < title_bar_max.x &&
pos_client.y >= title_bar_min.y && pos_client.y < title_bar_max.y;
bool is_maximised = IsZoomed(hwnd) != 0;
if (!is_maximised && is_over_top_resize)
result = HTTOP;
else if (is_over_title_bar)
result = HTCAPTION;
else
result = HTCLIENT;
}
}
} else {
handled = false;
}
} break;
default: {
handled = false;
} break;
}
if (!handled) {
if (w32->fallback_wnd_proc) {
result = CallWindowProcW(w32->fallback_wnd_proc, hwnd, msg, w_param, l_param);
} else {
result = DefWindowProcW(hwnd, msg, w_param, l_param);
}
}
return result;
}
DN_API DN_Str16 DN_OS_W32ErrorCodeToMsg16Alloc(DN_U32 error_code)
{
DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;