open window code still not opening :)
This commit is contained in:
1 parent
886e722c71
commit
4ec42f4bee
11 files changed
+559
-4
No files matched your search
@@ -15,10 +15,26 @@
|
||||
|
||||
internal bool32 frame()
|
||||
{
|
||||
{
|
||||
TempArena scratch = scratch_begin(0, 0);
|
||||
|
||||
WM_EventList events = { 0 };
|
||||
bool32 wait = 0;
|
||||
events = wm_get_events(scratch.arena, wait);
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void entry_point()
|
||||
{
|
||||
wm_init();
|
||||
|
||||
wm_window_open(rect2fp(50.f, 50.f, 1280.f, 720.f), 0, str8_literal("Hello"));
|
||||
|
||||
for (bool32 quit = 0; !quit;)
|
||||
{
|
||||
quit = update();
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#define internal static
|
||||
#define global static
|
||||
#define local_persist static
|
||||
|
||||
#if (COMPILER_CLANG && OS_WINDOWS) || COMPILER_MSVC
|
||||
# pragma section(".rdata$", read)
|
||||
@@ -76,6 +77,7 @@
|
||||
#define MemorySet(dst, src, size) memset((dst), (src), (size))
|
||||
|
||||
#define MemoryZero(ptr, size) memset((ptr), 0, (size))
|
||||
#define MemoryZeroStruct(s) MemoryZero((s), sizeof(*(s)))
|
||||
|
||||
// =============================================================================
|
||||
// Asserts
|
||||
@@ -122,13 +124,20 @@
|
||||
// clang-format on
|
||||
#define DLL_push_back_NPZ(nil, first, last, node, next, previous) \
|
||||
DLL_insert_NPZ(nil, first, last, last, node, next, previous)
|
||||
#define DLL_remove_NPZ(nil, first, last, node, next, previous) \
|
||||
(((node) == (first) ? (first) = (node)->next : (0)), ((node) == (last) ? (last) = (last)->previous : (0)), \
|
||||
(CheckNil(nil, (node)->previous) ? (0) : ((node)->previous->next = (node)->next)), \
|
||||
(CheckNil(nil, (node)->next) ? (0) : ((node)->next->previous = (node)->previous)))
|
||||
|
||||
// Single (link & head) lists (= stacks)
|
||||
#define SLL_stack_push_node(first, node, next) ((node)->next = (first), (first) = (node))
|
||||
#define SLL_stack_pop_node(first, next) ((first) = (first)->next);
|
||||
#define SLL_stack_push(first, node) SLL_stack_push_node(first, node, next)
|
||||
#define SLL_stack_pop(first) SLL_stack_pop_node(first, next)
|
||||
|
||||
// Double linked list helpers
|
||||
#define DLL_push_back(first, last, node) DLL_push_back_NPZ(0, first, last, node, next, previous)
|
||||
#define DLL_remove(first, last, node) DLL_remove_NPZ(0, first, last, node, next, previous)
|
||||
|
||||
// =============================================================================
|
||||
// Helpers
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "core.c"
|
||||
#include "core_memory.c"
|
||||
#include "core_arena.c"
|
||||
#include "core_math.c"
|
||||
#include "core_string.c"
|
||||
#include "core_system.c"
|
||||
#include "core_threads.c"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "core_memory.h"
|
||||
#include "core_processes.h"
|
||||
#include "core_arena.h"
|
||||
#include "core_math.h"
|
||||
#include "core_string.h"
|
||||
#include "core_system.h"
|
||||
#include "core_threads.h"
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// =============================================================================
|
||||
// Functions
|
||||
|
||||
// =============================================================================
|
||||
// Vectors
|
||||
|
||||
internal Vector2f vector_2f(float32 x, float32 y)
|
||||
{
|
||||
Vector2f v = { x, y };
|
||||
return v;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Rectangles
|
||||
|
||||
internal Rect2f rect_2f(Vector2f min, Vector2f max)
|
||||
{
|
||||
Rect2f rect = { min, max };
|
||||
return rect;
|
||||
}
|
||||
|
||||
internal bool32 contains_2f(Rect2f rect, Vector2f x)
|
||||
{
|
||||
bool32 cond = (rect.min.x <= x.x && x.x < rect.max.x && rect.min.y <= x.y && x.y < rect.max.y);
|
||||
return cond;
|
||||
}
|
||||
|
||||
internal Vector2f dimension_2f(Rect2f rect)
|
||||
{
|
||||
Vector2f dim = { ((rect.max.x > rect.min.x) ? (rect.max.x - rect.min.x) : 0),
|
||||
((rect.max.y > rect.min.y) ? (rect.max.y - rect.min.y) : 0) };
|
||||
return dim;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
// =============================================================================
|
||||
// Vector Types
|
||||
|
||||
typedef union Vector2f Vector2f;
|
||||
union Vector2f
|
||||
{
|
||||
struct
|
||||
{
|
||||
float32 x;
|
||||
float32 y;
|
||||
};
|
||||
float32 v[2];
|
||||
};
|
||||
|
||||
// =============================================================================
|
||||
// Rect Types
|
||||
|
||||
typedef union Rect2f Rect2f;
|
||||
union Rect2f
|
||||
{
|
||||
struct
|
||||
{
|
||||
Vector2f min;
|
||||
Vector2f max;
|
||||
};
|
||||
struct
|
||||
{
|
||||
Vector2f p0;
|
||||
Vector2f p1;
|
||||
};
|
||||
struct
|
||||
{
|
||||
float32 x0;
|
||||
float32 y0;
|
||||
float32 x1;
|
||||
float32 y1;
|
||||
};
|
||||
Vector2f v[2];
|
||||
};
|
||||
|
||||
// =============================================================================
|
||||
// Functions
|
||||
|
||||
// =============================================================================
|
||||
// Vectors
|
||||
|
||||
#define vector2f(x, y) vector_2f((x), (y))
|
||||
internal Vector2f vector_2f(float32 x, float32 y);
|
||||
|
||||
// =============================================================================
|
||||
// Rectangles
|
||||
|
||||
#define rect2f(min, max) rect_2f((min), (max))
|
||||
#define rect2fp(x, y, z, w) rect2f(vector2f((x), (y)), vector2f((z), (w)))
|
||||
internal Rect2f rect_2f(Vector2f min, Vector2f max);
|
||||
internal bool32 contains_2f(Rect2f rect, Vector2f x);
|
||||
internal Vector2f dimension_2f(Rect2f rect);
|
||||
@@ -43,6 +43,7 @@ internal uint64 cstring32_length(uint32* cstring);
|
||||
// ========================================================================== //
|
||||
// String Constructor
|
||||
|
||||
#define str8_literal(S) str8((uint8*)(S), sizeof(S) - 1)
|
||||
internal String8 str8(uint8* str, uint64 size);
|
||||
internal String8 str8_zero();
|
||||
internal String16 str16(uint16* str, uint64 size);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#pragma comment(lib, "user32")
|
||||
#pragma comment(lib, "shell32")
|
||||
// clang-format on
|
||||
|
||||
typedef struct W32_State W32_State;
|
||||
|
||||
@@ -8,6 +8,19 @@ global w32_GetDpiForWindow_Type* w32_GetDpiForWindow_func = 0;
|
||||
global w32_GetDpiForMonitor_Type* w32_GetDpiForMonitor_func = 0;
|
||||
global w32_GetSystemMetricsForDpi_Type* w32_GetSystemMetricsForDpi_func = 0;
|
||||
|
||||
// =============================================================================
|
||||
// Helpers
|
||||
|
||||
internal Rect2f w32_wm_rect2f_from_rect(RECT rect)
|
||||
{
|
||||
Rect2f result = { 0 };
|
||||
result.x0 = (float32)rect.left;
|
||||
result.x1 = (float32)rect.right;
|
||||
result.y0 = (float32)rect.top;
|
||||
result.y1 = (float32)rect.bottom;
|
||||
return result;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Windows
|
||||
|
||||
@@ -37,6 +50,47 @@ internal W32_WM_Window* w32_wm_window_from_hwnd(HWND hwnd)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal HWND w32_wm_hwnd_from_window(W32_WM_Window* window)
|
||||
{
|
||||
return window->hwnd;
|
||||
}
|
||||
|
||||
internal W32_WM_Window* w32_wm_window_alloc(HWND hwnd)
|
||||
{
|
||||
W32_WM_Window* result = w32_wm_state->free_window;
|
||||
if (result)
|
||||
{
|
||||
SLL_stack_pop(w32_wm_state->free_window);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = push_array_no_zero(w32_wm_state->arena, W32_WM_Window, 1);
|
||||
}
|
||||
MemoryZeroStruct(result);
|
||||
if (result)
|
||||
{
|
||||
DLL_push_back(w32_wm_state->first_window, w32_wm_state->last_window, result);
|
||||
}
|
||||
result->last_window_placement.length = sizeof(WINDOWPLACEMENT);
|
||||
|
||||
result->hwnd = hwnd;
|
||||
result->hdc = GetDC(hwnd);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void w32_wm_window_release(W32_WM_Window* window)
|
||||
{
|
||||
if (window->paint_arena != 0)
|
||||
{
|
||||
arena_release(window->paint_arena);
|
||||
}
|
||||
ReleaseDC(window->hwnd, window->hdc);
|
||||
DestroyWindow(window->hwnd);
|
||||
DLL_remove(w32_wm_state->first_window, w32_wm_state->last_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)
|
||||
{
|
||||
WM_Event* result = 0;
|
||||
@@ -94,6 +148,85 @@ internal LRESULT w32_wm_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPa
|
||||
case WM_CLOSE:
|
||||
{
|
||||
w32_wm_push_event(WM_EventKind_WindowClose, window);
|
||||
wm_send_wakeup_event();
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SETCURSOR:
|
||||
{
|
||||
Rect2f window_rect = wm_client_rect_from_window(window_handle);
|
||||
Vector2f mouse = wm_mouse_from_window(window_handle);
|
||||
bool32 on_border = 0;
|
||||
DWORD window_style = window ? GetWindowLong(window->hwnd, GWL_STYLE) : 0;
|
||||
bool32 is_fullscreen = !(window_style & WS_OVERLAPPEDWINDOW);
|
||||
if (window != 0 && window->custom_border && !is_fullscreen)
|
||||
{
|
||||
bool32 on_border_x = (mouse.x <= window->custom_border_edge_thickness ||
|
||||
window_rect.x1 - window->custom_border_edge_thickness <= mouse.x);
|
||||
bool32 on_border_y = (mouse.y <= window->custom_border_edge_thickness ||
|
||||
window_rect.y1 - window->custom_border_edge_thickness <= mouse.y);
|
||||
on_border = on_border_x || on_border_y;
|
||||
}
|
||||
if (!w32_wm_resizing && !on_border && contains_2f(window_rect, mouse))
|
||||
{
|
||||
SetCursor(w32_wm_state->hCursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DPICHANGED:
|
||||
{
|
||||
float32 new_dpi = (float32)(wParam & 0xFFFF);
|
||||
RECT suggested_new_rect = *(RECT*)lParam;
|
||||
window->dpi = new_dpi;
|
||||
SetWindowPos(window->hwnd, 0, suggested_new_rect.left, suggested_new_rect.top,
|
||||
suggested_new_rect.right - suggested_new_rect.left,
|
||||
suggested_new_rect.bottom - suggested_new_rect.top, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_NCPAINT:
|
||||
{
|
||||
if (w32_wm_new_window_custom_border || (window != 0 && window->custom_border && !window->custom_border_composition_enabled))
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DWMCOMPOSITIONCHANGED:
|
||||
{
|
||||
if (window != 0 && window->custom_border)
|
||||
{
|
||||
BOOL enabled = 0;
|
||||
DwmIsCompositionEnabled(&enabled);
|
||||
window->custom_border_composition_enabled = enabled;
|
||||
if (enabled)
|
||||
{
|
||||
MARGINS m = { 0, 0, 1, 0 };
|
||||
DwmExtendFrameIntoClientArea(hwnd, &m);
|
||||
DWORD dwmncrp_enabled = DWMNCRP_ENABLED;
|
||||
DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &enabled, sizeof(dwmncrp_enabled));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -165,6 +298,207 @@ internal void wm_init()
|
||||
{
|
||||
w32_wm_state->gfx_info.default_refresh_rate = (float32)devmodew.dmDisplayFrequency;
|
||||
}
|
||||
|
||||
// initial cursor
|
||||
wm_set_cursor(WM_Cursor_Pointer);
|
||||
|
||||
// fill the vkey to wmKey table
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'A'] = WM_Key_A;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'B'] = WM_Key_B;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'C'] = WM_Key_C;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'D'] = WM_Key_D;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'E'] = WM_Key_E;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'F'] = WM_Key_F;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'G'] = WM_Key_G;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'H'] = WM_Key_H;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'I'] = WM_Key_I;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'J'] = WM_Key_J;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'K'] = WM_Key_K;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'L'] = WM_Key_L;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'M'] = WM_Key_M;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'N'] = WM_Key_N;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'O'] = WM_Key_O;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'P'] = WM_Key_P;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'Q'] = WM_Key_Q;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'R'] = WM_Key_R;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'S'] = WM_Key_S;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'T'] = WM_Key_T;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'U'] = WM_Key_U;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'V'] = WM_Key_V;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'W'] = WM_Key_W;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'X'] = WM_Key_X;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'Y'] = WM_Key_Y;
|
||||
w32_wm_state->key_from_vkey_table[(unsigned int)'Z'] = WM_Key_Z;
|
||||
|
||||
// Num
|
||||
for (uint64 i = '0', j = WM_Key_0; i <= '9'; ++i, ++j)
|
||||
{
|
||||
w32_wm_state->key_from_vkey_table[i] = (WM_Key)j;
|
||||
}
|
||||
// Numpad num
|
||||
for (uint64 i = VK_NUMPAD0, j = WM_Key_Num0; i <= VK_NUMPAD9; ++i, ++j)
|
||||
{
|
||||
w32_wm_state->key_from_vkey_table[i] = (WM_Key)j;
|
||||
}
|
||||
// F1-24
|
||||
for (uint64 i = VK_F1, j = WM_Key_F1; i <= VK_F24; ++i, ++j)
|
||||
{
|
||||
w32_wm_state->key_from_vkey_table[i] = (WM_Key)j;
|
||||
}
|
||||
|
||||
// Other keys
|
||||
w32_wm_state->key_from_vkey_table[VK_SPACE] = WM_Key_Space;
|
||||
w32_wm_state->key_from_vkey_table[VK_OEM_3] = WM_Key_Tick;
|
||||
w32_wm_state->key_from_vkey_table[VK_OEM_MINUS] = WM_Key_Minus;
|
||||
w32_wm_state->key_from_vkey_table[VK_OEM_PLUS] = WM_Key_Equal;
|
||||
w32_wm_state->key_from_vkey_table[VK_OEM_4] = WM_Key_LeftBracket;
|
||||
w32_wm_state->key_from_vkey_table[VK_OEM_6] = WM_Key_RightBracket;
|
||||
w32_wm_state->key_from_vkey_table[VK_OEM_1] = WM_Key_Semicolon;
|
||||
w32_wm_state->key_from_vkey_table[VK_OEM_7] = WM_Key_Quote;
|
||||
w32_wm_state->key_from_vkey_table[VK_OEM_COMMA] = WM_Key_Comma;
|
||||
w32_wm_state->key_from_vkey_table[VK_OEM_PERIOD] = WM_Key_Period;
|
||||
w32_wm_state->key_from_vkey_table[VK_OEM_2] = WM_Key_Slash;
|
||||
w32_wm_state->key_from_vkey_table[VK_OEM_5] = WM_Key_BackSlash;
|
||||
|
||||
w32_wm_state->key_from_vkey_table[VK_TAB] = WM_Key_Tab;
|
||||
w32_wm_state->key_from_vkey_table[VK_PAUSE] = WM_Key_Pause;
|
||||
w32_wm_state->key_from_vkey_table[VK_ESCAPE] = WM_Key_Esc;
|
||||
|
||||
w32_wm_state->key_from_vkey_table[VK_UP] = WM_Key_Up;
|
||||
w32_wm_state->key_from_vkey_table[VK_LEFT] = WM_Key_Left;
|
||||
w32_wm_state->key_from_vkey_table[VK_DOWN] = WM_Key_Down;
|
||||
w32_wm_state->key_from_vkey_table[VK_RIGHT] = WM_Key_Right;
|
||||
|
||||
w32_wm_state->key_from_vkey_table[VK_BACK] = WM_Key_Backspace;
|
||||
w32_wm_state->key_from_vkey_table[VK_RETURN] = WM_Key_Return;
|
||||
|
||||
w32_wm_state->key_from_vkey_table[VK_DELETE] = WM_Key_Delete;
|
||||
w32_wm_state->key_from_vkey_table[VK_INSERT] = WM_Key_Insert;
|
||||
w32_wm_state->key_from_vkey_table[VK_PRIOR] = WM_Key_PageUp;
|
||||
w32_wm_state->key_from_vkey_table[VK_NEXT] = WM_Key_PageDown;
|
||||
w32_wm_state->key_from_vkey_table[VK_HOME] = WM_Key_Home;
|
||||
w32_wm_state->key_from_vkey_table[VK_END] = WM_Key_End;
|
||||
|
||||
w32_wm_state->key_from_vkey_table[VK_CAPITAL] = WM_Key_CapsLock;
|
||||
w32_wm_state->key_from_vkey_table[VK_NUMLOCK] = WM_Key_NumLock;
|
||||
w32_wm_state->key_from_vkey_table[VK_SCROLL] = WM_Key_ScrollLock;
|
||||
w32_wm_state->key_from_vkey_table[VK_APPS] = WM_Key_Menu;
|
||||
|
||||
w32_wm_state->key_from_vkey_table[VK_CONTROL] = WM_Key_Ctrl;
|
||||
w32_wm_state->key_from_vkey_table[VK_LCONTROL] = WM_Key_Ctrl;
|
||||
w32_wm_state->key_from_vkey_table[VK_RCONTROL] = WM_Key_Ctrl;
|
||||
w32_wm_state->key_from_vkey_table[VK_SHIFT] = WM_Key_Shift;
|
||||
w32_wm_state->key_from_vkey_table[VK_LSHIFT] = WM_Key_Shift;
|
||||
w32_wm_state->key_from_vkey_table[VK_RSHIFT] = WM_Key_Shift;
|
||||
w32_wm_state->key_from_vkey_table[VK_MENU] = WM_Key_Alt;
|
||||
w32_wm_state->key_from_vkey_table[VK_LMENU] = WM_Key_Alt;
|
||||
w32_wm_state->key_from_vkey_table[VK_RMENU] = WM_Key_Alt;
|
||||
|
||||
w32_wm_state->key_from_vkey_table[VK_DIVIDE] = WM_Key_NumSlash;
|
||||
w32_wm_state->key_from_vkey_table[VK_MULTIPLY] = WM_Key_NumStar;
|
||||
w32_wm_state->key_from_vkey_table[VK_SUBTRACT] = WM_Key_NumMinus;
|
||||
w32_wm_state->key_from_vkey_table[VK_ADD] = WM_Key_NumPlus;
|
||||
w32_wm_state->key_from_vkey_table[VK_DECIMAL] = WM_Key_NumPeriod;
|
||||
|
||||
for (uint64 i = 0xDF, j = 0; i < 0xFF; i += 1, j += 1)
|
||||
{
|
||||
w32_wm_state->key_from_vkey_table[i] = (WM_Key)((uint64)WM_Key_Ex0 + j);
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Windows
|
||||
|
||||
internal WM_Window wm_window_open(Rect2f rect, WM_WindowFlags flags, String8 title)
|
||||
{
|
||||
bool32 custom_border = !!(flags & WM_WindowFlag_CustomBorder);
|
||||
bool32 use_default_position = !!(flags & WM_WindowFlag_UseDefaultPosition);
|
||||
Vector2f position = rect.p0;
|
||||
Vector2f dimension = dimension_2f(rect);
|
||||
|
||||
HWND hwnd = 0;
|
||||
{
|
||||
TempArena scratch = scratch_begin(0, 0);
|
||||
String16 titel16 = str16_from_8(scratch.arena, title);
|
||||
w32_wm_new_window_custom_border = custom_border;
|
||||
DWORD style_flags = WS_EX_APPWINDOW;
|
||||
hwnd = CreateWindowExW(style_flags, L"juliet-window", (WCHAR*)titel16.str, WS_OVERLAPPEDWINDOW | WS_SIZEBOX,
|
||||
use_default_position ? CW_USEDEFAULT : (int32)position.x,
|
||||
use_default_position ? CW_USEDEFAULT : (int32)position.y, (int32)dimension.x,
|
||||
(int32)dimension.y, 0, 0, w32_wm_state->hIstance, 0);
|
||||
DragAcceptFiles(hwnd, 1);
|
||||
w32_wm_new_window_custom_border = 0;
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
W32_WM_Window* window = w32_wm_window_alloc(hwnd);
|
||||
{
|
||||
if (w32_GetDpiForWindow_func != 0)
|
||||
{
|
||||
window->dpi = (float32)w32_GetDpiForWindow_func(hwnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
window->dpi = 96.f;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
BOOL enabled = 0;
|
||||
DwmIsCompositionEnabled(&enabled);
|
||||
window->custom_border_composition_enabled = enabled;
|
||||
}
|
||||
|
||||
if (flags & WM_WindowFlag_CustomBorder)
|
||||
{
|
||||
window->custom_border = 1;
|
||||
window->paint_arena = arena_alloc();
|
||||
}
|
||||
|
||||
WM_Window result = w32_wm_handle_from_window(window);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal Rect2f wm_client_rect_from_window(WM_Window handle)
|
||||
{
|
||||
Rect2f result = { 0 };
|
||||
W32_WM_Window* window = w32_wm_window_from_handle(handle);
|
||||
if (window)
|
||||
{
|
||||
RECT rect = { 0 };
|
||||
GetClientRect(w32_wm_hwnd_from_window(window), &rect);
|
||||
result = w32_wm_rect2f_from_rect(rect);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Events
|
||||
|
||||
internal void wm_send_wakeup_event()
|
||||
{
|
||||
PostThreadMessageW(w32_wm_state->gfx_thread_tid, 0x401, 0, 0);
|
||||
}
|
||||
|
||||
internal WM_EventList wm_get_events(Arena* arena, bool32 wait)
|
||||
{
|
||||
w32_wm_event_arena = arena;
|
||||
MemoryZeroStruct(&w32_wm_event_list);
|
||||
MSG msg = { 0 };
|
||||
if (!wait || GetMessageW(&msg, 0, 0, 0))
|
||||
{
|
||||
bool32 first_wait = wait;
|
||||
for (; first_wait || PeekMessageW(&msg, 0, 0, 0, PM_REMOVE); first_wait = 0)
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
if (msg.message == WM_QUIT)
|
||||
{
|
||||
w32_wm_push_event(WM_EventKind_WindowClose, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return w32_wm_event_list;
|
||||
}
|
||||
|
||||
internal WM_Modifiers wm_get_modifiers()
|
||||
@@ -184,3 +518,60 @@ internal WM_Modifiers wm_get_modifiers()
|
||||
}
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
internal Vector2f wm_mouse_from_window(WM_Window handle)
|
||||
{
|
||||
Vector2f result = { 0 };
|
||||
POINT p;
|
||||
if (GetCursorPos(&p))
|
||||
{
|
||||
W32_WM_Window* window = w32_wm_window_from_handle(handle);
|
||||
ScreenToClient(window->hwnd, &p);
|
||||
result.x = (float32)p.x;
|
||||
result.y = (float32)p.y;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Cursors
|
||||
|
||||
internal void wm_set_cursor(WM_Cursor cursor)
|
||||
{
|
||||
bool32 valid_cursor = 1;
|
||||
HCURSOR hcursor = 0;
|
||||
switch (cursor)
|
||||
{
|
||||
default:
|
||||
{
|
||||
valid_cursor = 0;
|
||||
break;
|
||||
};
|
||||
#define WIN32_CURSOR_X_LIST(X) X(Pointer, IDC_ARROW)
|
||||
#define CURSOR_CASE(Entry, IDC) \
|
||||
case WM_Cursor_##Entry: \
|
||||
{ \
|
||||
local_persist HCURSOR curs = 0; \
|
||||
if (curs == 0) \
|
||||
{ \
|
||||
curs = LoadCursor(NULL, IDC); \
|
||||
} \
|
||||
hcursor = curs; \
|
||||
break; \
|
||||
}
|
||||
WIN32_CURSOR_X_LIST(CURSOR_CASE)
|
||||
#undef CURSOR_CASE
|
||||
#undef WIN32_CURSOR_X_LIST
|
||||
}
|
||||
if (valid_cursor && !w32_wm_resizing)
|
||||
{
|
||||
if (hcursor != w32_wm_state->hCursor)
|
||||
{
|
||||
PostMessageW(0, WM_SETCURSOR, 0, 0);
|
||||
POINT p = { 0 };
|
||||
GetCursorPos(&p);
|
||||
SetCursorPos(p.x, p.y);
|
||||
}
|
||||
w32_wm_state->hCursor = hcursor;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,11 @@ struct W32_WM_Window
|
||||
HDC hdc;
|
||||
WINDOWPLACEMENT last_window_placement;
|
||||
float32 dpi;
|
||||
bool32 custom_border;
|
||||
float32 custom_border_title_thickness;
|
||||
float32 custom_border_edge_thickness;
|
||||
bool32 custom_border_composition_enabled;
|
||||
Arena* paint_arena;
|
||||
};
|
||||
|
||||
// =============================================================================
|
||||
@@ -40,10 +45,16 @@ struct W32_WM_State
|
||||
// =============================================================================
|
||||
// Globals
|
||||
|
||||
global W32_WM_State* w32_wm_state = 0;
|
||||
global WM_EventList w32_wm_event_list = { 0 };
|
||||
global Arena* w32_wm_event_arena = 0;
|
||||
global bool32 w32_wm_resizing = 0;
|
||||
global W32_WM_State* w32_wm_state = 0;
|
||||
global WM_EventList w32_wm_event_list = { 0 };
|
||||
global Arena* w32_wm_event_arena = 0;
|
||||
global bool32 w32_wm_resizing = 0;
|
||||
global bool32 w32_wm_new_window_custom_border = 0;
|
||||
|
||||
// =============================================================================
|
||||
// Helpers
|
||||
|
||||
internal Rect2f w32_wm_rect2f_from_rect(RECT rect);
|
||||
|
||||
// =============================================================================
|
||||
// Windows
|
||||
@@ -51,4 +62,7 @@ global bool32 w32_wm_resizing = 0;
|
||||
internal WM_Window w32_wm_handle_from_window(W32_WM_Window* window);
|
||||
internal W32_WM_Window* w32_wm_window_from_handle(WM_Window handle);
|
||||
internal W32_WM_Window* w32_wm_window_from_hwnd(HWND hwnd);
|
||||
internal HWND w32_wm_hwnd_from_window(W32_WM_Window* window);
|
||||
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 void w32_wm_window_release(W32_WM_Window* window);
|
||||
@@ -14,6 +14,13 @@ struct WM_SystemInfo
|
||||
// =============================================================================
|
||||
// Window Types
|
||||
|
||||
typedef uint32 WM_WindowFlags;
|
||||
enum
|
||||
{
|
||||
WM_WindowFlag_CustomBorder = (1 << 0),
|
||||
WM_WindowFlag_UseDefaultPosition = (1 << 1),
|
||||
};
|
||||
|
||||
typedef struct WM_Window WM_Window;
|
||||
struct WM_Window
|
||||
{
|
||||
@@ -38,6 +45,14 @@ struct WM_MonitorArray
|
||||
|
||||
#include "window_manager_key.h"
|
||||
|
||||
// =============================================================================
|
||||
// Curosr Types
|
||||
typedef enum WM_Cursor
|
||||
{
|
||||
WM_Cursor_Pointer,
|
||||
WM_Cursor_COUNT
|
||||
} WM_Cursor;
|
||||
|
||||
// =============================================================================
|
||||
// Event Types
|
||||
|
||||
@@ -96,7 +111,21 @@ internal WM_Event* wm_event_list_push_new(Arena* arena, WM_EventList* events, WM
|
||||
|
||||
internal void wm_init();
|
||||
|
||||
// =============================================================================
|
||||
// Windows
|
||||
|
||||
internal WM_Window wm_widow_open(Rect2f rect, WM_WindowFlags flags, String8 title);
|
||||
internal Rect2f wm_client_rect_from_window(WM_Window window);
|
||||
|
||||
// =============================================================================
|
||||
// Events
|
||||
|
||||
internal void wm_send_wakeup_event();
|
||||
internal WM_EventList wm_get_events(Arena* arena, bool32 wait);
|
||||
internal WM_Modifiers wm_get_modifiers();
|
||||
internal Vector2f wm_mouse_from_window(WM_Window window);
|
||||
|
||||
// =============================================================================
|
||||
// Cursors
|
||||
|
||||
internal void wm_set_cursor(WM_Cursor cursor);
|
||||
Reference in new issue
Block a user