Compare commits

..

3 Commits

Author SHA1 Message Date
d3d8421110 step closer to opening a window, shouldn't be this hard but reasoning on
how to do this in a way that encourages cross-platform development.
2024-08-24 09:45:46 -05:00
404ec22e57 progress towards opening a window; minor fixes here and there;
added base_math
2024-08-21 11:58:46 -05:00
79b6e83147 building graphics layer i.e. opening a window. 2024-08-21 08:29:42 -05:00
24 changed files with 724 additions and 22 deletions

9
LICENSE Normal file
View File

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2024 tijani
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -129,15 +129,23 @@ A list of layers in the codebase and their associated namespaces are below:
- `base` (no namespace): Universal, codebase-wide constructs. It contains
strings, math, memory allocators, threading, and logging.
It depends on no other codebase layers.
- `es/core` (`ES_`): Short for Engine Subsystem. Implements the
- `es/gfx` (`ES_`): Engine Subsystem graphical frontend. Builds on top of
`es/core` to provide graphical features such as windows, panels, and all
interfaces needed for using the scanner. It is the main user of `os/gfx`.
- `os/core` (`OS_`): An abstraction layer that provides core, non-graphical
functionality from the operating sytem under a general use abstraction API.
This is implemented per supported operating system.
- `os/gfx` (`OS_`): This layer builds on top of `os/core`, it provides
graphical operating functionalities under a general use abstraction API.
- `ef/core` (`EF_`): The scanner engine's non-graphical frontend. It implements
interfacing with the scanner over usb, colour space settings, and all intricate
details that have to do with the software working with the scanner.
- `ef/gfx` (`EF_`): The scanner engine`s graphical frontend. It provides all
graphical features, including windows, panels, and all other various interfaces
needed by the engine to function.
- `render` (`R_`): An abstraction layer providing an abstract API for rendering using
various GPU APIs under a common interface. This layer does not implement a high level
API for drawing, it is strictly for minimal abstractions on a needed basis. Higher
level drawing features are implemented in the `draw` layer
- `draw` (`D_`): Implements a high level graphics drawing API for the scanning engine.
It uses the underlying `render` abstraction API. It provides a high-level API for various
draw commands, but takes care to bath them together.
- `ui` (`UI_`): For building graphical user interfaces. Provides a core
immediate mode hierarchical user interface data structure building API, and
has helper layers for building higher level widgets.

View File

@ -44,6 +44,10 @@
#define BUILD_DEBUG 1
#endif
#if !defined(BUILD_ENTRY_DEFINING_UNIT)
#define BUILD_ENTRY_DEFINING_UNIT 1
#endif
#if !defined(BUILD_VERSION_MAJOR)
#define BUILD_VERSION_MAJOR 0
#endif

6
src/base/base_core.c Normal file
View File

@ -0,0 +1,6 @@
// Safe Casts
internal u16 safe_cast_u16(u32 x) {
// Assert
u16 result = (u16)x;
return result;
}

View File

@ -134,6 +134,9 @@ global const u32 bit30 = (1 << 29);
global const u32 bit31 = (1 << 30);
global const u32 bit32 = (1 << 31);
// Safe Casts
internal u16 safe_cast_u16(u32 x);
// Misc helpers
// NOTE(tijani): Divides total size of array by size of one element in the array gives
// the number of elements in the array.

View File

@ -1 +1,12 @@
internal void main_thread_entry_point(void) { ThreadNameF("[main thread]"); }
internal void main_thread_base_entry_point(void) {
ThreadNameF("[main thread]");
#if defined(OS_GFX_H)
os_gfx_init();
#endif
#if defined(GFX_H)
gfx_init(update_and_render);
#endif
entry_point();
}

View File

@ -1,6 +1,6 @@
#ifndef BASE_ENTRY_POINT_H
#define BASE_ENTRY_POINT_H
internal void main_thread_entry_point(void);
internal void main_thread_base_entry_point(void);
#endif // BASE_ENTRY_POINT_H

View File

@ -1,7 +1,10 @@
// clang-format off
#include "base_core.c"
#include "base_arena.c"
#include "base_strings.c"
#include "base_markup.c"
#include "base_threading_context.c"
#include "base_entry_point.c"
// clang-format on

View File

@ -10,6 +10,8 @@
#include "base_strings.h"
#include "base_markup.h"
#include "base_threading_context.h"
#include "base_entry_point.h"
// clang-format on
#endif // BASE_INC_H

38
src/base/base_math.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef BASE_MATH_H
#define BASE_MATH_H
// Vector Types
typedef Vec2F32 Vec2F32;
union Vec2F32 {
struct {
f32 x;
f32 y;
};
f32 v[2];
};
// Range Types
// Range 2 (forms a rectangle)
typedef union Rng2F32 Rng2F32;
union Rng2F32 {
struct {
Vec2F32 min;
Vec2F32 Max;
};
struct {
Vec2F32 pos0;
Vec2F32 pos1;
};
struct {
f32 x0;
f32 y0;
f32 x1;
f32 y1;
};
Vec2F32 v[2];
};
#endif // BASE_MATH_H

46
src/ef/gfx/ef_gfx.c Normal file
View File

@ -0,0 +1,46 @@
// Window State functions
internal EF_Window *ef_window_open(Vec2F32 size, OS_Handle preferred_monitor) {
EF_Window *window = ef_gfx_state->free_window;
if (window != 0) {
SLLStackPop(ef_gfx_state->free_window);
u64 gen = window->gen;
MemoryZeroStruct(window);
window->gen = gen;
} else {
window = push_array(ef_gfx_state->arena, EF_Window, 1);
}
window->gen += 1;
window->arena = arena_alloc();
{
String8 title = str8_lit_comp(BUILD_TITLE_STRING_LITERAL);
window->os = os_window_open(size, OS_WindowFlag_CustomBorder, title);
}
window->last_dpi = os_dpi_fram_window(window->os);
// NOTE(tijani): Setting preferred monitor, not important
// OS_Handle zero_monitor = {0};
// if(!os_handle_match(zero_monitor, preferred_window)){
// os_set_window
// }
os_window_equip_repaint(window->os, ef_gfx_state->repaint_hook, window);
DLLPushBack(ef_gfx_state->first_winow, ef_gfx_state->last_window, window);
return window;
}
internal EF_Window *ef_window_from_os_handle(OS_Handle os) {}
internal void df_window_update_and_render(Arena *arena, EF_Window *window_state) {}
// Main layer top level calls
internal void ef_gfx_init(OS_WindowRepaintFunctionType *window_repaint_entry_point) {
// Begin profiling
Arena *arena = arena_alloc();
ef_gfx_state = push_array(arena, EF_GfxState, 1);
ef_gfx_state->arena = arena;
ef_gfx_state->num_frame_requested = 2;
ef_gfx_state->repaint_hook = window_repaint_entry_point;
}
internal void ef_gfx_begin_frame(Arena *arena) {}
internal void ef_gfx_end_frame(void) {}

84
src/ef/gfx/ef_gfx.h Normal file
View File

@ -0,0 +1,84 @@
#ifndef EF_GFX_H
#define EF_GFX_H
// Per-Window State
typedef struct EF_Window EF_Window;
struct EF_Window {
// Links and metadata
EF_Window *next;
EF_Window *previous;
u64 gen;
u64 frames_alive;
// EF_ConfigSource config_source;
// Top level info & handles
Arena *arena;
OS_Handle os;
// R_handle render; // not needed for now, will revisit
// UI_State *ui_state; // not needed for now, will revisit
f32 last_dpi;
// config / settings
// view state delta histor
// menu bar state
// tab context menu state
// error state
// panel state
// per-frame drawing state
};
// Graphical state
typedef struct EF_GfxState EF_GfxState;
struct EF_GfxState {
Arena *arena;
// frame request state
u64 num_frames_requested;
// history cache
// key map table NOTE(tijani): ??
// confirmation popup state
// windows
OS_WindowRepaintFunctionType *repaint_hook;
EF_Window *first_window;
EF_Window *last_window;
EF_Window *free_window;
u64 window_count;
b32 last_window_queued_save;
// view state
// drag/drop satte machine
// rich hove info
// running theme state
// global setting
// icon texture
};
// Globals
global EF_GfxState *ef_gfx_satet = 0;
// Window State functions
internal EF_Window *ef_window_open(Vec2F32 size, OS_Handle preferred_monitor);
internal EF_Window *ef_window_from_os_handle(OS_Handle os);
internal void df_window_update_and_render(Arena *arena, EF_Window *window_state);
// Main layer top level calls
internal void ef_gfx_init(OS_WindowRepaintFunctionType *window_repaint_entry_point);
internal void ef_gfx_begin_frame(Arena *arena);
internal void ef_gfx_end_frame(void);
#endif // EF_GFX_H

28
src/goff/goff.c Normal file
View File

@ -0,0 +1,28 @@
internal void update_and_render(OS_Handle repaint_window_handle) {
// Profiling start
Temp scratch = scratch_begin(0, 0);
// Get events from OS
OS_EventList events = {0};
if (os_handle_match(repaint_window_handle, os_handle_zero())) {
events = os_get_events(scratch.arena, gfx_state->num_frames_requested == 0);
}
// begin frames
{ gfx_begin_frame(scratch.arena); }
// Update and render
{}
// End frondend frame
{ gfx_end_frame(); }
// Submit rendering to all windows
{}
// Show windows after first frame
{}
scratch_end(scratch);
// Profiling end
}

8
src/goff/goff.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef GOFF_H
#define GOFF_H
// Frontend entry point
internal void update_and_render(OS_HANDLE repaint_window);
#endif // GOFF_H

View File

@ -10,4 +10,36 @@
// clang-format on
u64 main(int argc, char **argv) { return 0; }
// Build Options
// #define BUILD_VERSION_MAJOR 0
// #define BUILD_VERSION_MINOR 1
// #define BUILD_VERSION_PATCH 0
// #define BUILD_RELEASE_PHASE_STRING_LITERAL "ALPHA"
// #define BUILD_TITLE "Goff Film Scanner"
// #define OS_GRAPHICAL 1
// Entry Point
internal void entry_point() {
Temp scratch = scratch_begin(0, 0);
// Setup layers
{ gfx_init(); }
// Main application loop
{
for (;;) {
// Update and render frame here
OS_Handle repaint_window = {0};
update_and_render(repaint_window);
// Quit
// if (gfx_state->first_window == 0) {
// break;
// }
}
}
scratch_end(scratch);
}

0
src/os/core/os_core.c Normal file
View File

View File

@ -11,6 +11,12 @@ struct OS_SystemInfo {
String8 machine_name;
};
// Handle types
typedef struct OS_Handle OS_Handle;
struct OS_Handle {
u64 l_u64[1];
};
// Process Information
typedef struct OS_ProcessInfo OS_ProcessInfo;
struct OS_ProcessInfo {
@ -45,4 +51,14 @@ internal void os_set_thread_name(String8 name);
// %os_hooks(implemented per-os) Aborting
internal void os_abort(s32 exit_code);
// %os_hooks(implemented per-os) Entry Points
// os_core defines a low level entry point if BUILD_ENTRY_DEFINING_UNIT is
// defined to 1. This will call into the standard cocdebase program entry point
// called "entry_point"
#if BUILD_ENTRY_DEFINING_UNIT
internal void entry_point(void);
#endif
#endif // OS_CORE_H

View File

@ -2,8 +2,8 @@
// compatibility with older versions of windows where the modern WIN32
// SetThreadDescription function is not available and use old ways.
// This way it can be done dynamically at runtime without any hiccups.
typedef HRESULT W32_SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription);
global W32_SetThreadDescription *w32_SetThreadDescription_func = 0;
typedef HRESULT W32_SetThreadDescription_Type(HANDLE hThread, PCWSTR lpThreadDescription);
global W32_SetThreadDescription_Type *w32_SetThreadDescription_func = 0;
// %os_hooks(implemented per-os) System and process info
internal OS_SystemInfo *os_get_system_info(void) { return &os_w32_state.system_info; }
@ -46,7 +46,7 @@ internal b32 os_commit_large(void *ptr, u64 size) { return -1; }
// %os_hooks(implemented per-os) Threads
internal u32 os_thread_id(void) {
u32 id = GetCurrentThreadID();
u32 id = GetCurrentThreadId();
return (id);
}
@ -90,3 +90,41 @@ internal void os_set_thread_name(String8 name) {
// %os_hooks(implemented per-os) Aborting
internal void os_abort(s32 exit_code) { ExitProcess(exit_code); }
internal void w32_entry_point_caller() {
// OS layer initialization
{
// dynamically load windows functions, not guaranteed on all SDKs
{
HMODULE module = LoadLibraryA("kernel32.dll");
w32_SetThreadDescription_func = (W32_SetThreadDescription_Type *)GetProcAddress(module, "SetThreadDescription");
FreeLibrary(module);
}
// enable large pages if possible
{
HANDLE token;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
LUID luid;
if (LookupPrivilegeValue(0, SE_LOCK_MEMORY_NAME, &luid)) {
TOKEN_PRIVILEGES priv;
priv.PrivilegeCount = 1;
priv.Privileges[0].Luid = luid;
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(token, 0, &priv, sizeof(priv), 0, 0);
}
CloseHandle(token);
}
}
// Get system info
}
// call into the actual entry point
main_thread_base_entry_point();
}
int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd) {
w32_entry_point_caller();
return 0;
}

View File

@ -4,8 +4,12 @@
// clang-format off
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <processthreadsapi.h>
#pragma comment(lib, "user32")
#pragma comment(lib, "advapi32")
// clang-format on
// Application State

120
src/os/gfx/os_gfx.h Normal file
View File

@ -0,0 +1,120 @@
#ifndefine OS_GFX_H
#define OS_GFX_H
// Graphics system information
typedef struct OS_GfxInfo OS_GfxInfo;
struct OS_GfxInfo {
f32 double_click_time;
f32 caret_blink_time;
f32 default_referesh_rate;
};
// Window Types
typedef u32 OS_WindowFlags;
enum { OS_WindowFlag_CustomBorder = (1 << 0); };
typedef void OS_WindowRepaintFunctionType(OS_Handle window, void *user_data);
// Cursor Types
typedef enum OS_Cursor {
OS_Cursor_Pointer,
OS_Cursor_IBar,
OS_Cursor_LeftRight,
OS_Cursor_UpDown,
OS_Cursor_DownRight,
OS_Cursor_UpRight,
OS_Cursor_UpDownLeftRight,
OS_Cursor_HandPoint,
OS_Cursor_Disabled,
OS_Cursor_COUNT,
} OS_Cursor;
typedef enum OS_EventKind {
OS_EvenKind_NULL,
OS_EventKind_Press,
OS_EventKind_Release,
OS_EventKind_MouseMove,
OS_EventKind_Text,
OS_EventKind_Scroll,
OS_EventKind_WindowLoseFocus,
OS_EventKind_WindowClose,
OS_EventKind_Wakeup,
OS_EventKind_COUNT
} OS_EventKind;
typedef u32 OS_EventFlags;
enum { OS_EventFlag_Ctrl = (1 << 0), OS_EventFlag_Shift = (1 << 1), OS_EventFlag_Alt = (1 << 2); };
typedef struct OS_Event OS_Event;
struct OS_Event {
OS_Event *next;
OS_Event *previous;
u64 timestamp_us;
OS_Handle window;
OS_EventKind kind;
OS_EventFlag flags;
OS_Key key;
b32 is_repeat;
b32 right_sided;
u32 character;
u32 repeat_count;
Vec2F32 position;
Vec2F32 delta;
String8List strings;
};
typedef struct OS_EventList OS_EventList;
struct OS_EventList {
u64 count;
OS_Event *first;
OS_Event *last;
};
// %os_hooks Event function helpers (Implementd Per-OS)
internal os_eat_event(OS_EventList *events, OS_Event *event);
internal b32 os_key_press(OS_EventList *events, OS_Handle window, OS_EventFlags flags, OS_Key key);
internal os_key_release(OS_EventList *events, OS_Handle window, OS_EVentFlags flags, OS_Key key);
internal b32 os_text(OS_EventList *events, OS_Handle window, u32 character);
// %os_hooks Main initialization API (Implemented Per-OS)
internal void os_gfx_init(void);
// %os_Hooks Graphics System Info (Implemented Per-OS)
internal OS_GfxInfo *os_get_gfx_info(void);
// %os_hooks Windows (Implemented Per-OS)
intarnal OS_Handle os_window_open(Vec2F32 resolution, OS_WindowsFlags flags, String8 title);
internal void os_window_close(OS_Handle handle);
internal void os_window_first_paint(OS_Handle window_handle);
internal void os_window_equip_repaint(OS_Handle window, OS_WindowRepaintFunctionType *repaint, void *user_data);
internal void os_window_focus(OS_Handle window);
internal b32 os_window_is_focused(OS_Handle window);
internal b32 os_window_is_fullscreen(OS_Handle window);
internal void os_window_set_fullscreen(OS_Handle window, b32 fullscreen);
internal b32 os_window_is_maximized(OS_Handle window);
internal void os_window_set_maximized(OS_Handle window, b32 maximized);
internal void os_window_minimize(OS_Handle window);
internal void os_window_bring_to_front(OS_Handle window);
internal void os_window_set_monitor(OS_Handle window, OS_Handle monitor);
internal Rng2F32 os_rect_from_window(OS_Handle window);
internal Rng2F32 os_client_rect_from_window(OS_Handle window);
internal f32 os_dpi_from_window(OS_Handle window);
// %os_hooks Events (Implemented Per-OS)
internal void os_send_wakeup_event(void);
internal EventList os_get_events(Arena *arena, b32 wait);
internal OS_EventFlags os_get_event_flags(void);
internal Vec2F32 os_mouse_from_window(OS_Handle window);
// %os_hooks Cursors (Implemented Per-OS)
internal void os_set_cursor(OS_Cursr cursor);
// %os_hooks Native user facing graphical message (Implemented Per-OS)
internal void os_graphical_message(b32 error, String8 title, String8 message);
// %os_hooks Shell Operations ??
internal void os_show_in_filesystem_ui(String8 path);
#endif // OS_GFX_H

View File

@ -0,0 +1,151 @@
// Windows
internal OS_Handle os_w32_handle_from_window(OS_W32_Window *window) {}
internal OS_W32_Window *os_w32_window_from_handle(OS_Handle window) {}
internal OS_W32_Window *os_w32_window_from_hwnd(HWND hwnd) {}
internal HWND os_w32_hwnd_from_window(OS_W32_Window *window) {}
internal OS_W32_Window *os_w32_window_alloc(void) {}
internal void os_w32_window_release(OS_W32_Window *window) {}
internal OS_Event *os_w32_push_event(OS_EventKind kind, OS_W32_Window *window) {}
internal OS_Key os_w32_os_key_from_vkey(WPARAM vkey) {}
internal WPARAM os_w32_vkey_from_os_key(OS_Key key) {}
internal LRESULT os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
// Start profilling??
LRESULT result = 0;
b23 good = 1; // ??
if (os_w32_event_arena == 0) {
result = DefWindowProcW(hwnd, uMsg, wParam, lParam);
good = 0;
}
if (good) {
OS_W32_Window *window = os_w32_window_from_hwnd(hwnd);
OS_Handle window_handle = os_w32_handle_from_window(window);
b32 release = 0; // ??
switch (uMsg) {
default: {
result = DefWindowProcW(hwnd, uMsg, wParam, lParam);
} break;
case WM_SIZE:
case WM_PAINT {
if (window->repaint != 0) {
PAINTSTRUCT pain_struct = {0}; BeginPaint(hwnd, &paint_struct);
window->repaint(os_w32_handle_from_window(window), window->repaint_user_data);
EndPaint(hwnd, &paint_struct);
} else {
result = DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
} break;
case WM_CLOSE: {
os_w32_push_event(OS_EventKind_WindowClose, window);
} break;
case WM_DPICHANGED: {
f32 new_dpi = (f32)(wParam & 0xffff);
window->dpi = new_dpi;
} break;
}
}
// End profiling
return result;
}
internal void os_gfx_init(void) {
Arena *arena = arena_alloc();
os_w32_gfx_state->arena = push_array(arena, OS_W32_GfxState, 1);
os_w32_gfx_satte->gfx_thread_tid = (u32)GetCurrentThreadId();
os_w32_gfx_state->hInstance = GetModuleHandle(0);
// Set DPI Awareness
// Register grahical window
{
WNDCLASSEXW wndclass = {sizeof(wndclass)};
wndclass.lpfnWndProc = os_w32_wnd_proc;
wndclass.hInstance = os_w32_gfx_state->hInstance;
wndclass.lpszClassName = L"goff-graphical-window";
wndclass.hCursor = LoadCursor(0, IDC_ARROW);
wndclass.hIcon = LoadIcon(os_w32_gfx_state->hInstance, MAKEINTRESOURCE(1));
wndclass.style = CS_VREDRAW | CS_HREDRAW;
ATOM wndatom = RegisterClassEXW(&wndclass);
(void)wndatom;
}
// Get graphics system info
// Set initial cursor
// Fill vkeys -> OS_KEY table
}
// %os_Hooks Graphics System Info (Implemented Per-OS)
internal OS_GfxInfo *os_get_gfx_info(void) { return &os_w32_gfx_state->gfx_info; }
// %os_hooks Windows (Implemented Per-OS)
intarnal OS_Handle os_window_open(Vec2F32 resolution, OS_WindowsFlags flags, String8 title) {
// make HWND
HWND hwnd = 0;
{
Temp scratch = scratch_begin(0, 0);
String16 title16 = str16_from_8(scratch.arena, title);
hwnd = CreateWindowExW(WS_EX_APPWINDOW, L"goff-graphical-window", (WCHAR *)title16.str,
WS_OVERLAPPEDWINDOW | WS_SIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, (int)resolution.x,
(int)resolution.y, 0, 0, os_w32_gfx_state->hInstance, 0);
scratch_end(scratch);
}
// Make/fill window
OS_W32_Window *window = os_w32_window_alloc();
{
window->hwnd = hwnd;
// Set DPI
}
OS_Handle handle = os_w32_handle_from_window(window);
return handle;
}
internal void os_window_close(OS_Handle handle) {
OS_W32_Window *window = os_w32_window_from_handle(handle);
os_w32_window_release(window);
}
internal void os_window_first_paint(OS_Handle window_handle) {
OS_W32_Window *window = os_w32_window_from_handle(window_handle);
window->filst_paint_done = 1;
ShowWindow(window->handle, SW_SHOW);
if (window->maximized) {
ShowWindow(window - hwnd, SW_MAXIMIZE);
}
}
internal void os_window_equip_repaint(OS_Handle handle, OS_WindowRepaintFunctionType *repaint, void *user_data) {
OS_W32_Window *window = os_w32_window_from_handle(handle);
window->repaint = repaint;
window->repaint_user_data = user_data;
}
internal Rng2F32 os_rect_from_window(OS_Handle handle) {
Rng2F32 range = {0};
OS_W32_Window *window = os_w32_window_fram_handle(handle);
if (window) {
RECT rect = {0};
GetWindowRect(os_w32_hwnd_from_window(window), &rect);
range = os_w32_rng2f32_from_rect(rect);
}
return range;
}
internal Rng2F32 os_client_rect_from_window(OS_Handle handle) {
Rng2f32 range = {0};
OS_W32_Window *window = os_w32_window_fram_handle(handle);
if (window) {
RECT = {0};
GetClientRect(os_w32_hwnd_from_window(window), &rect);
range = os_w32_rng2f32_from_rect(rect);
}
return range;
}
internal f32 os_dpi_from_window(OS_Handle window) {}

View File

@ -0,0 +1,62 @@
#ifndef OS_GFX_WIN32_H
#define OS_GFX_WIN32_H
// Windows
typedef struct OS_W32_TitleBarClientArea OS_W32_TitleBarClientArean;
struct OS_W32_TitleBarClientArea {
OS_W32_TitleBarClientArea *next;
Rng2F32 rect;
};
typedef struct OS_W32_Window OS_W32_Window;
struct OS_W32_Window {
OS_W32_Window *next;
OS_W32_Window *prev;
HWND *hwnd;
WINDOWPLACEMENT last_window_placement;
OS_WindowRepaintFunctionType *repaint;
void *repaint_user_data;
f32 dpi;
b32 first_paint_done;
b32 maximized;
b32 custome_border;
f32 custom_border_title_thickness;
f32 custom_border_edge_thickness;
b32 custom_border_composition_enabled;
Arena *pain_arena;
OS_W32_TitleBarClientArea *first_title_bar_client_area;
OS_W32_TitleBarClientArea *last_title_bar_client_area;
};
// Global State
typedef struct OS_W32_GfxState OS_W32_GfxState;
struct OS_W32_GfxState {
Arena *arena;
u32 gfx_thread_id;
HINSTANCE hInstance;
HCURSOR hCursor;
OS_GfxInfo gfx_info;
OS_W32_Window *first_window;
OS_W32_Window *last_window;
OS_W32_Window *free_window;
OS_KEY key_from_vkey_table[256];
};
// Globals
global OS_W32_GfxState *os_w32_gfx_state = 0;
global OS_EventList os_w32_event_list = {0};
global Arena *os_w32_event_arena = 0;
b32 os_w32_resizing = 0;
// Windows
internal OS_Handle os_w32_handle_from_window(OS_W32_Window *window);
internal OS_W32_Window *os_w32_window_from_handle(OS_Handle window);
internal OS_W32_Window *os_w32_window_from_hwnd(HWND hwnd);
internal HWND os_w32_hwnd_from_window(OS_W32_Window *window);
internal OS_W32_Window *os_w32_window_alloc(void);
internal void os_w32_window_release(OS_W32_Window *window);
internal OS_Event *os_w32_push_event(OS_EventKind kind, OS_W32_Window *window);
internal OS_Key os_w32_os_key_from_vkey(WPARAM vkey);
internal WPARAM os_w32_vkey_from_os_key(OS_Key key);
internal LRESULT os_w32_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif // OS_GFX_WIN32_H

View File

@ -1,5 +1,18 @@
// clang-format off
#include "os/core/os_core.c"
#if OS_GRAPHICAL
#include "os/gfx/os_gfx.c"
#endif
#include "core/win32/os_core_win32.c"
#if OS_WINDOWS
#include "os/core/win32/os_core_win32.c"
#else
#error OS core layer not implemented for this operating system.
#endif
// clang-format on
#if OS_GRAPHICAL
#if OS_WINDOWS
#include "os/gfx/win32/os_gfx_win32.c"
#else
#error OS graphical layer not implemented for this operating system.
#endif
#endif

View File

@ -1,11 +1,27 @@
#ifndef OS_INC_H
#define OS_INC_H
// clang-format off
#if !defined(OS_GRAPHICAL)
#define OS_GRAPHICAL 0
#endif
#include "core/os_core.h"
#include "core/win32/os_core_win32.h"
#include "os/core/os_core.h"
#if OS_GRAHICAL
#include "os/gfx/os_gfx.h"
#endif
// clang-format on
#if OS_WINDOWS
#include "os/core/win32/os_core_win32.h"
#else
#error OS core layer not implemented for this operating system.
#endif
#if OS_GRAPHICAL
#if OS_WINDOWS
#include "os/gfx/win32/os_gfx_win32.h"
#else
#error OS graphical layer not implemented for this operating system.
#endif
#endif
#endif // OS_INC_H