window management. still missing first paint but progressing
This commit is contained in:
1 parent
bf13f269fe
commit
f6b48a1c11
9 files changed
+4703
-18
No files matched your search
+19
-2
@@ -74,16 +74,22 @@
|
|||||||
// For loop helpers
|
// For loop helpers
|
||||||
|
|
||||||
#define EachIndex(it, count) (uint64 it = 0; it < (count); ++it)
|
#define EachIndex(it, count) (uint64 it = 0; it < (count); ++it)
|
||||||
|
#define EachNode(it, Type, first) (Type* it = first; it != 0; it = it->next)
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Memory Helpers
|
// Memory Helpers
|
||||||
|
|
||||||
#define MemoryCopy(dst, src, size) memmove((dst), (src), (size))
|
#define MemoryCopy(dst, src, size) memmove((dst), (src), (size))
|
||||||
#define MemorySet(dst, src, size) memset((dst), (src), (size))
|
#define MemorySet(dst, src, size) memset((dst), (src), (size))
|
||||||
|
#define MemoryCompare(a, b, size) memcmp((a), (b), (size))
|
||||||
|
|
||||||
#define MemoryZero(ptr, size) memset((ptr), 0, (size))
|
#define MemoryZero(ptr, size) memset((ptr), 0, (size))
|
||||||
#define MemoryZeroStruct(s) MemoryZero((s), sizeof(*(s)))
|
#define MemoryZeroStruct(s) MemoryZero((s), sizeof(*(s)))
|
||||||
|
|
||||||
|
#define MemoryMatch(a, b, size) (MemoryCompare((a), (b), (size)) == 0)
|
||||||
|
#define MemoryMatchStruct(a, b) MemoryMatch((a), (b), sizeof(*(a)))
|
||||||
|
#define MemoryMatchArray(a, b) MemoryMatch((a), (b), sizeof(a))
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Asserts
|
// Asserts
|
||||||
|
|
||||||
@@ -135,18 +141,29 @@
|
|||||||
(CheckNil(nil, (node)->next) ? (0) : ((node)->next->previous = (node)->previous)))
|
(CheckNil(nil, (node)->next) ? (0) : ((node)->next->previous = (node)->previous)))
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
// Single link double head lists (= queues)
|
||||||
|
#define SLL_queue_push_next_zero(nil, first, last, node, next) \
|
||||||
|
(CheckNil(nil, first) ? ((first) = (last) = (node), SetNil(nil, (node)->next)) \
|
||||||
|
: ((last)->next = (node), (last) = (node), SetNil(nil, (node)->next)))
|
||||||
|
|
||||||
// Single (link & head) lists (= stacks)
|
// Single (link & head) lists (= stacks)
|
||||||
#define SLL_stack_push_next(first, node, next) ((node)->next = (first), (first) = (node))
|
#define SLL_stack_push_next(first, node, next) ((node)->next = (first), (first) = (node))
|
||||||
#define SLL_stack_pop_next(first, next) ((first) = (first)->next);
|
#define SLL_stack_pop_next(first, next) ((first) = (first)->next);
|
||||||
#define SLL_stack_push(first, node) SLL_stack_push_next(first, node, next)
|
|
||||||
#define SLL_stack_pop(first) SLL_stack_pop_next(first, next)
|
|
||||||
|
|
||||||
// Double linked list helpers
|
// Double linked list helpers
|
||||||
#define DLL_push_back_next_prev(first, last, node, next, previous) \
|
#define DLL_push_back_next_prev(first, last, node, next, previous) \
|
||||||
DLL_push_back_next_prev_zero(0, first, last, node, next, previous)
|
DLL_push_back_next_prev_zero(0, first, last, node, next, previous)
|
||||||
|
#define DLL_remove_next_prev(first, last, node, next, prev) DLL_remove_next_prev_zero(0, first, last, node, next, prev)
|
||||||
#define DLL_push_back(first, last, node) DLL_push_back_next_prev_zero(0, first, last, node, next, previous)
|
#define DLL_push_back(first, last, node) DLL_push_back_next_prev_zero(0, first, last, node, next, previous)
|
||||||
#define DLL_remove(first, last, node) DLL_remove_next_prev_zero(0, first, last, node, next, previous)
|
#define DLL_remove(first, last, node) DLL_remove_next_prev_zero(0, first, last, node, next, previous)
|
||||||
|
|
||||||
|
// Queue helpers
|
||||||
|
#define SLL_queue_push(first, last, node) SLL_queue_push_next_zero(0, first, last, node, next)
|
||||||
|
|
||||||
|
// Stack helpers
|
||||||
|
#define SLL_stack_push(first, node) SLL_stack_push_next(first, node, next)
|
||||||
|
#define SLL_stack_pop(first) SLL_stack_pop_next(first, next)
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,57 @@
|
|||||||
|
#ifndef MEM_STATIC
|
||||||
|
# define MEM_STATIC
|
||||||
|
# define MEM_API static inline
|
||||||
|
# include "external/memfun/memfun.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// String conversions
|
||||||
|
|
||||||
|
internal bool32 char_is_upper(uint8 c)
|
||||||
|
{
|
||||||
|
return ('A' <= c && c <= 'Z');
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool32 char_is_lower(uint8 c)
|
||||||
|
{
|
||||||
|
return ('a' <= c && c <= 'z');
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool32 char_is_slash(uint8 c)
|
||||||
|
{
|
||||||
|
return (c == '/' || c == '\\');
|
||||||
|
}
|
||||||
|
|
||||||
|
internal uint8 lower_from_char(uint8 c)
|
||||||
|
{
|
||||||
|
if (char_is_upper(c))
|
||||||
|
{
|
||||||
|
c += ('a' - 'A');
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal uint8 upper_from_char(uint8 c)
|
||||||
|
{
|
||||||
|
if (char_is_lower(c))
|
||||||
|
{
|
||||||
|
c += ('A' - 'a');
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal uint8 correct_slash_from_char(uint8 c)
|
||||||
|
{
|
||||||
|
if (char_is_slash(c))
|
||||||
|
{
|
||||||
|
c = '/';
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
// ========================================================================== //
|
// ========================================================================== //
|
||||||
// String Length
|
// String Length
|
||||||
#include "core/core_arena.h"
|
|
||||||
internal uint64 cstring8_length(uint8* cstring)
|
internal uint64 cstring8_length(uint8* cstring)
|
||||||
{
|
{
|
||||||
uint64 length = 0;
|
uint64 length = 0;
|
||||||
@@ -85,7 +136,52 @@ internal String32 str32_cstring(uint32* cstring)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========================================================================== //
|
// =============================================================================
|
||||||
|
// String Matching
|
||||||
|
|
||||||
|
internal bool32 str8_match(String8 a, String8 b, StringMatchFlags flags)
|
||||||
|
{
|
||||||
|
bool32 result = 0;
|
||||||
|
if (a.size == b.size && flags == 0)
|
||||||
|
{
|
||||||
|
result = MemIsEqual(a.str, b.str, b.size);
|
||||||
|
}
|
||||||
|
else if (a.size == b.size && flags == StringMatchFlag_CaseInsensitive)
|
||||||
|
{
|
||||||
|
result = MemCompareI(a.str, b.str, a.size) == 0;
|
||||||
|
}
|
||||||
|
else if (a.size == b.size || (flags * StringMatchFlag_RightSideSloppy))
|
||||||
|
{
|
||||||
|
bool32 case_insensitive = (flags & StringMatchFlag_CaseInsensitive);
|
||||||
|
bool32 slash_insensitive = (flags & StringMatchFlag_SlashInsensitive);
|
||||||
|
uint64 size = Min(a.size, b.size);
|
||||||
|
result = 1;
|
||||||
|
for
|
||||||
|
EachIndex(i, size)
|
||||||
|
{
|
||||||
|
uint8 at = a.str[i];
|
||||||
|
uint8 bt = b.str[i];
|
||||||
|
if (case_insensitive)
|
||||||
|
{
|
||||||
|
at = upper_from_char(at);
|
||||||
|
bt = upper_from_char(bt);
|
||||||
|
}
|
||||||
|
if (slash_insensitive)
|
||||||
|
{
|
||||||
|
at = correct_slash_from_char(at);
|
||||||
|
bt = correct_slash_from_char(bt);
|
||||||
|
}
|
||||||
|
if (at != bt)
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
// String Formatting & Copying
|
// String Formatting & Copying
|
||||||
|
|
||||||
internal String8 str8_copy(Arena* arena, String8 in)
|
internal String8 str8_copy(Arena* arena, String8 in)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// ========================================================================== //
|
// =============================================================================
|
||||||
// String Types
|
// String Types
|
||||||
|
|
||||||
typedef struct String8 String8;
|
typedef struct String8 String8;
|
||||||
@@ -24,7 +24,18 @@ struct String32
|
|||||||
uint64 size;
|
uint64 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========================================================================== //
|
// =============================================================================
|
||||||
|
// String Matching Types
|
||||||
|
|
||||||
|
typedef uint32 StringMatchFlags;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
StringMatchFlag_CaseInsensitive = (1 << 0),
|
||||||
|
StringMatchFlag_RightSideSloppy = (1 << 1),
|
||||||
|
StringMatchFlag_SlashInsensitive = (1 << 2),
|
||||||
|
};
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
// Unicode decoding Types
|
// Unicode decoding Types
|
||||||
|
|
||||||
typedef struct UnicodeDecode UnicodeDecode;
|
typedef struct UnicodeDecode UnicodeDecode;
|
||||||
@@ -34,13 +45,24 @@ struct UnicodeDecode
|
|||||||
uint32 codepoint;
|
uint32 codepoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========================================================================== //
|
// =============================================================================
|
||||||
|
// String conversions
|
||||||
|
|
||||||
|
internal bool32 char_is_upper(uint8 c);
|
||||||
|
internal bool32 char_is_lower(uint8 c);
|
||||||
|
internal bool32 char_is_slash(uint8 c);
|
||||||
|
internal uint8 lower_from_char(uint8 c);
|
||||||
|
internal uint8 upper_from_char(uint8 c);
|
||||||
|
internal uint8 correct_slash_from_char(uint8 c);
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
// String Length
|
// String Length
|
||||||
|
|
||||||
internal uint64 cstring8_length(uint8* cstring);
|
internal uint64 cstring8_length(uint8* cstring);
|
||||||
internal uint64 cstring16_length(uint16* cstring);
|
internal uint64 cstring16_length(uint16* cstring);
|
||||||
internal uint64 cstring32_length(uint32* cstring);
|
internal uint64 cstring32_length(uint32* cstring);
|
||||||
|
|
||||||
// ========================================================================== //
|
// =============================================================================
|
||||||
// String Constructor
|
// String Constructor
|
||||||
|
|
||||||
#define str8_literal(S) str8((uint8*)(S), sizeof(S) - 1)
|
#define str8_literal(S) str8((uint8*)(S), sizeof(S) - 1)
|
||||||
@@ -55,13 +77,19 @@ internal String8 str8_cstring(const char* cstring);
|
|||||||
internal String16 str16_cstring(uint16* cstring);
|
internal String16 str16_cstring(uint16* cstring);
|
||||||
internal String32 str32_cstring(uint32* cstring);
|
internal String32 str32_cstring(uint32* cstring);
|
||||||
|
|
||||||
// ========================================================================== //
|
// =============================================================================
|
||||||
|
// String Matching
|
||||||
|
|
||||||
|
internal bool32 str8_match(String8 a, String8 b, StringMatchFlags flags);
|
||||||
|
#define str8_matchi(a, b) str8_match(a, b, StringMatchFlag_CaseInsensitive)
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
// String Formatting & Copying
|
// String Formatting & Copying
|
||||||
|
|
||||||
internal String8 str8_copy(Arena* arena, String8 in);
|
internal String8 str8_copy(Arena* arena, String8 in);
|
||||||
internal String8 str8fv(Arena* arena, char* fmt, va_list args);
|
internal String8 str8fv(Arena* arena, char* fmt, va_list args);
|
||||||
|
|
||||||
// ========================================================================== //
|
// =============================================================================
|
||||||
// Unicode String Encode/Decode
|
// Unicode String Encode/Decode
|
||||||
|
|
||||||
internal UnicodeDecode utf8_decode(uint8* str, uint64 max);
|
internal UnicodeDecode utf8_decode(uint8* str, uint64 max);
|
||||||
@@ -69,7 +97,7 @@ internal UnicodeDecode utf16_decode(uint16* str, uint64 max);
|
|||||||
internal uint32 utf8_encode(uint8* str, uint32 codepoint);
|
internal uint32 utf8_encode(uint8* str, uint32 codepoint);
|
||||||
internal uint32 utf16_encode(uint16* str, uint32 codepoint);
|
internal uint32 utf16_encode(uint16* str, uint32 codepoint);
|
||||||
|
|
||||||
// ========================================================================== //
|
// =============================================================================
|
||||||
// Unicode String Conversions
|
// Unicode String Conversions
|
||||||
|
|
||||||
internal String8 str8_from_16(Arena* arena, String16 in);
|
internal String8 str8_from_16(Arena* arena, String16 in);
|
||||||
|
|||||||
Vendored
+4285
File diff suppressed because it is too large.
Load diff
@@ -56,13 +56,36 @@ internal void ja_frame()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Window Garbage collect
|
||||||
|
{
|
||||||
|
for
|
||||||
|
EachIndex(slot_idx, ja_state->window_state_slots_count)
|
||||||
|
{
|
||||||
|
for (JA_WindowState *ws = ja_state->window_state_slots[slot_idx].first, *next; ws != 0; ws = next)
|
||||||
|
{
|
||||||
|
next = ws->hash_next;
|
||||||
|
// TODO : need to be able to gc a closed window. Right now we only know number of window using
|
||||||
|
// the gen id, but we must do better. No need to save opened window in config so leaner version is ok
|
||||||
|
if (ja_state->quit)
|
||||||
|
{
|
||||||
|
wm_window_close(ws->plat_handle);
|
||||||
|
arena_release(ws->arena);
|
||||||
|
DLL_remove_next_prev_zero(&ja_nil_window_state, ja_state->first_window_state,
|
||||||
|
ja_state->last_window_state, ws, order_next, order_previous);
|
||||||
|
DLL_remove_next_prev(ja_state->window_state_slots[slot_idx].first,
|
||||||
|
ja_state->window_state_slots[slot_idx].last, ws, hash_next, hash_previous);
|
||||||
|
SLL_stack_push_next(ja_state->free_window_state, ws, order_next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ja_shutdown()
|
internal void ja_shutdown()
|
||||||
{
|
{
|
||||||
// wm_window_close(aaa);
|
arena_release(ja_state->arena);
|
||||||
arena_clear(ja_state->arena);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -117,5 +140,42 @@ internal JA_WindowState* ja_window_state_from_id(JA_ID id)
|
|||||||
DLL_push_back_next_prev(slot->first, slot->last, ws, hash_next, hash_previous);
|
DLL_push_back_next_prev(slot->first, slot->last, ws, hash_next, hash_previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ws != &ja_nil_window_state && wm_window_match(ws->plat_handle, wm_window_zero()))
|
||||||
|
{
|
||||||
|
TempArena scratch = scratch_begin(0, 0);
|
||||||
|
|
||||||
|
// TODO: save fav monitor in config
|
||||||
|
WM_Monitor prim_m = wm_primary_monitor();
|
||||||
|
String8 prim_name = wm_name_from_monitor(scratch.arena, prim_m);
|
||||||
|
|
||||||
|
WM_Monitor fav_monitor = { 0 };
|
||||||
|
{
|
||||||
|
WM_MonitorArray monitors = wm_push_monitors_array(scratch.arena);
|
||||||
|
for
|
||||||
|
EachIndex(idx, monitors.count)
|
||||||
|
{
|
||||||
|
String8 monitor_name = wm_name_from_monitor(scratch.arena, monitors.ptr[idx]);
|
||||||
|
if (str8_match(monitor_name, prim_name, StringMatchFlag_CaseInsensitive))
|
||||||
|
{
|
||||||
|
fav_monitor = monitors.ptr[idx];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO : put those in config, hardcoded for now
|
||||||
|
String8 title = str8_literal("Juliet");
|
||||||
|
ws->plat_handle = wm_window_open(rect2fp(50.f, 240.f, 1280.f, 720.f), WM_WindowFlag_UseDefaultPosition, title);
|
||||||
|
WM_Monitor zero_monitor = { 0 };
|
||||||
|
if (!wm_monitor_match(zero_monitor, fav_monitor))
|
||||||
|
{
|
||||||
|
wm_window_set_monitor(ws->plat_handle, fav_monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
scratch_end(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
ja_state->window_state_last_accessed_id = ws->id;
|
||||||
|
ja_state->window_state_last_accessed = ws;
|
||||||
return ws;
|
return ws;
|
||||||
}
|
}
|
||||||
@@ -79,6 +79,14 @@ internal W32_WM_Window* w32_wm_window_alloc(HWND hwnd)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal WM_Event* w32_wm_push_event(WM_EventKind kind, W32_WM_Window* window)
|
||||||
|
{
|
||||||
|
WM_Event* result = 0;
|
||||||
|
result->window = w32_wm_handle_from_window(window);
|
||||||
|
result->modifiers = wm_get_modifiers();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
internal void w32_wm_window_release(W32_WM_Window* window)
|
internal void w32_wm_window_release(W32_WM_Window* window)
|
||||||
{
|
{
|
||||||
if (window->paint_arena != 0)
|
if (window->paint_arena != 0)
|
||||||
@@ -91,14 +99,23 @@ internal void w32_wm_window_release(W32_WM_Window* window)
|
|||||||
SLL_stack_push(w32_wm_state->free_window, window);
|
SLL_stack_push(w32_wm_state->free_window, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal WM_Event* w32_wm_push_event(WM_EventKind kind, W32_WM_Window* window)
|
// =============================================================================
|
||||||
|
// Monitors
|
||||||
|
|
||||||
|
internal BOOL w32_wm_monitor_gather_enum_proc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM bundle_ptr)
|
||||||
{
|
{
|
||||||
WM_Event* result = 0;
|
W32_WM_MonitorGatherBundle* bundle = (W32_WM_MonitorGatherBundle*)bundle_ptr;
|
||||||
result->window = w32_wm_handle_from_window(window);
|
WM_Monitor m = { (uint64)monitor };
|
||||||
result->modifiers = wm_get_modifiers();
|
W32_WM_MonitorGatherNode* node = push_array(bundle->arena, W32_WM_MonitorGatherNode, 1);
|
||||||
return result;
|
node->handle = m;
|
||||||
|
SLL_queue_push(bundle->first_monitor, bundle->last_monitor, node);
|
||||||
|
bundle->monitor_count += 1;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// w32 windows proc
|
||||||
|
|
||||||
internal LRESULT w32_wm_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
internal LRESULT w32_wm_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
LRESULT result = 0;
|
LRESULT result = 0;
|
||||||
@@ -508,6 +525,37 @@ internal void wm_window_first_paint(WM_Window window_handle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void wm_window_set_monitor(WM_Window window_handle, WM_Monitor monitor)
|
||||||
|
{
|
||||||
|
W32_WM_Window* window = w32_wm_window_from_handle(window_handle);
|
||||||
|
if (window != 0)
|
||||||
|
{
|
||||||
|
HMONITOR hmonitor = (HMONITOR)monitor.handle[0];
|
||||||
|
MONITORINFOEXW info;
|
||||||
|
info.cbSize = sizeof(MONITORINFOEXW);
|
||||||
|
if (GetMonitorInfoW(hmonitor, (MONITORINFO*)&info))
|
||||||
|
{
|
||||||
|
Rect2f existing_rect = wm_rect_from_window(window_handle);
|
||||||
|
Vector2f window_size = dimension_2f(existing_rect);
|
||||||
|
SetWindowPos(window->hwnd, HWND_TOP, (info.rcWork.left + info.rcWork.right) / 2 - window_size.x / 2,
|
||||||
|
(info.rcWork.top + info.rcWork.bottom) / 2 - window_size.y / 2, window_size.x, window_size.y, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Rect2f wm_rect_from_window(WM_Window window_handle)
|
||||||
|
{
|
||||||
|
Rect2f r = { 0 };
|
||||||
|
W32_WM_Window* window = w32_wm_window_from_handle(window_handle);
|
||||||
|
if (window != 0)
|
||||||
|
{
|
||||||
|
RECT rect = { 0 };
|
||||||
|
GetWindowRect(w32_wm_hwnd_from_window(window), &rect);
|
||||||
|
r = w32_wm_rect2f_from_rect(rect);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
internal Rect2f wm_client_rect_from_window(WM_Window handle)
|
internal Rect2f wm_client_rect_from_window(WM_Window handle)
|
||||||
{
|
{
|
||||||
Rect2f result = { 0 };
|
Rect2f result = { 0 };
|
||||||
@@ -521,6 +569,93 @@ internal Rect2f wm_client_rect_from_window(WM_Window handle)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Monitors
|
||||||
|
|
||||||
|
internal WM_MonitorArray wm_push_monitors_array(Arena* arena)
|
||||||
|
{
|
||||||
|
TempArena scratch = scratch_begin(&arena, 1);
|
||||||
|
|
||||||
|
W32_WM_MonitorGatherBundle bundle = { arena };
|
||||||
|
EnumDisplayMonitors(0, 0, w32_wm_monitor_gather_enum_proc, (LPARAM)&bundle);
|
||||||
|
WM_MonitorArray array = { 0 };
|
||||||
|
array.count = bundle.monitor_count;
|
||||||
|
array.ptr = push_array(arena, WM_Monitor, array.count);
|
||||||
|
{
|
||||||
|
uint64 idx = 0;
|
||||||
|
for
|
||||||
|
EachNode(node, W32_WM_MonitorGatherNode, bundle.first_monitor)
|
||||||
|
{
|
||||||
|
array.ptr[idx] = node->handle;
|
||||||
|
idx += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scratch_end(scratch);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal WM_Monitor wm_primary_monitor()
|
||||||
|
{
|
||||||
|
POINT zero_pt = { 0, 0 };
|
||||||
|
HMONITOR monitor = MonitorFromPoint(zero_pt, MONITOR_DEFAULTTOPRIMARY);
|
||||||
|
WM_Monitor result = { (uint64)monitor };
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal WM_Monitor wm_monitor_from_window(WM_Window window)
|
||||||
|
{
|
||||||
|
W32_WM_Window* w = w32_wm_window_from_handle(window);
|
||||||
|
WM_Monitor result = { 0 };
|
||||||
|
if (w != 0)
|
||||||
|
{
|
||||||
|
HMONITOR handle = MonitorFromWindow(w->hwnd, MONITOR_DEFAULTTOPRIMARY);
|
||||||
|
result.handle[0] = (uint64)handle;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal String8 wm_name_from_monitor(Arena* arena, WM_Monitor monitor)
|
||||||
|
{
|
||||||
|
String8 result = { 0 };
|
||||||
|
HMONITOR monitor_handle = (HMONITOR)monitor.handle[0];
|
||||||
|
MONITORINFOEXW info;
|
||||||
|
info.cbSize = sizeof(MONITORINFOEXW);
|
||||||
|
if (GetMonitorInfoW(monitor_handle, (MONITORINFO*)&info))
|
||||||
|
{
|
||||||
|
String16 result16 = str16_cstring((uint16*)info.szDevice);
|
||||||
|
result = str8_from_16(arena, result16);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Vector2f wm_dim_from_monitor(WM_Monitor monitor)
|
||||||
|
{
|
||||||
|
Vector2f result = { 0 };
|
||||||
|
HMONITOR monitor_handle = (HMONITOR)monitor.handle[0];
|
||||||
|
MONITORINFO info;
|
||||||
|
info.cbSize = sizeof(MONITORINFO);
|
||||||
|
if (GetMonitorInfoW(monitor_handle, &info))
|
||||||
|
{
|
||||||
|
result.x = info.rcWork.right - info.rcWork.left;
|
||||||
|
result.y = info.rcWork.bottom - info.rcWork.top;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal float32 wm_dpi_from_monitor(WM_Monitor monitor)
|
||||||
|
{
|
||||||
|
float32 result = 96.f;
|
||||||
|
HMONITOR monitor_handle = (HMONITOR)monitor.handle[0];
|
||||||
|
if (w32_GetDpiForMonitor_func != 0)
|
||||||
|
{
|
||||||
|
UINT dpi_x = 0;
|
||||||
|
UINT dpi_y = 0;
|
||||||
|
HRESULT hr = w32_GetDpiForMonitor_func(monitor_handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y);
|
||||||
|
result = (float32)dpi_x;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Events
|
// Events
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,25 @@ struct W32_WM_Window
|
|||||||
Arena* paint_arena;
|
Arena* paint_arena;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Monitor gathering bundle
|
||||||
|
|
||||||
|
typedef struct W32_WM_MonitorGatherNode W32_WM_MonitorGatherNode;
|
||||||
|
struct W32_WM_MonitorGatherNode
|
||||||
|
{
|
||||||
|
W32_WM_MonitorGatherNode* next;
|
||||||
|
WM_Monitor handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct W32_WM_MonitorGatherBundle W32_WM_MonitorGatherBundle;
|
||||||
|
struct W32_WM_MonitorGatherBundle
|
||||||
|
{
|
||||||
|
Arena* arena;
|
||||||
|
W32_WM_MonitorGatherNode* first_monitor;
|
||||||
|
W32_WM_MonitorGatherNode* last_monitor;
|
||||||
|
uint64 monitor_count;
|
||||||
|
};
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Windows Global State
|
// Windows Global State
|
||||||
|
|
||||||
@@ -68,3 +87,8 @@ internal HWND w32_wm_hwnd_from_window(W32_WM_Window* window);
|
|||||||
internal W32_WM_Window* w32_wm_window_alloc(HWND hwnd);
|
internal W32_WM_Window* w32_wm_window_alloc(HWND hwnd);
|
||||||
internal WM_Event* w32_wm_push_event(WM_EventKind kind, W32_WM_Window* window);
|
internal WM_Event* w32_wm_push_event(WM_EventKind kind, W32_WM_Window* window);
|
||||||
internal void w32_wm_window_release(W32_WM_Window* window);
|
internal void w32_wm_window_release(W32_WM_Window* window);
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Monitors
|
||||||
|
|
||||||
|
internal BOOL w32_wm_monitor_gather_enum_proc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM bundle_ptr);
|
||||||
@@ -1,3 +1,24 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// Handle type helpers
|
||||||
|
|
||||||
|
internal WM_Window wm_window_zero()
|
||||||
|
{
|
||||||
|
WM_Window result = { 0 };
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool32 wm_window_match(WM_Window a, WM_Window b)
|
||||||
|
{
|
||||||
|
bool32 result = MemoryMatchStruct(&a, &b);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool32 wm_monitor_match(WM_Monitor a, WM_Monitor b)
|
||||||
|
{
|
||||||
|
bool32 result = MemoryMatchStruct(&a, &b);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Event Functions
|
// Event Functions
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,13 @@ struct WM_EventList
|
|||||||
|
|
||||||
internal bool32 frame();
|
internal bool32 frame();
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Handle type helpers
|
||||||
|
|
||||||
|
internal WM_Window wm_window_zero();
|
||||||
|
internal bool32 wm_window_match(WM_Window a, WM_Window b);
|
||||||
|
internal bool32 wm_monitor_match(WM_Monitor a, WM_Monitor b);
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Event Functions
|
// Event Functions
|
||||||
|
|
||||||
@@ -119,8 +126,20 @@ internal void wm_init();
|
|||||||
internal WM_Window wm_widow_open(Rect2f rect, WM_WindowFlags flags, String8 title);
|
internal WM_Window wm_widow_open(Rect2f rect, WM_WindowFlags flags, String8 title);
|
||||||
internal void wm_window_close(WM_Window handle);
|
internal void wm_window_close(WM_Window handle);
|
||||||
internal void wm_window_first_paint(WM_Window window_handle);
|
internal void wm_window_first_paint(WM_Window window_handle);
|
||||||
|
internal void wm_window_set_monitor(WM_Window window, WM_Monitor monitor);
|
||||||
|
internal Rect2f wm_rect_from_window(WM_Window window_handle);
|
||||||
internal Rect2f wm_client_rect_from_window(WM_Window window);
|
internal Rect2f wm_client_rect_from_window(WM_Window window);
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Monitors
|
||||||
|
|
||||||
|
internal WM_MonitorArray wm_push_monitors_array(Arena* arena);
|
||||||
|
internal WM_Monitor wm_primary_monitor();
|
||||||
|
internal WM_Monitor wm_monitor_from_window(WM_Window window);
|
||||||
|
internal String8 wm_name_from_monitor(Arena* arena, WM_Monitor monitor);
|
||||||
|
internal Vector2f wm_dim_from_monitor(WM_Monitor monitor);
|
||||||
|
internal float32 wm_dpi_from_monitor(WM_Monitor monitor);
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Events
|
// Events
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user