diff --git a/Source/OS/dn_os_posix.cpp b/Source/OS/dn_os_posix.cpp index 38af509..36c33fe 100644 --- a/Source/OS/dn_os_posix.cpp +++ b/Source/OS/dn_os_posix.cpp @@ -1274,6 +1274,53 @@ DN_API void DN_OS_ConditionVariableBroadcast(DN_OSConditionVariable *cv) } } +DN_API DN_OSWindowMinimise DN_OS_WindowIsMinimised(DN_OSWindow *window) +{ + (void)window; + DN_AssertInvalidCodePath; + return DN_OSWindowMinimise_No; +} + +DN_API DN_OSWindowMaximise DN_OS_WindowIsMaximised(DN_OSWindow *window) +{ + (void)window; + DN_AssertInvalidCodePath; + return DN_OSWindowMaximise_No; +} + +DN_API void DN_OS_WindowSetTitle(DN_OSWindow *window, DN_Str8 title) +{ + (void)window; + (void)title; + DN_AssertInvalidCodePath; +} + +DN_API void DN_OS_WindowShow(DN_OSWindow *window, DN_OSWindowShow show) +{ + (void)window; + (void)show; + DN_AssertInvalidCodePath; +} + +DN_API void DN_OS_WindowBringToFront(DN_OSWindow *window) +{ + (void)window; + DN_AssertInvalidCodePath; +} + +DN_API void DN_OS_WindowFocus(DN_OSWindow *window) +{ + (void)window; + DN_AssertInvalidCodePath; +} + +DN_API bool DN_OS_WindowIsFocused(DN_OSWindow *window) +{ + (void)window; + DN_AssertInvalidCodePath; + return false; +} + // NOTE: DN_OSThread static void *DN_OS_ThreadFunc_(void *user_context) { diff --git a/Source/OS/dn_os_w32.cpp b/Source/OS/dn_os_w32.cpp index 17047f8..2744b08 100644 --- a/Source/OS/dn_os_w32.cpp +++ b/Source/OS/dn_os_w32.cpp @@ -2,6 +2,7 @@ #define DN_WITH_OS 1 #include "../dn.h" #include "dn_os_w32.h" + #include #endif // NOTE: DN_Mem @@ -1287,6 +1288,70 @@ DN_API void DN_OS_ConditionVariableBroadcast(DN_OSConditionVariable *cv) } } +DN_API DN_OSWindowMinimise DN_OS_WindowIsMinimised(DN_OSWindow *window) +{ + HWND hwnd = window ? DN_Cast(HWND) window->handle : nullptr; + DN_OSWindowMinimise result = DN_OSWindowMinimise_No; + if (hwnd && IsIconic(hwnd) != 0) + result = DN_OSWindowMinimise_Yes; + return result; +} + +DN_API DN_OSWindowMaximise DN_OS_WindowIsMaximised(DN_OSWindow *window) +{ + HWND hwnd = window ? DN_Cast(HWND) window->handle : nullptr; + DN_OSWindowMaximise result = DN_OSWindowMaximise_No; + if (hwnd && IsZoomed(hwnd) != 0) + result = DN_OSWindowMaximise_Yes; + return result; +} + +DN_API void DN_OS_WindowSetTitle(DN_OSWindow *window, DN_Str8 title) +{ + HWND hwnd = window ? DN_Cast(HWND) window->handle : nullptr; + if (hwnd) { + DN_TcScratch scratch = DN_TcScratchBeginArena(nullptr, 0); + DN_Str16 title16 = DN_OS_W32Str8ToStr16(&scratch.arena, title); + SetWindowTextW(hwnd, (WCHAR *)title16.data); + DN_TcScratchEnd(&scratch); + } +} + +DN_API void DN_OS_WindowShow(DN_OSWindow *window, DN_OSWindowShow show) +{ + switch (show) { + case DN_OSWindowShow_Nil: break; + case DN_OSWindowShow_Restore: ShowWindow(DN_Cast(HWND)window->handle, SW_RESTORE); break; + case DN_OSWindowShow_Minimise: ShowWindow(DN_Cast(HWND)window->handle, SW_MINIMIZE); break; + case DN_OSWindowShow_Maximise: ShowWindow(DN_Cast(HWND)window->handle, SW_MAXIMIZE); break; + } +} + +DN_API void DN_OS_WindowBringToFront(DN_OSWindow *window) +{ + HWND hwnd = window ? DN_Cast(HWND)window->handle : nullptr; + if (hwnd) + BringWindowToTop(hwnd); +} + +DN_API void DN_OS_WindowFocus(DN_OSWindow *window) +{ + HWND hwnd = window ? DN_Cast(HWND)window->handle : nullptr; + if (hwnd) { + SetForegroundWindow(hwnd); + SetFocus(hwnd); + } +} + +DN_API bool DN_OS_WindowIsFocused(DN_OSWindow *window) +{ + bool result = false; + HWND hwnd = window ? DN_Cast(HWND) window->handle : nullptr; + if (hwnd) + result = hwnd == GetForegroundWindow(); + return result; +} + static DWORD __stdcall DN_OS_ThreadFunc_(void *user_context) { DN_OS_ThreadExecute_(user_context); diff --git a/Source/OS/dn_os_windows.h b/Source/OS/dn_os_windows.h index 40423b9..15a258e 100644 --- a/Source/OS/dn_os_windows.h +++ b/Source/OS/dn_os_windows.h @@ -674,9 +674,11 @@ #define SW_HIDE 0 #define SW_NORMAL 1 + #define SW_SHOWNORMAL 1 #define SW_MAXIMIZE 3 #define SW_SHOWNOACTIVATE 4 #define SW_SHOW 5 + #define SW_RESTORE 9 #define SW_FORCEMINIMIZE 11 extern "C" @@ -686,7 +688,12 @@ __declspec(dllimport) UINT __stdcall GetWindowModuleFileNameA(HWND hwnd, LPSTR pszFileName, UINT cchFileNameMax); __declspec(dllimport) BOOL __stdcall ShowWindow (HWND hWnd, int nCmdShow); __declspec(dllimport) BOOL __stdcall GetWindowPlacement (HWND hWnd, WINDOWPLACEMENT *lpwndpl); - + __declspec(dllimport) BOOL __stdcall IsIconic (HWND hWnd); + __declspec(dllimport) BOOL __stdcall BringWindowToTop (HWND hWnd); + __declspec(dllimport) BOOL __stdcall SetForegroundWindow (HWND hWnd); + __declspec(dllimport) HWND __stdcall SetFocus (HWND hWnd); + __declspec(dllimport) HWND __stdcall GetForegroundWindow (); + __declspec(dllimport) BOOL __stdcall SetWindowTextW (HWND hWnd, LPCWSTR lpString); } // NOTE: um/wininet.h ////////////////////////////////////////////////////////////////////////// @@ -1188,7 +1195,6 @@ // NOTE: um/shellapi.h ///////////////////////////////////////////////////////////////////////// extern "C" { - __declspec(dllimport) HINSTANCE __stdcall ShellExecuteA(HWND hwnd, CHAR const *lpOperation, CHAR const *lpFile, CHAR const *lpParameters, CHAR const *lpDirectory, INT nShowCmd); __declspec(dllimport) HINSTANCE __stdcall ShellExecuteW(HWND hwnd, WCHAR const *lpOperation, WCHAR const *lpFile, WCHAR const *lpParameters, WCHAR const *lpDirectory, INT nShowCmd); } diff --git a/Source/dn.cpp b/Source/dn.cpp index 7f548ab..bb7e9dd 100644 --- a/Source/dn.cpp +++ b/Source/dn.cpp @@ -5,6 +5,7 @@ #define DN_WITH_NET_CURL 1 #define DN_ARENA_TEMP_MEM_UAF_GUARD 1 #include "dn.h" + #include #endif #if DN_STR8_AVX512F @@ -4003,13 +4004,65 @@ DN_API DN_Str8 DN_Str8PadNewLinesArena(DN_Str8 string, DN_Str8 pad_string, DN_Ar return result; } -DN_API DN_USize DN_USizeCodepointCountFromUTF8(DN_Str8 str, DN_CodepointCountFlags flags) +DN_API bool DN_Utf32IsAlphabet(DN_U32 codepoint) +{ + bool result = (codepoint >= 'A' && codepoint <= 'Z') || (codepoint >= 'a' && codepoint <= 'z'); + return result; +} + +DN_API bool DN_Utf32IsDigit(DN_U32 codepoint) +{ + bool result = (codepoint >= '0' && codepoint <= '9'); + return result; +} + +DN_API bool DN_Utf32IsAlphaNum(DN_U32 codepoint) +{ + bool result = DN_Utf32IsAlphabet(codepoint) || DN_Utf32IsDigit(codepoint); + return result; +} + +DN_API bool DN_Utf32IsWhitespace(DN_U32 codepoint) +{ + bool result = (codepoint == ' ' || codepoint == '\t' || codepoint == '\n' || codepoint == '\r'); + return result; +} + +DN_API bool DN_Utf32IsHex(DN_U32 codepoint) +{ + bool result = ((codepoint >= 'a' && codepoint <= 'f') || (codepoint >= 'A' && codepoint <= 'F') || (codepoint >= '0' && codepoint <= '9')); + return result; +} + +DN_API bool DN_Utf32IsWordCharacter(DN_U32 codepoint) +{ + bool result = DN_Utf32IsAlphaNum(codepoint) || codepoint == '_'; + return result; +} + +DN_API DN_U32 DN_Utf32ToLower(DN_U32 codepoint) +{ + DN_U32 result = codepoint; + if (result >= 'A' && result <= 'Z') + result += 'a' - 'A'; + return result; +} + +DN_API DN_U32 DN_Utf32ToUpper(DN_U32 codepoint) +{ + DN_U32 result = codepoint; + if (result >= 'a' && result <= 'z') + result -= 'a' - 'A'; + return result; +} + +DN_API DN_USize DN_Utf32CodepointCountFromUtf8(DN_Str8 str, DN_CodepointCountFlags flags) { DN_USize result = 0; if (DN_BitIsNotSet(flags, DN_CodepointCountFlags_SkipAnsiCode)) { - DN_UTF8DecodeIterator it = {}; - while (DN_UTF8DecodeIterate(&it, str)) + DN_Utf32FromUtf8Iterator it = {}; + while (DN_Utf32FromUtf8Iterate(&it, DN_Utf32IterateDir_Forwards, str)) ; result = it.codepoint_index; } else { @@ -4033,7 +4086,7 @@ DN_API DN_USize DN_USizeCodepointCountFromUTF8(DN_Str8 str, DN_CodepointCountFla continue; } - DN_UTF8DecodeResult decode = DN_UTF8Decode(DN_Str8FromPtr(p, end - p)); + DN_Utf32FromResult decode = DN_Utf32FromUtf8Stream(DN_Str8FromPtr(p, end - p)); if (!decode.success) break; p = decode.remaining.data; @@ -4130,7 +4183,7 @@ DN_API DN_Str8 DN_Str8Table(DN_Str8 const *rows, DN_USize num_rows, DN_USize num for (DN_USize i = 0; i < num_cols; i++) { for (DN_USize j = 0; j < num_rows; j++) { DN_USize index = j * num_cols + i; - col_widths[i] = DN_Max(col_widths[i], (DN_U16)DN_USizeCodepointCountFromUTF8(rows[index], DN_CodepointCountFlags_SkipAnsiCode)); + col_widths[i] = DN_Max(col_widths[i], (DN_U16)DN_Utf32CodepointCountFromUtf8(rows[index], DN_CodepointCountFlags_SkipAnsiCode)); } } @@ -4149,7 +4202,7 @@ DN_API DN_Str8 DN_Str8Table(DN_Str8 const *rows, DN_USize num_rows, DN_USize num DN_USize index = (i * num_cols) + j; DN_Str8 item = rows[index]; DN_Str8BuilderAppendF(&builder, " %.*s", DN_Str8PrintFmt(item)); - DN_USize item_width = DN_USizeCodepointCountFromUTF8(item, DN_CodepointCountFlags_SkipAnsiCode); + DN_USize item_width = DN_Utf32CodepointCountFromUtf8(item, DN_CodepointCountFlags_SkipAnsiCode); for (DN_USize k = 0; k < col_widths[j] - item_width; k++) DN_Str8BuilderAppendF(&builder, " "); DN_Str8BuilderAppendF(&builder, " |"); @@ -4658,7 +4711,7 @@ DN_API DN_Str8Builder DN_Str8BuilderFromBuilder(DN_Arena *arena, DN_Str8Builder return result; } -DN_API bool DN_Str8BuilderAddArrayRef(DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize count, DN_Str8BuilderAdd add) +DN_API bool DN_Str8BuilderAddArrayRef(DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize count, DN_AddType add) { if (!builder) return false; @@ -4671,7 +4724,7 @@ DN_API bool DN_Str8BuilderAddArrayRef(DN_Str8Builder *builder, DN_Str8 const *st if (!links) return false; - if (add == DN_Str8BuilderAdd_Append) { + if (add == DN_AddType_Append) { for (DN_ForIndexU(index, count)) { DN_Str8 string = strings[index]; DN_Str8Link *link = links + index; @@ -4686,7 +4739,7 @@ DN_API bool DN_Str8BuilderAddArrayRef(DN_Str8Builder *builder, DN_Str8 const *st builder->string_size += string.count; } } else { - DN_Assert(add == DN_Str8BuilderAdd_Prepend); + DN_Assert(add == DN_AddType_Prepend); DN_MSVC_WARNING_PUSH DN_MSVC_WARNING_DISABLE(6293) // NOTE: Ill-defined loop for (DN_USize index = count - 1; index < count; index--) { @@ -4705,7 +4758,7 @@ DN_API bool DN_Str8BuilderAddArrayRef(DN_Str8Builder *builder, DN_Str8 const *st return true; } -DN_API bool DN_Str8BuilderAddArrayCopy(DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize count, DN_Str8BuilderAdd add) +DN_API bool DN_Str8BuilderAddArrayCopy(DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize count, DN_AddType add) { if (!builder) return false; @@ -4731,7 +4784,7 @@ DN_API bool DN_Str8BuilderAddArrayCopy(DN_Str8Builder *builder, DN_Str8 const *s return result; } -DN_API bool DN_Str8BuilderAddFV(DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_FMT_ATTRIB char const *fmt, va_list args) +DN_API bool DN_Str8BuilderAddFV(DN_Str8Builder *builder, DN_AddType add, DN_FMT_ATTRIB char const *fmt, va_list args) { DN_Str8 string = DN_Str8FmtVArena(builder->arena, fmt, args); DN_U64 arena_p = DN_MemListPos(builder->arena->mem); @@ -4743,13 +4796,13 @@ DN_API bool DN_Str8BuilderAddFV(DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_API bool DN_Str8BuilderAppendRef(DN_Str8Builder *builder, DN_Str8 string) { - bool result = DN_Str8BuilderAddArrayRef(builder, &string, 1, DN_Str8BuilderAdd_Append); + bool result = DN_Str8BuilderAddArrayRef(builder, &string, 1, DN_AddType_Append); return result; } DN_API bool DN_Str8BuilderAppendCopy(DN_Str8Builder *builder, DN_Str8 string) { - bool result = DN_Str8BuilderAddArrayCopy(builder, &string, 1, DN_Str8BuilderAdd_Append); + bool result = DN_Str8BuilderAddArrayCopy(builder, &string, 1, DN_AddType_Append); return result; } @@ -4838,13 +4891,13 @@ DN_API bool DN_Str8BuilderAppendBuilderCopy(DN_Str8Builder *dest, DN_Str8Builder DN_API bool DN_Str8BuilderPrependRef(DN_Str8Builder *builder, DN_Str8 string) { - bool result = DN_Str8BuilderAddArrayRef(builder, &string, 1, DN_Str8BuilderAdd_Prepend); + bool result = DN_Str8BuilderAddArrayRef(builder, &string, 1, DN_AddType_Prepend); return result; } DN_API bool DN_Str8BuilderPrependCopy(DN_Str8Builder *builder, DN_Str8 string) { - bool result = DN_Str8BuilderAddArrayCopy(builder, &string, 1, DN_Str8BuilderAdd_Prepend); + bool result = DN_Str8BuilderAddArrayCopy(builder, &string, 1, DN_AddType_Prepend); return result; } @@ -5095,9 +5148,7 @@ DN_API DN_Str8 DN_Str8FmtOsPathArena(DN_Arena *arena, DN_FMT_ATTRIB char const * return result; } - -// NOTE: DN_UTF -DN_API int DN_UTF8Encode(DN_U8 utf8[4], DN_U32 codepoint) +DN_API DN_USize DN_Utf8FromUtf32(DN_U8 utf8[4], DN_U32 codepoint) { // NOTE: Table from https://www.reedbeta.com/blog/programmers-intro-to-unicode/ // ----------------------------------------+----------------------------+--------------------+ @@ -5138,96 +5189,7 @@ DN_API int DN_UTF8Encode(DN_U8 utf8[4], DN_U32 codepoint) return 0; } -DN_API DN_UTF8DecodeResult DN_UTF8Decode(DN_Str8 stream) -{ - DN_UTF8DecodeResult result = {}; - result.remaining = stream; - if (stream.count <= 0) - return result; - - DN_U8 b0 = DN_Cast(DN_U8)stream.data[0]; - DN_U8 b1 = DN_Cast(DN_U8)(stream.count >= 2 ? stream.data[1] : 0); - DN_U8 b2 = DN_Cast(DN_U8)(stream.count >= 3 ? stream.data[2] : 0); - DN_U8 b3 = DN_Cast(DN_U8)(stream.count >= 4 ? stream.data[3] : 0); - - if ((b0 & 0b1000'0000) == 0) { - result.codepoint = b0; - result.success = true; - result.remaining = DN_Str8FromPtr(stream.data + 1, stream.count - 1); - return result; - } - - if ((b0 & 0b1110'0000) == 0b1100'0000) { - if (stream.count < 2) - return result; - if ((b1 & 0b1100'0000) != 0b1000'0000) - return result; - DN_U32 cp = ((b0 & 0b0001'1111) << 6) | ((b1 & 0b0011'1111) << 0); - if (cp < 0x80) - return result; - result.codepoint = cp; - result.success = true; - result.remaining = DN_Str8FromPtr(stream.data + 2, stream.count - 2); - return result; - } - - if ((b0 & 0b1111'0000) == 0b1110'0000) { - if (stream.count < 3) - return result; - if ((b1 & 0b1100'0000) != 0b1000'0000) - return result; - if ((b2 & 0b1100'0000) != 0b1000'0000) - return result; - DN_U32 cp = ((b0 & 0b0000'1111) << 12) | ((b1 & 0b0011'1111) << 6) | ((b2 & 0b0011'1111) << 0); - if (cp < 0x800) - return result; - result.codepoint = cp; - result.success = true; - result.remaining = DN_Str8FromPtr(stream.data + 3, stream.count - 3); - return result; - } - - if ((b0 & 0b1111'1000) == 0b1111'0000) { - if (stream.count < 4) - return result; - if ((b1 & 0b1100'0000) != 0b1000'0000) - return result; - if ((b2 & 0b1100'0000) != 0b1000'0000) - return result; - if ((b3 & 0b1100'0000) != 0b1000'0000) - return result; - DN_U32 cp = ((b0 & 0b0000'0111) << 18) | - ((b1 & 0b0011'1111) << 12) | - ((b2 & 0b0011'1111) << 6) | - ((b3 & 0b0011'1111) << 0); - if (cp < 0x10000 || cp > 0x10FFFF) - return result; - result.codepoint = cp; - result.success = true; - result.remaining = DN_Str8FromPtr(stream.data + 4, stream.count - 4); - return result; - } - - return result; -} - -DN_API bool DN_UTF8DecodeIterate(DN_UTF8DecodeIterator *it, DN_Str8 utf8) -{ - if (it->init) { - it->codepoint_index++; - } else { - it->remaining = utf8; - it->init = true; - } - DN_UTF8DecodeResult decode = DN_UTF8Decode(it->remaining); - it->success = decode.success; - it->remaining = decode.remaining; - it->codepoint = decode.codepoint; - bool result = it->success; - return result; -} - -DN_API int DN_UTF16Encode(DN_U16 utf16[2], DN_U32 codepoint) +DN_API DN_USize DN_Utf32FromUtf16(DN_U16 utf16[2], DN_U32 codepoint) { // NOTE: Table from https://www.reedbeta.com/blog/programmers-intro-to-unicode/ // ----------------------------------------+------------------------------------+------------------+ @@ -5252,6 +5214,128 @@ DN_API int DN_UTF16Encode(DN_U16 utf16[2], DN_U32 codepoint) return 0; } +DN_API DN_Utf32FromResult DN_Utf32FromUtf8Stream(DN_Str8 stream) +{ + DN_Utf32FromResult result = {}; + result.remaining = stream; + if (stream.count <= 0) + return result; + + // NOTE: Decompose stream into 4 potential utf8 bytes + DN_U8 b0 = DN_Cast(DN_U8)stream.data[0]; + DN_U8 b1 = DN_Cast(DN_U8)(stream.count >= 2 ? stream.data[1] : 0); + DN_U8 b2 = DN_Cast(DN_U8)(stream.count >= 3 ? stream.data[2] : 0); + DN_U8 b3 = DN_Cast(DN_U8)(stream.count >= 4 ? stream.data[3] : 0); + + // NOTE: Decode + if ((b0 & 0b1000'0000) == 0) { + result.codepoint = b0; + result.success = true; + result.remaining = DN_Str8FromPtr(stream.data + 1, stream.count - 1); + result.byte_count = 1; + return result; + } + + if ((b0 & 0b1110'0000) == 0b1100'0000) { + if (stream.count < 2) + return result; + if ((b1 & 0b1100'0000) != 0b1000'0000) + return result; + DN_U32 cp = ((b0 & 0b0001'1111) << 6) | ((b1 & 0b0011'1111) << 0); + if (cp < 0x80) + return result; + result.codepoint = cp; + result.success = true; + result.remaining = DN_Str8FromPtr(stream.data + 2, stream.count - 2); + result.byte_count = 2; + return result; + } + + if ((b0 & 0b1111'0000) == 0b1110'0000) { + if (stream.count < 3) + return result; + if ((b1 & 0b1100'0000) != 0b1000'0000) + return result; + if ((b2 & 0b1100'0000) != 0b1000'0000) + return result; + DN_U32 cp = ((b0 & 0b0000'1111) << 12) | ((b1 & 0b0011'1111) << 6) | ((b2 & 0b0011'1111) << 0); + if (cp < 0x800) + return result; + result.codepoint = cp; + result.success = true; + result.remaining = DN_Str8FromPtr(stream.data + 3, stream.count - 3); + result.byte_count = 3; + return result; + } + + if ((b0 & 0b1111'1000) == 0b1111'0000) { + if (stream.count < 4) + return result; + if ((b1 & 0b1100'0000) != 0b1000'0000) + return result; + if ((b2 & 0b1100'0000) != 0b1000'0000) + return result; + if ((b3 & 0b1100'0000) != 0b1000'0000) + return result; + DN_U32 cp = ((b0 & 0b0000'0111) << 18) | ((b1 & 0b0011'1111) << 12) | ((b2 & 0b0011'1111) << 6) | ((b3 & 0b0011'1111) << 0); + if (cp < 0x10000 || cp > 0x10FFFF) + return result; + result.codepoint = cp; + result.success = true; + result.remaining = DN_Str8FromPtr(stream.data + 4, stream.count - 4); + result.byte_count = 4; + return result; + } + + return result; +} + +DN_API bool DN_Utf32FromUtf8Iterate(DN_Utf32FromUtf8Iterator *it, DN_Utf32IterateDir dir, DN_Str8 utf8) +{ + // NOTE: Iterate forwards + if (dir == DN_Utf32IterateDir_Forwards) { + if (it->init) { + it->codepoint_index++; + } else { + it->remaining = utf8; + it->init = true; + } + DN_Utf32FromResult decode = DN_Utf32FromUtf8Stream(it->remaining); + it->success = decode.success; + it->remaining = decode.remaining; + it->codepoint = decode.codepoint; + it->bytes_decoded += decode.byte_count; + } + + // NOTE: Or otherwise iterate backwards + if (dir == DN_Utf32IterateDir_Reverse) { + bool first_time = it->init == false; + if (first_time) { + it->remaining = utf8; + it->init = true; + } + + it->success = false; + for (DN_USize codepoint_size = 1; codepoint_size <= 4; codepoint_size++) { + DN_Str8 utf8_stream = DN_Str8Subset(it->remaining, it->remaining.count - codepoint_size, codepoint_size); + DN_Utf32FromResult utf32_from = DN_Utf32FromUtf8Stream(utf8_stream); + if (utf32_from.success) { + DN_Assert(utf32_from.byte_count <= it->remaining.count); + it->success = true; + it->remaining = DN_Str8FromPtr(it->remaining.data, it->remaining.count - utf32_from.byte_count); + it->bytes_decoded += utf32_from.byte_count; + it->codepoint = utf32_from.codepoint; + break; + } + } + + if (!first_time && it->success) + it->codepoint_index++; + } + + bool result = it->success; + return result; +} DN_API DN_U8 DN_U8FromHexNibble(char hex) { @@ -8593,13 +8677,14 @@ DN_API void *DN_ArrayMakeArrayPool(void **data, DN_USize *count, DN_USize *max, return result; } -DN_API void *DN_ArrayAddArray(void *data, DN_USize *count, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add) +DN_API void *DN_ArrayAddArray(void *data, DN_USize *count, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_AddType add) { void *result = DN_ArrayMakeArray(data, count, max, elem_size, elems_count, DN_ZMem_No); if (result) { - if (add == DN_ArrayAdd_Append) { + if (add == DN_AddType_Append) { DN_Memcpy(result, elems, elems_count * elem_size); } else { + DN_Assert(add == DN_AddType_Prepend); char *move_dest = DN_Cast(char *)data + (elems_count * elem_size); // Shift elements forward char *move_src = DN_Cast(char *)data; DN_Memmove(move_dest, move_src, elem_size * count[0]); @@ -8609,7 +8694,7 @@ DN_API void *DN_ArrayAddArray(void *data, DN_USize *count, DN_USize max, DN_USiz return result; } -DN_API void *DN_ArrayAddArrayArena(void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, DN_Arena *arena, void const *elems, DN_USize elems_count, DN_ArrayAdd add) +DN_API void *DN_ArrayAddArrayArena(void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, DN_Arena *arena, void const *elems, DN_USize elems_count, DN_AddType add) { void *result = nullptr; if (DN_ArrayPrepareArena(data, *count, max, elem_size, arena, elems_count)) @@ -8617,7 +8702,7 @@ DN_API void *DN_ArrayAddArrayArena(void **data, DN_USize *count, DN_USize *max, return result; } -DN_API void *DN_ArrayAddArrayPool(void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, DN_Pool *pool, void const *elems, DN_USize elems_count, DN_ArrayAdd add) +DN_API void *DN_ArrayAddArrayPool(void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, DN_Pool *pool, void const *elems, DN_USize elems_count, DN_AddType add) { void *result = nullptr; if (DN_ArrayPreparePool(data, *count, max, elem_size, pool, elems_count)) @@ -8625,7 +8710,7 @@ DN_API void *DN_ArrayAddArrayPool(void **data, DN_USize *count, DN_USize *max, D return result; } -DN_API void *DN_ArrayAddArrayAssert(void *data, DN_USize *count, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site) +DN_API void *DN_ArrayAddArrayAssert(void *data, DN_USize *count, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_AddType add, DN_CallSite call_site) { void *result = DN_ArrayAddArray(data, count, max, elem_size, elems, elems_count, add); DN_AssertCallSiteF(result, call_site, "Array out of space, failed to add %zu items: array=%p size=%zu max=%zu", elems_count, data, *count, max); @@ -12052,6 +12137,14 @@ DN_API DN_Str8 DN_OS_ExeDir(DN_Arena *arena) return result; } +DN_API void DN_OS_OpenUrl(DN_Str8 url) +{ + DN_TcScratch scratch = DN_TcScratchBeginArena(nullptr, 0); + DN_Str16 url16 = DN_OS_W32Str8ToStr16(&scratch.arena, url); + ShellExecuteW(0, L"open", (WCHAR *)url16.data, 0, 0, SW_SHOWNORMAL); + DN_TcScratchEnd(&scratch); +} + // NOTE: Counters DN_API DN_F64 DN_OS_PerfCounterS(uint64_t begin, uint64_t end) { @@ -12402,6 +12495,32 @@ DN_API DN_OSExecResult DN_OS_ExecOrAbort(DN_Str8Slice cmd_line, DN_OSExecArgs ar return result; } +DN_API void DN_OS_WindowMaximise(DN_OSWindow *window, DN_OSWindowMaximise maximise) +{ + DN_OSWindowMaximise is_maximised = DN_OS_WindowIsMaximised(window); + if (is_maximised != maximise) { + DN_OSWindowShow show = DN_OSWindowShow_Nil; + switch (maximise) { + case DN_OSWindowMaximise_No: show = DN_OSWindowShow_Restore; break; + case DN_OSWindowMaximise_Yes: show = DN_OSWindowShow_Maximise; break; + } + DN_OS_WindowShow(window, show); + } +} + +DN_API void DN_OS_WindowMinimise(DN_OSWindow *window, DN_OSWindowMinimise minimise) +{ + DN_OSWindowMinimise is_minimised = DN_OS_WindowIsMinimised(window); + if (is_minimised != minimise) { + DN_OSWindowShow show = DN_OSWindowShow_Nil; + switch (minimise) { + case DN_OSWindowMinimise_No: show = DN_OSWindowShow_Restore; break; + case DN_OSWindowMinimise_Yes: show = DN_OSWindowShow_Minimise; break; + } + DN_OS_WindowShow(window, show); + } +} + static void DN_OS_ThreadExecute_(void *user_context) { DN_OSThread *thread = DN_Cast(DN_OSThread *) user_context; diff --git a/Source/dn.h b/Source/dn.h index b29fd64..3bda49f 100644 --- a/Source/dn.h +++ b/Source/dn.h @@ -1,6 +1,10 @@ #if !defined(DN_H) #define DN_H +#if defined(_CLANGD) + #define DN_WITH_OS 1 +#endif + // NOTE: DN // Getting Started @@ -782,6 +786,11 @@ typedef enum DN_ZMem { DN_ZMem_Yes, // Memory should be zero-ed out before giving to the callee } DN_ZMem; +typedef enum DN_AddType { + DN_AddType_Prepend, + DN_AddType_Append, +} DN_AddType; + typedef struct DN_Str8 DN_Str8; struct DN_Str8 { @@ -1363,24 +1372,32 @@ struct DN_Pool DN_U8 align; }; -typedef struct DN_UTF8DecodeResult DN_UTF8DecodeResult; -struct DN_UTF8DecodeResult +typedef struct DN_Utf32FromResult DN_Utf32FromResult; +struct DN_Utf32FromResult { - bool success; - DN_Str8 remaining; - DN_U32 codepoint; + bool success; + DN_Str8 remaining; + DN_U32 codepoint; + DN_USize byte_count; // Number of bytes from the stream that was decoded }; -typedef struct DN_UTF8DecodeIterator DN_UTF8DecodeIterator; -struct DN_UTF8DecodeIterator +typedef struct DN_Utf32FromIterator DN_Utf32FromUtf8Iterator; +struct DN_Utf32FromIterator { bool init; bool success; DN_Str8 remaining; + DN_USize bytes_decoded; DN_USize codepoint_index; DN_U32 codepoint; }; +enum DN_Utf32IterateDir +{ + DN_Utf32IterateDir_Forwards, + DN_Utf32IterateDir_Reverse, +}; + typedef DN_U32 DN_CodepointCountFlags; enum DN_CodepointCountFlags_ { @@ -1497,12 +1514,6 @@ struct DN_Str8Builder DN_USize count; // The number of links in the linked list of strings }; -enum DN_Str8BuilderAdd -{ - DN_Str8BuilderAdd_Append, - DN_Str8BuilderAdd_Prepend, -}; - #if !defined(DN_OsPathSeperator) #if defined(DN_PLATFORM_WIN32) #define DN_OsPathSeperator "\\" @@ -1966,11 +1977,6 @@ typedef enum DN_ArrayErase { DN_ArrayErase_Stable, } DN_ArrayErase; -typedef enum DN_ArrayAdd { - DN_ArrayAdd_Append, - DN_ArrayAdd_Prepend, -} DN_ArrayAdd; - typedef struct DN_ArrayEraseResult DN_ArrayEraseResult; struct DN_ArrayEraseResult { @@ -2449,6 +2455,31 @@ struct DN_OSConditionVariable DN_U64 handle; }; +struct DN_OSWindow +{ + DN_UPtr handle; +}; + +enum DN_OSWindowShow +{ + DN_OSWindowShow_Nil, + DN_OSWindowShow_Restore, + DN_OSWindowShow_Minimise, + DN_OSWindowShow_Maximise, +}; + +enum DN_OSWindowMaximise +{ + DN_OSWindowMaximise_No, + DN_OSWindowMaximise_Yes, +}; + +enum DN_OSWindowMinimise +{ + DN_OSWindowMinimise_No, + DN_OSWindowMinimise_Yes, +}; + typedef DN_I32(DN_OSThreadFunc)(struct DN_OSThread *); typedef DN_U32 DN_OSThreadFlags; @@ -3178,28 +3209,28 @@ DN_API DN_Str8Builder DN_Str8BuilderFromArena DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRef (DN_Arena *arena, DN_Str8 const *strings, DN_USize count); DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopy (DN_Arena *arena, DN_Str8 const *strings, DN_USize count); DN_API DN_Str8Builder DN_Str8BuilderFromBuilder (DN_Arena *arena, DN_Str8Builder const *builder); -DN_API bool DN_Str8BuilderAddArrayRef (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize count, DN_Str8BuilderAdd add); -DN_API bool DN_Str8BuilderAddArrayCopy (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize count, DN_Str8BuilderAdd add); -DN_API bool DN_Str8BuilderAddFV (DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_FMT_ATTRIB char const *fmt, va_list args); -#define DN_Str8BuilderAppendArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Append) -#define DN_Str8BuilderAppendArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Append) -#define DN_Str8BuilderAppendSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.count, DN_Str8BuilderAdd_Append) -#define DN_Str8BuilderAppendSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.count, DN_Str8BuilderAdd_Append) +DN_API bool DN_Str8BuilderAddArrayRef (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize count, DN_AddType add); +DN_API bool DN_Str8BuilderAddArrayCopy (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize count, DN_AddType add); +DN_API bool DN_Str8BuilderAddFV (DN_Str8Builder *builder, DN_AddType add, DN_FMT_ATTRIB char const *fmt, va_list args); +#define DN_Str8BuilderAppendArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_AddType_Append) +#define DN_Str8BuilderAppendArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_AddType_Append) +#define DN_Str8BuilderAppendSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.count, DN_AddType_Append) +#define DN_Str8BuilderAppendSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.count, DN_AddType_Append) DN_API bool DN_Str8BuilderAppendRef (DN_Str8Builder *builder, DN_Str8 string); DN_API bool DN_Str8BuilderAppendCopy (DN_Str8Builder *builder, DN_Str8 string); -#define DN_Str8BuilderAppendFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_Str8BuilderAdd_Append, fmt, args) +#define DN_Str8BuilderAppendFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_AddType_Append, fmt, args) DN_API bool DN_Str8BuilderAppendF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...); DN_API bool DN_Str8BuilderAppendBytesRef (DN_Str8Builder *builder, void const *ptr, DN_USize count); DN_API bool DN_Str8BuilderAppendBytesCopy (DN_Str8Builder *builder, void const *ptr, DN_USize count); DN_API bool DN_Str8BuilderAppendBuilderRef (DN_Str8Builder *dest, DN_Str8Builder const *src); DN_API bool DN_Str8BuilderAppendBuilderCopy (DN_Str8Builder *dest, DN_Str8Builder const *src); -#define DN_Str8BuilderPrependArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Prepend) -#define DN_Str8BuilderPrependArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Prepend) -#define DN_Str8BuilderPrependSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.count, DN_Str8BuilderAdd_Prepend) -#define DN_Str8BuilderPrependSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.count, DN_Str8BuilderAdd_Prepend) +#define DN_Str8BuilderPrependArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_AddType_Prepend) +#define DN_Str8BuilderPrependArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_AddType_Prepend) +#define DN_Str8BuilderPrependSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.count, DN_AddType_Prepend) +#define DN_Str8BuilderPrependSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.count, DN_AddType_Prepend) DN_API bool DN_Str8BuilderPrependRef (DN_Str8Builder *builder, DN_Str8 string); DN_API bool DN_Str8BuilderPrependCopy (DN_Str8Builder *builder, DN_Str8 string); -#define DN_Str8BuilderPrependFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_Str8BuilderAdd_Prepend, fmt, args) +#define DN_Str8BuilderPrependFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_AddType_Prepend, fmt, args) DN_API bool DN_Str8BuilderPrependF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...); DN_API bool DN_Str8BuilderErase (DN_Str8Builder *builder, DN_Str8 string); DN_API DN_Str8 DN_Str8FromStr8BuilderAllocator (DN_Str8Builder const *builder, DN_Allocator allocator); @@ -3219,11 +3250,19 @@ DN_API DN_Str8 DN_Str8FmtPathPool DN_API DN_Str8 DN_Str8FmtOsPathArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8 DN_Str8FmtOsPathPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...); -DN_API int DN_UTF8Encode (DN_U8 utf8[4], DN_U32 codepoint); -DN_API int DN_UTF16Encode (DN_U16 utf16[2], DN_U32 codepoint); -DN_API DN_UTF8DecodeResult DN_UTF8Decode (DN_Str8 stream); -DN_API bool DN_UTF8DecodeIterate (DN_UTF8DecodeIterator *it, DN_Str8 utf8); -DN_API DN_USize DN_USizeCodepointCountFromUTF8 (DN_Str8 str, DN_CodepointCountFlags flags); +DN_API DN_USize DN_Utf8FromUtf32 (DN_U8 utf8[4], DN_U32 codepoint); +DN_API bool DN_Utf32IsAlphabet (DN_U32 codepoint); +DN_API bool DN_Utf32IsDigit (DN_U32 codepoint); +DN_API bool DN_Utf32IsAlphaNum (DN_U32 codepoint); +DN_API bool DN_Utf32IsWhitespace (DN_U32 codepoint); +DN_API bool DN_Utf32IsHex (DN_U32 codepoint); +DN_API bool DN_Utf32IsWordCharacter (DN_U32 codepoint); +DN_API DN_U32 DN_Utf32ToLower (DN_U32 codepoint); +DN_API DN_U32 DN_Utf32ToUpper (DN_U32 codepoint); +DN_API DN_USize DN_Utf32FromUtf16 (DN_U16 utf16[2], DN_U32 codepoint); +DN_API DN_Utf32FromResult DN_Utf32FromUtf8Stream (DN_Str8 stream); +DN_API bool DN_Utf32FromUtf8Iterate (DN_Utf32FromUtf8Iterator *it, DN_Utf32IterateDir dir, DN_Str8 utf8); +DN_API DN_USize DN_Utf32CodepointCountFromUtf8 (DN_Str8 str, DN_CodepointCountFlags flags); DN_API DN_U8 DN_U8FromHexNibble (char hex); DN_API DN_NibbleFromU8Result DN_NibbleFromU8 (DN_U8 u8); @@ -4004,15 +4043,15 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 #define DN_PArrayAdd(ptr, ptr_size, max, item, add) DN_TArrayAddArray(ptr, ptr_size, max, &item, 1, add) #define DN_PArrayAddArena(ptr, ptr_size, ptr_max, arena, item, add) DN_TArrayAddArrayArena(&(ptr), ptr_size, ptr_max, arena, &item, 1, add) #define DN_PArrayAddPool(ptr, ptr_size, ptr_max, pool, item, add) DN_TArrayAddArrayPool(&(ptr), ptr_size, ptr_max, pool, &item, 1, add) - #define DN_PArrayAppendArray(ptr, ptr_size, max, items, count) DN_TArrayAddArray(ptr, ptr_size, max, items, count, DN_ArrayAdd_Append) - #define DN_PArrayAppend(ptr, ptr_size, max, item) DN_TArrayAddArray(ptr, ptr_size, max, &item, 1, DN_ArrayAdd_Append) - #define DN_PArrayAppendArena(ptr, ptr_size, ptr_max, arena, item) DN_TArrayAddArrayArena(&(ptr), ptr_size, ptr_max, arena, &item, 1, DN_ArrayAdd_Append) - #define DN_PArrayAppendPool(ptr, ptr_size, ptr_max, pool, item) DN_TArrayAddArrayPool(&(ptr), ptr_size, ptr_max, pool, &item, 1, DN_ArrayAdd_Append) - #define DN_PArrayAppendAssert(ptr, ptr_size, max, item) DN_TArrayAddArrayAssert(ptr, ptr_size, max, &item, 1, DN_ArrayAdd_Append, DN_CallSiteNow) - #define DN_PArrayPrependArray(ptr, ptr_size, max, items, count) DN_TArrayAddArray(ptr, ptr_size, max, items, count, DN_ArrayAdd_Prepend) - #define DN_PArrayPrepend(ptr, ptr_size, max, item) DN_TArrayAddArray(ptr, ptr_size, max, &item, 1, DN_ArrayAdd_Prepend) - #define DN_PArrayPrependArena(ptr, ptr_size, ptr_max, arena, item) DN_TArrayAddArrayArena(&(ptr), ptr_size, ptr_max, arena, &item, 1, DN_ArrayAdd_Prepend) - #define DN_PArrayPrependPool(ptr, ptr_size, ptr_max, pool, item) DN_TArrayAddArrayPool(&(ptr), ptr_size, ptr_max, pool, &item, 1, DN_ArrayAdd_Prepend) + #define DN_PArrayAppendArray(ptr, ptr_size, max, items, count) DN_TArrayAddArray(ptr, ptr_size, max, items, count, DN_AddType_Append) + #define DN_PArrayAppend(ptr, ptr_size, max, item) DN_TArrayAddArray(ptr, ptr_size, max, &item, 1, DN_AddType_Append) + #define DN_PArrayAppendArena(ptr, ptr_size, ptr_max, arena, item) DN_TArrayAddArrayArena(&(ptr), ptr_size, ptr_max, arena, &item, 1, DN_AddType_Append) + #define DN_PArrayAppendPool(ptr, ptr_size, ptr_max, pool, item) DN_TArrayAddArrayPool(&(ptr), ptr_size, ptr_max, pool, &item, 1, DN_AddType_Append) + #define DN_PArrayAppendAssert(ptr, ptr_size, max, item) DN_TArrayAddArrayAssert(ptr, ptr_size, max, &item, 1, DN_AddType_Append, DN_CallSiteNow) + #define DN_PArrayPrependArray(ptr, ptr_size, max, items, count) DN_TArrayAddArray(ptr, ptr_size, max, items, count, DN_AddType_Prepend) + #define DN_PArrayPrepend(ptr, ptr_size, max, item) DN_TArrayAddArray(ptr, ptr_size, max, &item, 1, DN_AddType_Prepend) + #define DN_PArrayPrependArena(ptr, ptr_size, ptr_max, arena, item) DN_TArrayAddArrayArena(&(ptr), ptr_size, ptr_max, arena, &item, 1, DN_AddType_Prepend) + #define DN_PArrayPrependPool(ptr, ptr_size, ptr_max, pool, item) DN_TArrayAddArrayPool(&(ptr), ptr_size, ptr_max, pool, &item, 1, DN_AddType_Prepend) #define DN_PArrayEraseRange(ptr, ptr_size, begin_index, count, erase) DN_TArrayEraseRange(ptr, ptr_size, begin_index, count, erase) #define DN_PArrayErase(ptr, ptr_size, index, erase) DN_TArrayEraseRange(ptr, ptr_size, index, 1, erase) @@ -4066,15 +4105,15 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 #define DN_PArrayAdd(ptr, ptr_size, max, item, add) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, add) #define DN_PArrayAddArena(ptr, ptr_size, max, arena, item, add) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayArena((void **)&(ptr), ptr_size, max, sizeof((ptr)[0]), arena, &item, 1, add) #define DN_PArrayAddPool(ptr, ptr_size, max, pool, item, add) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayPool((void **)&(ptr), ptr_size, max, sizeof((ptr)[0]), pool, &item, 1, add) - #define DN_PArrayAppendArray(ptr, ptr_size, max, items, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, DN_ArrayAdd_Append) - #define DN_PArrayAppend(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_ArrayAdd_Append) - #define DN_PArrayAppendArena(ptr, ptr_size, max, arena, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayArena((void **)&(ptr), ptr_size, max, sizeof((ptr)[0]), arena, &item, 1, DN_ArrayAdd_Append) - #define DN_PArrayAppendPool(ptr, ptr_size, max, pool, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayPool((void **)&(ptr), ptr_size, max, sizeof((ptr)[0]), pool, &item, 1, DN_ArrayAdd_Append) - #define DN_PArrayAppendAssert(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_ArrayAdd_Append, DN_CallSiteNow) - #define DN_PArrayPrependArray(ptr, ptr_size, max, items, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, DN_ArrayAdd_Prepend) - #define DN_PArrayPrepend(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_ArrayAdd_Prepend) - #define DN_PArrayPrependArena(ptr, ptr_size, max, arena, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayArena((void **)&(ptr), ptr_size, max, sizeof((ptr)[0]), arena, &item, 1, DN_ArrayAdd_Prepend) - #define DN_PArrayPrependPool(ptr, ptr_size, max, pool, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayPool((void **)&(ptr), ptr_size, max, sizeof((ptr)[0]), pool, &item, 1, DN_ArrayAdd_Prepend) + #define DN_PArrayAppendArray(ptr, ptr_size, max, items, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, DN_AddType_Append) + #define DN_PArrayAppend(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_AddType_Append) + #define DN_PArrayAppendArena(ptr, ptr_size, max, arena, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayArena((void **)&(ptr), ptr_size, max, sizeof((ptr)[0]), arena, &item, 1, DN_AddType_Append) + #define DN_PArrayAppendPool(ptr, ptr_size, max, pool, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayPool((void **)&(ptr), ptr_size, max, sizeof((ptr)[0]), pool, &item, 1, DN_AddType_Append) + #define DN_PArrayAppendAssert(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_AddType_Append, DN_CallSiteNow) + #define DN_PArrayPrependArray(ptr, ptr_size, max, items, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, DN_AddType_Prepend) + #define DN_PArrayPrepend(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_AddType_Prepend) + #define DN_PArrayPrependArena(ptr, ptr_size, max, arena, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayArena((void **)&(ptr), ptr_size, max, sizeof((ptr)[0]), arena, &item, 1, DN_AddType_Prepend) + #define DN_PArrayPrependPool(ptr, ptr_size, max, pool, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayPool((void **)&(ptr), ptr_size, max, sizeof((ptr)[0]), pool, &item, 1, DN_AddType_Prepend) #define DN_PArrayEraseRange(ptr, ptr_size, begin_index, count, erase) DN_ArrayEraseRange(ptr, ptr_size, sizeof((ptr)[0]), begin_index, count, erase) #define DN_PArrayErase(ptr, ptr_size, index, erase) DN_ArrayEraseRange(ptr, ptr_size, sizeof((ptr)[0]), index, 1, erase) @@ -4199,10 +4238,10 @@ DN_API void* DN_ArrayMakeArray (void * DN_API void* DN_ArrayMakeArrayAssert (void *data, DN_USize *count, DN_USize max, DN_USize elem_size, DN_USize make_count, DN_ZMem z_mem, DN_CallSite call_site); DN_API void* DN_ArrayMakeArrayArena (void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, DN_Arena *arena, DN_USize make_count, DN_ZMem z_mem); DN_API void* DN_ArrayMakeArrayPool (void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize make_count, DN_ZMem z_mem); -DN_API void* DN_ArrayAddArray (void *data, DN_USize *count, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add); -DN_API void* DN_ArrayAddArrayAssert (void *data, DN_USize *count, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site); -DN_API void* DN_ArrayAddArrayArena (void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_Arena *arena, DN_ArrayAdd add); -DN_API void* DN_ArrayAddArrayPool (void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_Pool *pool, DN_ArrayAdd add); +DN_API void* DN_ArrayAddArray (void *data, DN_USize *count, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_AddType add); +DN_API void* DN_ArrayAddArrayAssert (void *data, DN_USize *count, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_AddType add, DN_CallSite call_site); +DN_API void* DN_ArrayAddArrayArena (void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_Arena *arena, DN_AddType add); +DN_API void* DN_ArrayAddArrayPool (void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_Pool *pool, DN_AddType add); DN_API bool DN_ArrayResizePool (void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize new_max); DN_API bool DN_ArrayResizeArena (void **data, DN_USize *count, DN_USize *max, DN_USize elem_size, DN_Arena *arena, DN_USize new_max); DN_API bool DN_ArrayReservePool (void **data, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize new_max); @@ -4225,24 +4264,24 @@ template T* DN_TArrayMakeArray (T *dat template T* DN_TArrayMakeArrayAssert (T *data, DN_USize *count, DN_USize max, DN_USize make_count, DN_ZMem z_mem, DN_CallSite call_site); template T* DN_TArrayMakeArrayAssertZ (T *data, DN_USize *count, DN_USize max, DN_USize make_count, DN_CallSite call_site); template T* DN_TArrayMakeArrayAssertNoZ (T *data, DN_USize *count, DN_USize max, DN_USize make_count, DN_CallSite call_site); -template T* DN_TArrayAddArray (T *data, DN_USize *count, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add); -template T* DN_TArrayAddArrayAssert (T *data, DN_USize *count, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site); +template T* DN_TArrayAddArray (T *data, DN_USize *count, DN_USize max, T const *elems, DN_USize elems_count, DN_AddType add); +template T* DN_TArrayAddArrayAssert (T *data, DN_USize *count, DN_USize max, T const *elems, DN_USize elems_count, DN_AddType add, DN_CallSite call_site); template T* DN_TArrayMakeArrayArena (T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, DN_USize make_count, DN_ZMem z_mem); template T* DN_TArrayMakeArrayArenaZ (T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, DN_USize make_count); template T* DN_TArrayMakeArrayArenaNoZ (T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, DN_USize make_count); template T* DN_TArrayMakeArrayPool (T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, DN_USize make_count, DN_ZMem z_mem); template T* DN_TArrayMakeArrayPoolZ (T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, DN_USize make_count); template T* DN_TArrayMakeArrayPoolNoZ (T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, DN_USize make_count); -template T* DN_TArrayAddArrayArena (T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, T const *elems, DN_USize elems_count, DN_ArrayAdd add); -template T* DN_TArrayAddArrayPool (T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, T const *elems, DN_USize elems_count, DN_ArrayAdd add); +template T* DN_TArrayAddArrayArena (T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, T const *elems, DN_USize elems_count, DN_AddType add); +template T* DN_TArrayAddArrayPool (T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, T const *elems, DN_USize elems_count, DN_AddType add); template T* DN_TArrayMakeArena (T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, DN_ZMem z_mem); template T* DN_TArrayMakeArenaZ (T **data, DN_USize *count, DN_USize *max, DN_Arena *arena); template T* DN_TArrayMakeArenaNoZ (T **data, DN_USize *count, DN_USize *max, DN_Arena *arena); template T* DN_TArrayMakePool (T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, DN_ZMem z_mem); template T* DN_TArrayMakePoolZ (T **data, DN_USize *count, DN_USize *max, DN_Pool *pool); template T* DN_TArrayMakePoolNoZ (T **data, DN_USize *count, DN_USize *max, DN_Pool *pool); -template T* DN_TArrayAddArena (T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, T const *elems, DN_USize elems_count, DN_ArrayAdd add); -template T* DN_TArrayAddPool (T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, T const *elems, DN_USize elems_count, DN_ArrayAdd add); +template T* DN_TArrayAddArena (T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, T const *elems, DN_USize elems_count, DN_AddType add); +template T* DN_TArrayAddPool (T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, T const *elems, DN_USize elems_count, DN_AddType add); template bool DN_TArrayResizePool (T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, DN_USize new_max); template bool DN_TArrayResizeArena (T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, DN_USize new_max); template bool DN_TArrayReservePool (T **data, DN_USize *max, DN_Pool *pool, DN_USize new_max); @@ -4627,6 +4666,7 @@ DN_API bool DN_OS_SetEnvVar (D DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path); DN_API DN_Str8 DN_OS_ExePath (DN_Arena *arena); DN_API DN_Str8 DN_OS_ExeDir (DN_Arena *arena); +DN_API void DN_OS_OpenUrl (DN_Str8 url); DN_API void DN_OS_SleepMs (DN_UInt milliseconds); DN_API DN_U64 DN_OS_PerfCounterNow (); @@ -4743,6 +4783,17 @@ DN_API bool DN_OS_ConditionVariableWaitUntil (D DN_API void DN_OS_ConditionVariableSignal (DN_OSConditionVariable *cv); DN_API void DN_OS_ConditionVariableBroadcast (DN_OSConditionVariable *cv); +// NOTE: Windowing +DN_API DN_OSWindowMinimise DN_OS_WindowIsMinimised (DN_OSWindow *window); +DN_API DN_OSWindowMaximise DN_OS_WindowIsMaximised (DN_OSWindow *window); +DN_API void DN_OS_WindowSetTitle (DN_OSWindow *window, DN_Str8 title); +DN_API void DN_OS_WindowShow (DN_OSWindow *window, DN_OSWindowShow min); +DN_API void DN_OS_WindowMaximise (DN_OSWindow *window, DN_OSWindowMaximise maximise); +DN_API void DN_OS_WindowMinimise (DN_OSWindow *window, DN_OSWindowMinimise minimise); +DN_API void DN_OS_WindowBringToFront (DN_OSWindow *window); +DN_API void DN_OS_WindowFocus (DN_OSWindow *window); +DN_API bool DN_OS_WindowIsFocused (DN_OSWindow *window); + // NOTE: Thread // Overview // Threading primitives that uses CreateThread on Win32 and pthreads everywhere else. Threads @@ -5003,14 +5054,14 @@ T *DN_TArrayMakeArrayAssertNoZ(T *data, DN_USize *count, DN_USize max, DN_USize } template -T *DN_TArrayAddArray(T *data, DN_USize *count, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add) +T *DN_TArrayAddArray(T *data, DN_USize *count, DN_USize max, T const *elems, DN_USize elems_count, DN_AddType add) { T* result = DN_Cast(T *)DN_ArrayAddArray(data, count, max, sizeof(*elems), elems, elems_count, add); return result; } template -T *DN_TArrayAddArrayAssert(T *data, DN_USize *count, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site) +T *DN_TArrayAddArrayAssert(T *data, DN_USize *count, DN_USize max, T const *elems, DN_USize elems_count, DN_AddType add, DN_CallSite call_site) { T* result = DN_Cast(T *)DN_ArrayAddArrayAssert(data, count, max, sizeof(*elems), elems, elems_count, add, call_site); return result; @@ -5059,14 +5110,14 @@ T *DN_TArrayMakeArrayPoolNoZ(T **data, DN_USize *count, DN_USize *max, DN_Pool * } template -T *DN_TArrayAddArrayArena(T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, T const *elems, DN_USize elems_count, DN_ArrayAdd add) +T *DN_TArrayAddArrayArena(T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, T const *elems, DN_USize elems_count, DN_AddType add) { T *result = DN_Cast(T *)DN_ArrayAddArrayArena(DN_Cast(void **)data, count, max, sizeof(**data), arena, elems, elems_count, add); return result; } template -T *DN_TArrayAddArrayPool(T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, T const *elems, DN_USize elems_count, DN_ArrayAdd add) +T *DN_TArrayAddArrayPool(T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, T const *elems, DN_USize elems_count, DN_AddType add) { T *result = DN_Cast(T *)DN_ArrayAddArrayPool(DN_Cast(void **)data, count, max, sizeof(**data), pool, elems, elems_count, add); return result; @@ -5115,14 +5166,14 @@ T *DN_TArrayMakePoolNoZ(T **data, DN_USize *count, DN_USize *max, DN_Pool *pool) } template -T *DN_TArrayAddArena(T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, T const *elems, DN_USize elems_count, DN_ArrayAdd add) +T *DN_TArrayAddArena(T **data, DN_USize *count, DN_USize *max, DN_Arena *arena, T const *elems, DN_USize elems_count, DN_AddType add) { T *result = DN_TArrayAddArrayArena(data, count, max, arena, elems, elems_count, add); return result; } template -T *DN_TArrayAddPool(T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, T const *elems, DN_USize elems_count, DN_ArrayAdd add) +T *DN_TArrayAddPool(T **data, DN_USize *count, DN_USize *max, DN_Pool *pool, T const *elems, DN_USize elems_count, DN_AddType add) { T *result = DN_TArrayAddArrayPool(data, count, max, pool, elems, elems_count, add); return result;