mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
re-slice linux/win32 backends, top-level folder is backend (demon/win32 -> win32/demon, etc.); os_gfx -> window_manager; fix linux / opengl builds for new apis/types
This commit is contained in:
+2
-2
@@ -49,13 +49,13 @@ commands =
|
||||
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
// .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
.f1 = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
.f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
|
||||
//- rjf: [raddbg wsl]
|
||||
// .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
|
||||
//- rjf: [scratch]
|
||||
.f2 = { .win = "build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
.f2 = { .win = "wsl ./build.sh radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
|
||||
//- rjf: [textperf]
|
||||
// .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
|
||||
+2
-1
@@ -28,7 +28,8 @@ struct ARCH_Info
|
||||
global read_only Rng1U16 arch_reg_code_rng_nil = {0};
|
||||
global read_only String8 arch_reg_code_name_nil = {0};
|
||||
global read_only U8 arch_reg_code_u8_nil = 0;
|
||||
global read_only ARCH_Info arch_info_nil = {0, 0, 0, 0, &arch_reg_code_rng_nil, &arch_reg_code_name_nil, &arch_reg_code_u8_nil, &arch_reg_code_u8_nil};
|
||||
global read_only B8 arch_reg_code_b8_nil = 0;
|
||||
global read_only ARCH_Info arch_info_nil = {0, 0, 0, 0, &arch_reg_code_rng_nil, &arch_reg_code_name_nil, &arch_reg_code_u8_nil, &arch_reg_code_b8_nil};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Abstracted Architecture Functions
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
#include "demon/demon_core.c"
|
||||
|
||||
#if OS_WINDOWS
|
||||
# include "demon/win32/demon_core_win32.c"
|
||||
# include "win32/demon/win32_demon.c"
|
||||
#elif OS_LINUX
|
||||
# include "demon/linux/demon_core_linux.c"
|
||||
# include "linux/demon/linux_demon.c"
|
||||
#else
|
||||
# error Demon layer backend not defined for this operating system.
|
||||
#endif
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
#include "demon/demon_core.h"
|
||||
|
||||
#if OS_WINDOWS
|
||||
# include "demon/win32/demon_core_win32.h"
|
||||
# include "win32/demon/win32_demon.h"
|
||||
#elif OS_LINUX
|
||||
# include "demon/linux/demon_core_linux.h"
|
||||
# include "linux/demon/linux_demon.h"
|
||||
#else
|
||||
# error Demon layer backend not defined for this operating system.
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,222 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef DEMON_OS_LINUX_H
|
||||
#define DEMON_OS_LINUX_H
|
||||
|
||||
// TODO(allen): Potential Upgrades:
|
||||
//
|
||||
// memory fd upgrade - Right now for each process we hold open a file
|
||||
// descriptor for the process's memory (/proc/%d/mem) for the entire lifetime
|
||||
// of the process; it could be opened and closed with some kind of LRU cache
|
||||
// to put a finite cap on the number of handles the demon holds
|
||||
//
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Get The Linux Includes
|
||||
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <elf.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Linux Demon Types
|
||||
|
||||
//- entities
|
||||
|
||||
// Demon Linux Entity Extensions
|
||||
// Process: ext_u64 set to memory file descriptor
|
||||
// Thread : ext_u64 cast to DEMON_LNX_ThreadExt
|
||||
// Module : ext_u64 set to U64 (address of name)
|
||||
|
||||
struct DEMON_LNX_ThreadExt{
|
||||
B32 expecting_dummy_sigstop;
|
||||
};
|
||||
StaticAssert(sizeof(DEMON_LNX_ThreadExt) <= sizeof(Member(DEMON_Entity, ext_u64)), check_demon_lnx_thread_ext);
|
||||
|
||||
//- helpers
|
||||
|
||||
struct DEMON_LNX_AttachNode{
|
||||
DEMON_LNX_AttachNode *next;
|
||||
pid_t pid;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_ProcessAux{
|
||||
B32 filled;
|
||||
U64 phnum;
|
||||
U64 phent;
|
||||
U64 phdr;
|
||||
U64 execfn;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_PhdrInfo{
|
||||
Rng1U64 range;
|
||||
U64 dynamic;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_ModuleNode{
|
||||
DEMON_LNX_ModuleNode *next;
|
||||
U64 vaddr;
|
||||
U64 size;
|
||||
U64 name;
|
||||
U64 already_known;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_EntityNode{
|
||||
DEMON_LNX_EntityNode *next;
|
||||
DEMON_Entity *entity;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Linux Demon Register Layouts
|
||||
|
||||
// these are defined in <sys/user.h> but only for one architecture at a time
|
||||
// (and we can't really trick it into giving us both in any obvious way)
|
||||
// we define them here so that we have them all "at once"
|
||||
|
||||
struct DEMON_LNX_UserRegsX64{
|
||||
U64 r15;
|
||||
U64 r14;
|
||||
U64 r13;
|
||||
U64 r12;
|
||||
U64 rbp;
|
||||
U64 rbx;
|
||||
U64 r11;
|
||||
U64 r10;
|
||||
U64 r9;
|
||||
U64 r8;
|
||||
U64 rax;
|
||||
U64 rcx;
|
||||
U64 rdx;
|
||||
U64 rsi;
|
||||
U64 rdi;
|
||||
U64 orig_rax;
|
||||
U64 rip;
|
||||
U64 cs;
|
||||
U64 rflags;
|
||||
U64 rsp;
|
||||
U64 ss;
|
||||
U64 fsbase;
|
||||
U64 gsbase;
|
||||
U64 ds;
|
||||
U64 es;
|
||||
U64 fs;
|
||||
U64 gs;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_UserX64{
|
||||
DEMON_LNX_UserRegsX64 regs;
|
||||
S32 u_fpvalid, _pad0;
|
||||
SYMS_XSaveLegacy i387;
|
||||
U64 u_tsize, u_dsize, u_ssize, start_code, start_stack;
|
||||
U64 signal;
|
||||
S32 reserved, _pad1;
|
||||
U64 u_ar0, u_fpstate;
|
||||
U64 magic;
|
||||
U8 u_comm[32];
|
||||
U64 u_debugreg[8];
|
||||
};
|
||||
|
||||
struct DEMON_LNX_UserRegsX86{
|
||||
U32 ebx;
|
||||
U32 ecx;
|
||||
U32 edx;
|
||||
U32 esi;
|
||||
U32 edi;
|
||||
U32 ebp;
|
||||
U32 eax;
|
||||
U32 ds;
|
||||
U32 es;
|
||||
U32 fs;
|
||||
U32 gs;
|
||||
U32 orig_eax;
|
||||
U32 eip;
|
||||
U32 cs;
|
||||
U32 eflags;
|
||||
U32 sp;
|
||||
U32 ss;
|
||||
};
|
||||
|
||||
struct DEMON_LNX_UserX86{
|
||||
DEMON_LNX_UserRegsX86 regs;
|
||||
S32 u_fpvalid;
|
||||
SYMS_FSave i387;
|
||||
U32 u_tsize, u_dsize, u_ssize, start_code, start_stack;
|
||||
S32 signal, reserved;
|
||||
U32 u_ar0, u_fpstate;
|
||||
U32 magic;
|
||||
U8 u_comm[32];
|
||||
U32 u_debugreg[8];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
enum
|
||||
{
|
||||
DEMON_LNX_PermFlags_Read = (1 << 0),
|
||||
DEMON_LNX_PermFlags_Write = (1 << 1),
|
||||
DEMON_LNX_PermFlags_Exec = (1 << 2),
|
||||
DEMON_LNX_PermFlags_Private = (1 << 3)
|
||||
};
|
||||
typedef int DEMON_LNX_PermFlags;
|
||||
|
||||
enum
|
||||
{
|
||||
DEMON_LNX_MapsEntryType_Null,
|
||||
DEMON_LNX_MapsEntryType_Path,
|
||||
DEMON_LNX_MapsEntryType_Heap,
|
||||
DEMON_LNX_MapsEntryType_Stack,
|
||||
DEMON_LNX_MapsEntryType_VDSO,
|
||||
};
|
||||
typedef int DEMON_LNX_MapsEntryType;
|
||||
|
||||
struct DEMON_LNX_MapsEntry
|
||||
{
|
||||
U64 address_lo;
|
||||
U64 address_hi;
|
||||
DEMON_LNX_PermFlags perms;
|
||||
U64 offset;
|
||||
U32 dev_major;
|
||||
U32 dev_minor;
|
||||
U64 inode;
|
||||
String8 pathname;
|
||||
DEMON_LNX_MapsEntryType type;
|
||||
pid_t stack_tid;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
internal DEMON_LNX_ThreadExt* demon_lnx_thread_ext(DEMON_Entity *entity);
|
||||
|
||||
internal B32 demon_lnx_attach_pid(Arena *arena, pid_t pid, DEMON_LNX_AttachNode **new_node);
|
||||
|
||||
internal String8 demon_lnx_executable_path_from_pid(Arena *arena, pid_t pid);
|
||||
internal int demon_lnx_open_memory_fd_for_pid(pid_t pid);
|
||||
|
||||
internal Arch demon_lnx_arch_from_pid(pid_t pid);
|
||||
internal DEMON_LNX_ProcessAux demon_lnx_aux_from_pid(pid_t pid, Arch arch);
|
||||
internal DEMON_LNX_PhdrInfo demon_lnx_phdr_info_from_memory(int memory_fd, B32 is_32bit,
|
||||
U64 phvaddr, U64 phstride, U64 phcount);
|
||||
internal DEMON_LNX_ModuleNode* demon_lnx_module_list_from_process(Arena *arena, DEMON_Entity *process);
|
||||
|
||||
internal U64 demon_lnx_read_memory(int memory_fd, void *dst, U64 src, U64 size);
|
||||
internal B32 demon_lnx_write_memory(int memory_fd, U64 dst, void *src, U64 size);
|
||||
internal String8 demon_lnx_read_memory_str(Arena *arena, int memory_fd, U64 address);
|
||||
|
||||
internal void demon_lnx_regs_x64_from_usr_regs_x64(SYMS_RegX64 *dst, DEMON_LNX_UserRegsX64 *src);
|
||||
internal void demon_lnx_usr_regs_x64_from_regs_x64(DEMON_LNX_UserRegsX64 *dst, SYMS_RegX64 *src);
|
||||
|
||||
internal String8 demon_lnx_read_int_string(int fd);
|
||||
internal B32 demon_lnx_read_expect(int fd, char expect);
|
||||
internal int demon_lnx_read_whitespace(int fd);
|
||||
internal String8 demon_lnx_read_string(Arena *arena, int fd);
|
||||
|
||||
internal int demon_lnx_open_maps(pid_t pid);
|
||||
internal B32 demon_lnx_next_map(Arena *arena, int maps, DEMON_LNX_MapsEntry *entry_out);
|
||||
|
||||
#endif //DEMON_OS_LINUX_H
|
||||
@@ -17,7 +17,6 @@
|
||||
// --- Code Base ---------------------------------------------------------------
|
||||
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "hash_table.h"
|
||||
#include "coff/coff.h"
|
||||
#include "coff/coff_parse.h"
|
||||
@@ -37,7 +36,6 @@
|
||||
#include "llvm/llvm.h"
|
||||
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "hash_table.c"
|
||||
#include "coff/coff.c"
|
||||
#include "coff/coff_parse.c"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,4 +4,154 @@
|
||||
#ifndef LINUX_BASE_H
|
||||
#define LINUX_BASE_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes
|
||||
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <execinfo.h>
|
||||
#include <fcntl.h>
|
||||
#include <features.h>
|
||||
#include <linux/limits.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <spawn.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pid_t gettid(void);
|
||||
int pthread_setname_np(pthread_t thread, const char *name);
|
||||
int pthread_getname_np(pthread_t thread, char *name, size_t size);
|
||||
|
||||
typedef struct tm tm;
|
||||
typedef struct timespec timespec;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Linux Call Interruption Retry Helper
|
||||
|
||||
#define OS_LNX_RETRY_ON_EINTR(expr) \
|
||||
(__extension__({ \
|
||||
__typeof__(expr) __ret; \
|
||||
do { \
|
||||
__ret = (expr); \
|
||||
} while ((__ret == -1) && errno == EINTR); \
|
||||
__ret; \
|
||||
}))
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: File Iterator
|
||||
|
||||
typedef struct OS_LNX_FileIter OS_LNX_FileIter;
|
||||
struct OS_LNX_FileIter
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *dp;
|
||||
String8 path;
|
||||
};
|
||||
StaticAssert(sizeof(Member(FileIter, memory)) >= sizeof(OS_LNX_FileIter), os_lnx_file_iter_size_check);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Safe Call Handler Chain
|
||||
|
||||
typedef struct OS_LNX_SafeCallChain OS_LNX_SafeCallChain;
|
||||
struct OS_LNX_SafeCallChain
|
||||
{
|
||||
OS_LNX_SafeCallChain *next;
|
||||
ThreadEntryPointFunctionType *fail_handler;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entities
|
||||
|
||||
typedef enum OS_LNX_EntityKind
|
||||
{
|
||||
OS_LNX_EntityKind_Thread,
|
||||
OS_LNX_EntityKind_Mutex,
|
||||
OS_LNX_EntityKind_RWMutex,
|
||||
OS_LNX_EntityKind_ConditionVariable,
|
||||
OS_LNX_EntityKind_Barrier,
|
||||
}
|
||||
OS_LNX_EntityKind;
|
||||
|
||||
typedef struct OS_LNX_Entity OS_LNX_Entity;
|
||||
struct OS_LNX_Entity
|
||||
{
|
||||
OS_LNX_Entity *next;
|
||||
OS_LNX_EntityKind kind;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
pthread_t handle;
|
||||
ThreadEntryPointFunctionType *func;
|
||||
void *ptr;
|
||||
} thread;
|
||||
pthread_mutex_t mutex_handle;
|
||||
pthread_rwlock_t rwmutex_handle;
|
||||
struct
|
||||
{
|
||||
pthread_cond_t cond_handle;
|
||||
pthread_mutex_t rwlock_mutex_handle;
|
||||
} cv;
|
||||
pthread_barrier_t barrier;
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: State
|
||||
|
||||
typedef struct OS_LNX_State OS_LNX_State;
|
||||
struct OS_LNX_State
|
||||
{
|
||||
Arena *arena;
|
||||
SystemInfo system_info;
|
||||
ProcessInfo process_info;
|
||||
pthread_mutex_t entity_mutex;
|
||||
Arena *entity_arena;
|
||||
OS_LNX_Entity *entity_free;
|
||||
U64 default_env_count;
|
||||
char **default_env;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global OS_LNX_State os_lnx_state = {0};
|
||||
thread_static OS_LNX_SafeCallChain *os_lnx_safe_call_chain = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
internal DateTime os_lnx_date_time_from_tm(tm in, U32 msec);
|
||||
internal tm os_lnx_tm_from_date_time(DateTime dt);
|
||||
internal timespec os_lnx_timespec_from_date_time(DateTime dt);
|
||||
internal DenseTime os_lnx_dense_time_from_timespec(timespec in);
|
||||
internal FileProperties os_lnx_file_properties_from_stat(struct stat *s);
|
||||
internal void os_lnx_safe_call_sig_handler(int x);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entities
|
||||
|
||||
internal OS_LNX_Entity *os_lnx_entity_alloc(OS_LNX_EntityKind kind);
|
||||
internal void os_lnx_entity_release(OS_LNX_Entity *entity);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Entry Point
|
||||
|
||||
internal void *os_lnx_thread_entry_point(void *ptr);
|
||||
|
||||
#endif // LINUX_BASE_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,442 +1,502 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef DEMON_CORE_LINUX_H
|
||||
#define DEMON_CORE_LINUX_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ TLS
|
||||
|
||||
typedef struct DMN_LNX_DbDesc
|
||||
{
|
||||
U32 bit_size;
|
||||
U32 count;
|
||||
U32 offset;
|
||||
} DMN_LNX_DbDesc;
|
||||
|
||||
////////////////////////////////
|
||||
//~ SDT Probes
|
||||
|
||||
typedef struct DMN_LNX_Probe
|
||||
{
|
||||
String8 provider;
|
||||
String8 name;
|
||||
String8 args_string;
|
||||
STAP_ArgArray args;
|
||||
U64 pc;
|
||||
U64 semaphore;
|
||||
} DMN_LNX_Probe;
|
||||
|
||||
typedef struct DMN_LNX_ProbeNode
|
||||
{
|
||||
DMN_LNX_Probe v;
|
||||
struct DMN_LNX_ProbeNode *next;
|
||||
} DMN_LNX_ProbeNode;
|
||||
|
||||
typedef struct DMN_LNX_ProbeList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ProbeNode *first;
|
||||
DMN_LNX_ProbeNode *last;
|
||||
} DMN_LNX_ProbeList;
|
||||
|
||||
#define DMN_LNX_Probe_XList \
|
||||
X(InitStart, 2, "init_start") \
|
||||
X(InitComplete, 2, "init_complete") \
|
||||
X(RelocStart, 2, "reloc_start") \
|
||||
X(RelocComplete, 3, "reloc_complete") \
|
||||
X(MapStart, 2, "map_start") \
|
||||
X(MapComplete, 3, "map_complete") \
|
||||
X(UnmapStart, 2, "unmap_start") \
|
||||
X(UnmapComplete, 2, "unmap_complete") \
|
||||
X(LongJmp, 3, "longjmp") \
|
||||
X(LongJmpTarget, 3, "longjmp_target") \
|
||||
X(SetJmp, 3, "setjmp")
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMN_LNX_ProbeType_Null,
|
||||
#define X(_N,...) DMN_LNX_ProbeType_##_N,
|
||||
DMN_LNX_Probe_XList
|
||||
#undef X
|
||||
DMN_LNX_ProbeType_Count,
|
||||
} DMN_LNX_ProbeType;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Info
|
||||
|
||||
typedef struct DMN_LNX_Auxv
|
||||
{
|
||||
U64 base;
|
||||
U64 phnum;
|
||||
U64 phent;
|
||||
U64 phdr;
|
||||
U64 execfn;
|
||||
U64 pagesz;
|
||||
} DMN_LNX_Auxv;
|
||||
|
||||
typedef struct DMN_LNX_DynamicInfo
|
||||
{
|
||||
U64 hash_vaddr;
|
||||
U64 gnu_hash_vaddr;
|
||||
U64 strtab_vaddr;
|
||||
U64 strtab_size;
|
||||
U64 symtab_vaddr;
|
||||
U64 symtab_entry_size;
|
||||
} DMN_LNX_DynamicInfo;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Entities
|
||||
|
||||
typedef enum DMN_LNX_EntityKind
|
||||
{
|
||||
DMN_LNX_EntityKind_Null,
|
||||
DMN_LNX_EntityKind_Process,
|
||||
DMN_LNX_EntityKind_ProcessCtx,
|
||||
DMN_LNX_EntityKind_Thread,
|
||||
DMN_LNX_EntityKind_Module,
|
||||
} DMN_LNX_EntityKind;
|
||||
|
||||
typedef enum DMN_LNX_ThreadState
|
||||
{
|
||||
DMN_LNX_ThreadState_Null,
|
||||
DMN_LNX_ThreadState_Running,
|
||||
DMN_LNX_ThreadState_Stopped,
|
||||
DMN_LNX_ThreadState_Exited,
|
||||
DMN_LNX_ThreadState_PendingCreation,
|
||||
} DMN_LNX_ThreadState;
|
||||
|
||||
typedef struct DMN_LNX_Thread
|
||||
{
|
||||
pid_t tid;
|
||||
DMN_LNX_ThreadState state;
|
||||
struct DMN_LNX_Process *process;
|
||||
void *reg_block;
|
||||
B32 is_reg_block_dirty;
|
||||
B32 pass_through_signal;
|
||||
U64 pass_through_signo;
|
||||
U64 orig_rax;
|
||||
|
||||
struct DMN_LNX_Thread *next;
|
||||
struct DMN_LNX_Thread *prev;
|
||||
} DMN_LNX_Thread;
|
||||
|
||||
typedef struct DMN_LNX_ThreadPtrNode
|
||||
{
|
||||
DMN_LNX_Thread *v;
|
||||
struct DMN_LNX_ThreadPtrNode *next;
|
||||
struct DMN_LNX_ThreadPtrNode *prev;
|
||||
} DMN_LNX_ThreadPtrNode;
|
||||
|
||||
typedef struct DMN_LNX_ThreadPtrList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ThreadPtrNode *first;
|
||||
DMN_LNX_ThreadPtrNode *last;
|
||||
} DMN_LNX_ThreadPtrList;
|
||||
|
||||
typedef struct DMN_LNX_Module
|
||||
{
|
||||
U64 name_vaddr;
|
||||
U64 base_vaddr;
|
||||
U64 name_space_id;
|
||||
U64 size;
|
||||
U64 phvaddr;
|
||||
U64 phentsize;
|
||||
U64 phcount;
|
||||
U64 tls_index;
|
||||
U64 tls_offset;
|
||||
B8 is_live;
|
||||
B8 is_main;
|
||||
|
||||
struct DMN_LNX_Module *next;
|
||||
struct DMN_LNX_Module *prev;
|
||||
} DMN_LNX_Module;
|
||||
|
||||
typedef struct DMN_LNX_ModulePtrNode
|
||||
{
|
||||
DMN_LNX_Module *v;
|
||||
struct DMN_LNX_ModulePtrNode *next;
|
||||
} DMN_LNX_ModulePtrNode;
|
||||
|
||||
typedef struct DMN_LNX_ModulePtrList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ModulePtrNode *first;
|
||||
DMN_LNX_ModulePtrNode *last;
|
||||
} DMN_LNX_ModulePtrList;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMN_LNX_ProcessState_Null,
|
||||
DMN_LNX_ProcessState_Launch,
|
||||
DMN_LNX_ProcessState_Attach,
|
||||
DMN_LNX_ProcessState_WaitForExec,
|
||||
DMN_LNX_ProcessState_ExecFailedDoExit,
|
||||
DMN_LNX_ProcessState_Normal,
|
||||
} DMN_LNX_ProcessState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMN_LNX_CreateProcessFlag_DebugSubprocesses = (1 << 0),
|
||||
DMN_LNX_CreateProcessFlag_Rebased = (1 << 1),
|
||||
DMN_LNX_CreateProcessFlag_Cow = (1 << 2),
|
||||
DMN_LNX_CreateProcessFlag_ClonedMemory = (1 << 3),
|
||||
} DMN_LNX_CreateProcessFlags;
|
||||
|
||||
typedef struct DMN_LNX_Process
|
||||
{
|
||||
pid_t pid;
|
||||
int fd;
|
||||
DMN_LNX_ProcessState state;
|
||||
B32 debug_subprocesses;
|
||||
B32 is_cow;
|
||||
B32 vfork_with_spoof;
|
||||
U64 thread_count;
|
||||
DMN_LNX_Thread *first_thread;
|
||||
DMN_LNX_Thread *last_thread;
|
||||
U64 main_thread_exit_code;
|
||||
struct DMN_LNX_Process *parent_process;
|
||||
struct DMN_LNX_ProcessCtx *ctx;
|
||||
|
||||
|
||||
struct DMN_LNX_Process *next;
|
||||
struct DMN_LNX_Process *prev;
|
||||
} DMN_LNX_Process;
|
||||
|
||||
typedef struct DMN_LNX_ProcessPtrNode
|
||||
{
|
||||
DMN_LNX_Process *v;
|
||||
struct DMN_LNX_ProcessPtrNode *next;
|
||||
} DMN_LNX_ProcessPtrNode;
|
||||
|
||||
typedef struct DMN_LNX_ProcessPtrList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ProcessPtrNode *first;
|
||||
DMN_LNX_ProcessPtrNode *last;
|
||||
} DMN_LNX_ProcessPtrList;
|
||||
|
||||
typedef struct DMN_LNX_ProcessCtx
|
||||
{
|
||||
Arena *arena;
|
||||
Arch arch;
|
||||
U64 rdebug_vaddr;
|
||||
ELF_Class dl_class;
|
||||
HashTable *loaded_modules_ht;
|
||||
DMN_LNX_Probe **probes;
|
||||
DMN_ActiveTrap *first_probe_trap;
|
||||
DMN_ActiveTrap *last_probe_trap;
|
||||
DMN_LNX_Module *first_module;
|
||||
DMN_LNX_Module *last_module;
|
||||
U64 module_count;
|
||||
U64 ref_count;
|
||||
|
||||
String8List free_reg_blocks;
|
||||
String8List free_reg_block_nodes;
|
||||
|
||||
// x64
|
||||
U64 xcr0;
|
||||
U64 xsave_size;
|
||||
X64_XSaveLayout xsave_layout;
|
||||
} DMN_LNX_ProcessCtx;
|
||||
|
||||
typedef struct DMN_LNX_Entity
|
||||
{
|
||||
union
|
||||
{
|
||||
DMN_LNX_Process process;
|
||||
DMN_LNX_ProcessCtx process_ctx;
|
||||
DMN_LNX_Thread thread;
|
||||
DMN_LNX_Module module;
|
||||
struct
|
||||
{
|
||||
struct DMN_LNX_Entity *next;
|
||||
};
|
||||
};
|
||||
U32 gen;
|
||||
DMN_LNX_EntityKind kind;
|
||||
} DMN_LNX_Entity;
|
||||
|
||||
typedef struct DMN_LNX_EntityNode
|
||||
{
|
||||
DMN_LNX_Entity *v;
|
||||
struct DMN_LNX_EntityNode *next;
|
||||
} DMN_LNX_EntityNode;
|
||||
|
||||
typedef struct DMN_LNX_EntityList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_EntityNode *first;
|
||||
DMN_LNX_EntityNode *last;
|
||||
} DMN_LNX_EntityList;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Global State
|
||||
|
||||
typedef struct DMN_LNX_State
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
// rjf: access locking mechanism
|
||||
Mutex access_mutex;
|
||||
B32 access_run_state;
|
||||
|
||||
// rjf: entity storage
|
||||
Arena *entities_arena;
|
||||
DMN_LNX_Entity *entities_base;
|
||||
DMN_LNX_Entity *free_entity;
|
||||
U64 entities_count;
|
||||
|
||||
HashTable *tid_ht; // thread id -> thread entity
|
||||
HashTable *pid_ht; // process id -> process entity
|
||||
|
||||
// process tracking
|
||||
U64 process_count;
|
||||
DMN_LNX_Process *first_process;
|
||||
DMN_LNX_Process *last_process;
|
||||
|
||||
// process/thread creation tracking
|
||||
U64 process_pending_creation;
|
||||
U64 threads_pending_creation;
|
||||
|
||||
// halter
|
||||
Mutex halter_mutex;
|
||||
pid_t halter_tid;
|
||||
U64 halt_code;
|
||||
U64 halt_user_data;
|
||||
B32 is_halting;
|
||||
|
||||
// TLS
|
||||
B32 is_tls_detected;
|
||||
DMN_LNX_DbDesc tls_modid_desc;
|
||||
DMN_LNX_DbDesc tls_offset_desc;
|
||||
} DMN_LNX_State;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Globals
|
||||
|
||||
global B32 dmn_lnx_ctrl_thread;
|
||||
global DMN_LNX_State *dmn_lnx_state;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Memory R/W
|
||||
|
||||
internal U64 dmn_lnx_read(int memory_fd, Rng1U64 range, void *dst);
|
||||
internal B32 dmn_lnx_write(int memory_fd, Rng1U64 range, void *src);
|
||||
internal String8 dmn_lnx_read_string_capped(Arena *arena, int memory_fd, U64 base_vaddr, U64 cap_size);
|
||||
internal String8 dmn_lnx_read_string(Arena *arena, int memory_fd, U64 base_vaddr);
|
||||
#define dmn_lnx_read_struct(fd, vaddr, ptr) dmn_lnx_read((fd), r1u64((vaddr), (vaddr)+sizeof(*(ptr))), (ptr))
|
||||
#define dmn_lnx_write_struct(fd, vaddr, ptr) dmn_lnx_write((fd), r1u64((vaddr), (vaddr)+sizeof(*(ptr))), (ptr))
|
||||
|
||||
////////////////////////////////
|
||||
//~ ELF/GNU info
|
||||
|
||||
internal Rng1U64 dmn_lnx_compute_image_vrange(int memory_fd, ELF_Class elf_class, U64 rebase, U64 e_phaddr, U64 e_phentsize, U64 e_phnum);
|
||||
internal DMN_LNX_DynamicInfo dmn_lnx_dynamic_info_from_memory(int memory_fd, ELF_Class elf_Class, U64 rebase, U64 dynamic_vaddr);
|
||||
internal U64 dmn_lnx_rdebug_vaddr_from_memory(int memory_fd, U64 loader_vaddr, B32 is_rebased);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Info
|
||||
|
||||
internal String8 dmn_lnx_exe_path_from_pid(Arena *arena, pid_t pid);
|
||||
internal String8 dmn_lnx_dl_path_from_pid(Arena *arena, pid_t pid, U64 auxv_base);
|
||||
internal ELF_Hdr64 dmn_lnx_ehdr_from_pid(pid_t pid);
|
||||
internal DMN_LNX_Auxv dmn_lnx_auxv_from_pid(pid_t pid, ELF_Class elf_class);
|
||||
internal DMN_LNX_Thread * dmn_lnx_thread_from_pid(pid_t pid);
|
||||
internal DMN_LNX_Process * dmn_lnx_process_from_pid(pid_t pid);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Entity
|
||||
|
||||
// alloc
|
||||
internal DMN_LNX_Entity * dmn_lnx_entity_alloc(DMN_LNX_EntityKind kind);
|
||||
internal DMN_LNX_Process * dmn_lnx_process_alloc(pid_t pid, DMN_LNX_ProcessState state, DMN_LNX_Process *parent_process, B32 debug_subprocess, B32 is_cow);
|
||||
internal DMN_LNX_ProcessCtx * dmn_lnx_process_ctx_alloc(DMN_LNX_Process *process, B32 is_rebased);
|
||||
internal DMN_LNX_Thread * dmn_lnx_thread_alloc(DMN_LNX_Process *process, DMN_LNX_ThreadState thread_state, pid_t tid);
|
||||
internal DMN_LNX_Module * dmn_lnx_module_alloc(DMN_LNX_ProcessCtx *ctx, int memory_fd, U64 base_vaddr, U64 name_vaddr, U64 name_space_id, B32 is_main);
|
||||
|
||||
// release
|
||||
internal void dmn_lnx_entity_release(DMN_LNX_Entity *entity);
|
||||
internal void dmn_lnx_process_release(DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_process_ctx_release(DMN_LNX_ProcessCtx *process_ctx);
|
||||
internal void dmn_lnx_thread_release(DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_module_release(DMN_LNX_ProcessCtx *ctx, DMN_LNX_Module *module);
|
||||
|
||||
// clone
|
||||
internal DMN_LNX_ProcessCtx * dmn_lnx_process_ctx_clone(DMN_LNX_Process *process, DMN_LNX_ProcessCtx *ctx);
|
||||
internal DMN_LNX_Module * dmn_lnx_module_clone(DMN_LNX_ProcessCtx *process_ctx, DMN_LNX_Module *module);
|
||||
|
||||
// entity -> handle
|
||||
internal DMN_Handle dmn_lnx_handle_from_entity(DMN_LNX_Entity *entity);
|
||||
internal DMN_Handle dmn_lnx_handle_from_process(DMN_LNX_Process *process);
|
||||
internal DMN_Handle dmn_lnx_handle_from_process_ctx(DMN_LNX_ProcessCtx *process_ctx);
|
||||
internal DMN_Handle dmn_lnx_handle_from_thread(DMN_LNX_Thread *thread);
|
||||
internal DMN_Handle dmn_lnx_handle_from_module(DMN_LNX_Module *module);
|
||||
|
||||
// handle -> entity
|
||||
internal DMN_LNX_Entity * dmn_lnx_entity_from_handle(DMN_Handle handle, DMN_LNX_EntityKind expected_kind);
|
||||
internal DMN_LNX_Process * dmn_lnx_process_from_handle(DMN_Handle process_handle);
|
||||
internal DMN_LNX_ProcessCtx * dmn_lnx_process_ctx_from_handle(DMN_Handle process_ctx_handle);
|
||||
internal DMN_LNX_Thread * dmn_lnx_thread_from_handle(DMN_Handle thread_handle);
|
||||
internal DMN_LNX_Module * dmn_lnx_module_from_handle(DMN_Handle module_handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Helpers
|
||||
|
||||
internal void dmn_lnx_process_trap_probes(DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_process_untrap_probes(DMN_LNX_Process *process);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Thread Helpers
|
||||
|
||||
internal U64 dmn_lnx_thread_read_ip(DMN_LNX_Thread *thread);
|
||||
internal U64 dmn_lnx_thread_read_sp(DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_thread_write_ip(DMN_LNX_Thread *thread, U64 ip);
|
||||
internal void dmn_lnx_thread_write_sp(DMN_LNX_Thread *thread, U64 sp);
|
||||
internal B32 dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread);
|
||||
internal B32 dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread);
|
||||
internal B32 dmn_lnx_set_single_step_flag(DMN_LNX_Thread *thread, B32 is_on);
|
||||
|
||||
////////////////////////////////
|
||||
//~ List Helpers
|
||||
|
||||
internal void dmn_lnx_thread_ptr_list_push_node(DMN_LNX_ThreadPtrList *list, DMN_LNX_ThreadPtrNode *n);
|
||||
internal DMN_LNX_ThreadPtrNode * dmn_lnx_thread_ptr_list_push(Arena *arena, DMN_LNX_ThreadPtrList *list, DMN_LNX_Thread *v);
|
||||
internal DMN_LNX_ModulePtrNode * dmn_lnx_module_ptr_list_push(Arena *arena, DMN_LNX_ModulePtrList *list, DMN_LNX_Module *v);
|
||||
internal DMN_LNX_ProcessPtrNode * dmn_lnx_process_ptr_list_push(Arena *arena, DMN_LNX_ProcessPtrList *list, DMN_LNX_Process *v);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Debug Event Pushers
|
||||
|
||||
internal void dmn_lnx_push_event_create_process(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_push_event_exit_process(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_push_event_create_thread(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_push_event_exit_thread(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 exit_code);
|
||||
internal void dmn_lnx_push_event_load_module(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, DMN_LNX_Module *module);
|
||||
internal void dmn_lnx_push_event_unload_module(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process, DMN_LNX_Module *module);
|
||||
internal void dmn_lnx_push_event_handshake_complete(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_push_event_breakpoint(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 address);
|
||||
internal void dmn_lnx_push_event_single_step(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_push_event_exception(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 signo);
|
||||
internal void dmn_lnx_push_event_halt(Arena *arena, DMN_EventList *events);
|
||||
internal void dmn_lnx_push_event_not_attached(Arena *arena, DMN_EventList *events);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Debug Event
|
||||
|
||||
internal DMN_LNX_Thread * dmn_lnx_event_create_thread(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process, pid_t tid);
|
||||
internal void dmn_lnx_event_exit_thread(Arena *arena, DMN_EventList *events, pid_t tid, U64 exit_code);
|
||||
internal DMN_LNX_Process * dmn_lnx_event_create_process(Arena *arena, DMN_EventList *events, pid_t pid, DMN_LNX_Process *parent_process, DMN_LNX_CreateProcessFlags flags);
|
||||
internal void dmn_lnx_event_exit_process(Arena *arena, DMN_EventList *events, pid_t pid);
|
||||
internal void dmn_lnx_event_load_module(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 name_space_id, U64 new_link_map_vaddr);
|
||||
internal void dmn_lnx_event_unload_module(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process, U64 rdebug_vaddr);
|
||||
internal void dmn_lnx_event_breakpoint(Arena *arena, DMN_EventList *events, DMN_ActiveTrap *user_traps, pid_t tid);
|
||||
internal void dmn_lnx_event_data_breakpoint(Arena *arena, DMN_EventList *events, pid_t tid);
|
||||
internal void dmn_lnx_event_halt(Arena *arena, DMN_EventList *events);
|
||||
internal void dmn_lnx_event_single_step(Arena *arena, DMN_EventList *events, pid_t tid);
|
||||
internal void dmn_lnx_event_exception(Arena *arena, DMN_EventList *events, pid_t tid, U64 signo);
|
||||
internal DMN_LNX_Process * dmn_lnx_event_attach(Arena *arena, DMN_EventList *events, pid_t pid);
|
||||
|
||||
#endif // DEMON_CORE_LINUX_H
|
||||
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef DEMON_CORE_LINUX_H
|
||||
#define DEMON_CORE_LINUX_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Register Layouts
|
||||
//
|
||||
// These are defined in <sys/user.h>, but only for one architecture at a time
|
||||
|
||||
typedef struct OS_LNX_GprsX64 OS_LNX_GprsX64;
|
||||
struct OS_LNX_GprsX64
|
||||
{
|
||||
U64 r15;
|
||||
U64 r14;
|
||||
U64 r13;
|
||||
U64 r12;
|
||||
U64 rbp;
|
||||
U64 rbx;
|
||||
U64 r11;
|
||||
U64 r10;
|
||||
U64 r9;
|
||||
U64 r8;
|
||||
U64 rax;
|
||||
U64 rcx;
|
||||
U64 rdx;
|
||||
U64 rsi;
|
||||
U64 rdi;
|
||||
U64 orig_rax;
|
||||
U64 rip;
|
||||
U64 cs;
|
||||
U64 rflags;
|
||||
U64 rsp;
|
||||
U64 ss;
|
||||
U64 fsbase;
|
||||
U64 gsbase;
|
||||
U64 ds;
|
||||
U64 es;
|
||||
U64 fs;
|
||||
U64 gs;
|
||||
};
|
||||
|
||||
typedef struct OS_LNX_UserX64 OS_LNX_UserX64;
|
||||
struct OS_LNX_UserX64
|
||||
{
|
||||
OS_LNX_GprsX64 regs;
|
||||
S32 u_fpvalid;
|
||||
U32 _pad0;
|
||||
X64_FXSave i387;
|
||||
U64 u_tsize;
|
||||
U64 u_dsize;
|
||||
U64 u_ssize;
|
||||
U64 start_code;
|
||||
U64 start_stack;
|
||||
U64 signal;
|
||||
U32 reserved;
|
||||
U32 _pad1;
|
||||
U64 u_ar0;
|
||||
U64 u_fpstate;
|
||||
U64 magic;
|
||||
U8 u_comm[32];
|
||||
U64 u_debugreg[8];
|
||||
};
|
||||
StaticAssert(sizeof(OS_LNX_UserX64) == 912, g_os_lnx_user_x64_size_check);
|
||||
|
||||
////////////////////////////////
|
||||
//~ TLS
|
||||
|
||||
typedef struct DMN_LNX_DbDesc
|
||||
{
|
||||
U32 bit_size;
|
||||
U32 count;
|
||||
U32 offset;
|
||||
} DMN_LNX_DbDesc;
|
||||
|
||||
////////////////////////////////
|
||||
//~ SDT Probes
|
||||
|
||||
typedef struct DMN_LNX_Probe
|
||||
{
|
||||
String8 provider;
|
||||
String8 name;
|
||||
String8 args_string;
|
||||
STAP_ArgArray args;
|
||||
U64 pc;
|
||||
U64 semaphore;
|
||||
} DMN_LNX_Probe;
|
||||
|
||||
typedef struct DMN_LNX_ProbeNode
|
||||
{
|
||||
DMN_LNX_Probe v;
|
||||
struct DMN_LNX_ProbeNode *next;
|
||||
} DMN_LNX_ProbeNode;
|
||||
|
||||
typedef struct DMN_LNX_ProbeList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ProbeNode *first;
|
||||
DMN_LNX_ProbeNode *last;
|
||||
} DMN_LNX_ProbeList;
|
||||
|
||||
#define DMN_LNX_Probe_XList \
|
||||
X(InitStart, 2, "init_start") \
|
||||
X(InitComplete, 2, "init_complete") \
|
||||
X(RelocStart, 2, "reloc_start") \
|
||||
X(RelocComplete, 3, "reloc_complete") \
|
||||
X(MapStart, 2, "map_start") \
|
||||
X(MapComplete, 3, "map_complete") \
|
||||
X(UnmapStart, 2, "unmap_start") \
|
||||
X(UnmapComplete, 2, "unmap_complete") \
|
||||
X(LongJmp, 3, "longjmp") \
|
||||
X(LongJmpTarget, 3, "longjmp_target") \
|
||||
X(SetJmp, 3, "setjmp")
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMN_LNX_ProbeType_Null,
|
||||
#define X(_N,...) DMN_LNX_ProbeType_##_N,
|
||||
DMN_LNX_Probe_XList
|
||||
#undef X
|
||||
DMN_LNX_ProbeType_Count,
|
||||
} DMN_LNX_ProbeType;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Info
|
||||
|
||||
typedef struct DMN_LNX_Auxv
|
||||
{
|
||||
U64 base;
|
||||
U64 phnum;
|
||||
U64 phent;
|
||||
U64 phdr;
|
||||
U64 execfn;
|
||||
U64 pagesz;
|
||||
} DMN_LNX_Auxv;
|
||||
|
||||
typedef struct DMN_LNX_DynamicInfo
|
||||
{
|
||||
U64 hash_vaddr;
|
||||
U64 gnu_hash_vaddr;
|
||||
U64 strtab_vaddr;
|
||||
U64 strtab_size;
|
||||
U64 symtab_vaddr;
|
||||
U64 symtab_entry_size;
|
||||
} DMN_LNX_DynamicInfo;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Entities
|
||||
|
||||
typedef enum DMN_LNX_EntityKind
|
||||
{
|
||||
DMN_LNX_EntityKind_Null,
|
||||
DMN_LNX_EntityKind_Process,
|
||||
DMN_LNX_EntityKind_ProcessCtx,
|
||||
DMN_LNX_EntityKind_Thread,
|
||||
DMN_LNX_EntityKind_Module,
|
||||
} DMN_LNX_EntityKind;
|
||||
|
||||
typedef enum DMN_LNX_ThreadState
|
||||
{
|
||||
DMN_LNX_ThreadState_Null,
|
||||
DMN_LNX_ThreadState_Running,
|
||||
DMN_LNX_ThreadState_Stopped,
|
||||
DMN_LNX_ThreadState_Exited,
|
||||
DMN_LNX_ThreadState_PendingCreation,
|
||||
} DMN_LNX_ThreadState;
|
||||
|
||||
typedef struct DMN_LNX_Thread
|
||||
{
|
||||
pid_t tid;
|
||||
DMN_LNX_ThreadState state;
|
||||
struct DMN_LNX_Process *process;
|
||||
void *reg_block;
|
||||
B32 is_reg_block_dirty;
|
||||
B32 pass_through_signal;
|
||||
U64 pass_through_signo;
|
||||
U64 orig_rax;
|
||||
|
||||
struct DMN_LNX_Thread *next;
|
||||
struct DMN_LNX_Thread *prev;
|
||||
} DMN_LNX_Thread;
|
||||
|
||||
typedef struct DMN_LNX_ThreadPtrNode
|
||||
{
|
||||
DMN_LNX_Thread *v;
|
||||
struct DMN_LNX_ThreadPtrNode *next;
|
||||
struct DMN_LNX_ThreadPtrNode *prev;
|
||||
} DMN_LNX_ThreadPtrNode;
|
||||
|
||||
typedef struct DMN_LNX_ThreadPtrList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ThreadPtrNode *first;
|
||||
DMN_LNX_ThreadPtrNode *last;
|
||||
} DMN_LNX_ThreadPtrList;
|
||||
|
||||
typedef struct DMN_LNX_Module
|
||||
{
|
||||
U64 name_vaddr;
|
||||
U64 base_vaddr;
|
||||
U64 name_space_id;
|
||||
U64 size;
|
||||
U64 phvaddr;
|
||||
U64 phentsize;
|
||||
U64 phcount;
|
||||
U64 tls_index;
|
||||
U64 tls_offset;
|
||||
B8 is_live;
|
||||
B8 is_main;
|
||||
|
||||
struct DMN_LNX_Module *next;
|
||||
struct DMN_LNX_Module *prev;
|
||||
} DMN_LNX_Module;
|
||||
|
||||
typedef struct DMN_LNX_ModulePtrNode
|
||||
{
|
||||
DMN_LNX_Module *v;
|
||||
struct DMN_LNX_ModulePtrNode *next;
|
||||
} DMN_LNX_ModulePtrNode;
|
||||
|
||||
typedef struct DMN_LNX_ModulePtrList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ModulePtrNode *first;
|
||||
DMN_LNX_ModulePtrNode *last;
|
||||
} DMN_LNX_ModulePtrList;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMN_LNX_ProcessState_Null,
|
||||
DMN_LNX_ProcessState_Launch,
|
||||
DMN_LNX_ProcessState_Attach,
|
||||
DMN_LNX_ProcessState_WaitForExec,
|
||||
DMN_LNX_ProcessState_ExecFailedDoExit,
|
||||
DMN_LNX_ProcessState_Normal,
|
||||
} DMN_LNX_ProcessState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMN_LNX_CreateProcessFlag_DebugSubprocesses = (1 << 0),
|
||||
DMN_LNX_CreateProcessFlag_Rebased = (1 << 1),
|
||||
DMN_LNX_CreateProcessFlag_Cow = (1 << 2),
|
||||
DMN_LNX_CreateProcessFlag_ClonedMemory = (1 << 3),
|
||||
} DMN_LNX_CreateProcessFlags;
|
||||
|
||||
typedef struct DMN_LNX_Process
|
||||
{
|
||||
pid_t pid;
|
||||
int fd;
|
||||
DMN_LNX_ProcessState state;
|
||||
B32 debug_subprocesses;
|
||||
B32 is_cow;
|
||||
B32 vfork_with_spoof;
|
||||
U64 thread_count;
|
||||
DMN_LNX_Thread *first_thread;
|
||||
DMN_LNX_Thread *last_thread;
|
||||
U64 main_thread_exit_code;
|
||||
struct DMN_LNX_Process *parent_process;
|
||||
struct DMN_LNX_ProcessCtx *ctx;
|
||||
|
||||
|
||||
struct DMN_LNX_Process *next;
|
||||
struct DMN_LNX_Process *prev;
|
||||
} DMN_LNX_Process;
|
||||
|
||||
typedef struct DMN_LNX_ProcessPtrNode
|
||||
{
|
||||
DMN_LNX_Process *v;
|
||||
struct DMN_LNX_ProcessPtrNode *next;
|
||||
} DMN_LNX_ProcessPtrNode;
|
||||
|
||||
typedef struct DMN_LNX_ProcessPtrList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_ProcessPtrNode *first;
|
||||
DMN_LNX_ProcessPtrNode *last;
|
||||
} DMN_LNX_ProcessPtrList;
|
||||
|
||||
typedef struct DMN_LNX_ProcessCtx
|
||||
{
|
||||
Arena *arena;
|
||||
Arch arch;
|
||||
U64 rdebug_vaddr;
|
||||
ELF_Class dl_class;
|
||||
HashTable *loaded_modules_ht;
|
||||
DMN_LNX_Probe **probes;
|
||||
DMN_ActiveTrap *first_probe_trap;
|
||||
DMN_ActiveTrap *last_probe_trap;
|
||||
DMN_LNX_Module *first_module;
|
||||
DMN_LNX_Module *last_module;
|
||||
U64 module_count;
|
||||
U64 ref_count;
|
||||
|
||||
String8List free_reg_blocks;
|
||||
String8List free_reg_block_nodes;
|
||||
|
||||
// x64
|
||||
U64 xcr0;
|
||||
U64 xsave_size;
|
||||
X64_XSaveLayout xsave_layout;
|
||||
} DMN_LNX_ProcessCtx;
|
||||
|
||||
typedef struct DMN_LNX_Entity
|
||||
{
|
||||
union
|
||||
{
|
||||
DMN_LNX_Process process;
|
||||
DMN_LNX_ProcessCtx process_ctx;
|
||||
DMN_LNX_Thread thread;
|
||||
DMN_LNX_Module module;
|
||||
struct
|
||||
{
|
||||
struct DMN_LNX_Entity *next;
|
||||
};
|
||||
};
|
||||
U32 gen;
|
||||
DMN_LNX_EntityKind kind;
|
||||
} DMN_LNX_Entity;
|
||||
|
||||
typedef struct DMN_LNX_EntityNode
|
||||
{
|
||||
DMN_LNX_Entity *v;
|
||||
struct DMN_LNX_EntityNode *next;
|
||||
} DMN_LNX_EntityNode;
|
||||
|
||||
typedef struct DMN_LNX_EntityList
|
||||
{
|
||||
U64 count;
|
||||
DMN_LNX_EntityNode *first;
|
||||
DMN_LNX_EntityNode *last;
|
||||
} DMN_LNX_EntityList;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Global State
|
||||
|
||||
typedef struct DMN_LNX_State
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
// rjf: access locking mechanism
|
||||
Mutex access_mutex;
|
||||
B32 access_run_state;
|
||||
|
||||
// rjf: entity storage
|
||||
Arena *entities_arena;
|
||||
DMN_LNX_Entity *entities_base;
|
||||
DMN_LNX_Entity *free_entity;
|
||||
U64 entities_count;
|
||||
|
||||
HashTable *tid_ht; // thread id -> thread entity
|
||||
HashTable *pid_ht; // process id -> process entity
|
||||
|
||||
// process tracking
|
||||
U64 process_count;
|
||||
DMN_LNX_Process *first_process;
|
||||
DMN_LNX_Process *last_process;
|
||||
|
||||
// process/thread creation tracking
|
||||
U64 process_pending_creation;
|
||||
U64 threads_pending_creation;
|
||||
|
||||
// halter
|
||||
Mutex halter_mutex;
|
||||
pid_t halter_tid;
|
||||
U64 halt_code;
|
||||
U64 halt_user_data;
|
||||
B32 is_halting;
|
||||
|
||||
// TLS
|
||||
B32 is_tls_detected;
|
||||
DMN_LNX_DbDesc tls_modid_desc;
|
||||
DMN_LNX_DbDesc tls_offset_desc;
|
||||
} DMN_LNX_State;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Globals
|
||||
|
||||
global B32 dmn_lnx_ctrl_thread;
|
||||
global DMN_LNX_State *dmn_lnx_state;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Memory R/W
|
||||
|
||||
internal U64 dmn_lnx_read(int memory_fd, Rng1U64 range, void *dst);
|
||||
internal B32 dmn_lnx_write(int memory_fd, Rng1U64 range, void *src);
|
||||
internal String8 dmn_lnx_read_string_capped(Arena *arena, int memory_fd, U64 base_vaddr, U64 cap_size);
|
||||
internal String8 dmn_lnx_read_string(Arena *arena, int memory_fd, U64 base_vaddr);
|
||||
#define dmn_lnx_read_struct(fd, vaddr, ptr) dmn_lnx_read((fd), r1u64((vaddr), (vaddr)+sizeof(*(ptr))), (ptr))
|
||||
#define dmn_lnx_write_struct(fd, vaddr, ptr) dmn_lnx_write((fd), r1u64((vaddr), (vaddr)+sizeof(*(ptr))), (ptr))
|
||||
|
||||
////////////////////////////////
|
||||
//~ ELF/GNU info
|
||||
|
||||
internal Rng1U64 dmn_lnx_compute_image_vrange(int memory_fd, ELF_Class elf_class, U64 rebase, U64 e_phaddr, U64 e_phentsize, U64 e_phnum);
|
||||
internal DMN_LNX_DynamicInfo dmn_lnx_dynamic_info_from_memory(int memory_fd, ELF_Class elf_Class, U64 rebase, U64 dynamic_vaddr);
|
||||
internal U64 dmn_lnx_rdebug_vaddr_from_memory(int memory_fd, U64 loader_vaddr, B32 is_rebased);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Info
|
||||
|
||||
internal String8 dmn_lnx_exe_path_from_pid(Arena *arena, pid_t pid);
|
||||
internal String8 dmn_lnx_dl_path_from_pid(Arena *arena, pid_t pid, U64 auxv_base);
|
||||
internal ELF_Hdr64 dmn_lnx_ehdr_from_pid(pid_t pid);
|
||||
internal DMN_LNX_Auxv dmn_lnx_auxv_from_pid(pid_t pid, ELF_Class elf_class);
|
||||
internal DMN_LNX_Thread * dmn_lnx_thread_from_pid(pid_t pid);
|
||||
internal DMN_LNX_Process * dmn_lnx_process_from_pid(pid_t pid);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Entity
|
||||
|
||||
// alloc
|
||||
internal DMN_LNX_Entity * dmn_lnx_entity_alloc(DMN_LNX_EntityKind kind);
|
||||
internal DMN_LNX_Process * dmn_lnx_process_alloc(pid_t pid, DMN_LNX_ProcessState state, DMN_LNX_Process *parent_process, B32 debug_subprocess, B32 is_cow);
|
||||
internal DMN_LNX_ProcessCtx * dmn_lnx_process_ctx_alloc(DMN_LNX_Process *process, B32 is_rebased);
|
||||
internal DMN_LNX_Thread * dmn_lnx_thread_alloc(DMN_LNX_Process *process, DMN_LNX_ThreadState thread_state, pid_t tid);
|
||||
internal DMN_LNX_Module * dmn_lnx_module_alloc(DMN_LNX_ProcessCtx *ctx, int memory_fd, U64 base_vaddr, U64 name_vaddr, U64 name_space_id, B32 is_main);
|
||||
|
||||
// release
|
||||
internal void dmn_lnx_entity_release(DMN_LNX_Entity *entity);
|
||||
internal void dmn_lnx_process_release(DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_process_ctx_release(DMN_LNX_ProcessCtx *process_ctx);
|
||||
internal void dmn_lnx_thread_release(DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_module_release(DMN_LNX_ProcessCtx *ctx, DMN_LNX_Module *module);
|
||||
|
||||
// clone
|
||||
internal DMN_LNX_ProcessCtx * dmn_lnx_process_ctx_clone(DMN_LNX_Process *process, DMN_LNX_ProcessCtx *ctx);
|
||||
internal DMN_LNX_Module * dmn_lnx_module_clone(DMN_LNX_ProcessCtx *process_ctx, DMN_LNX_Module *module);
|
||||
|
||||
// entity -> handle
|
||||
internal DMN_Handle dmn_lnx_handle_from_entity(DMN_LNX_Entity *entity);
|
||||
internal DMN_Handle dmn_lnx_handle_from_process(DMN_LNX_Process *process);
|
||||
internal DMN_Handle dmn_lnx_handle_from_process_ctx(DMN_LNX_ProcessCtx *process_ctx);
|
||||
internal DMN_Handle dmn_lnx_handle_from_thread(DMN_LNX_Thread *thread);
|
||||
internal DMN_Handle dmn_lnx_handle_from_module(DMN_LNX_Module *module);
|
||||
|
||||
// handle -> entity
|
||||
internal DMN_LNX_Entity * dmn_lnx_entity_from_handle(DMN_Handle handle, DMN_LNX_EntityKind expected_kind);
|
||||
internal DMN_LNX_Process * dmn_lnx_process_from_handle(DMN_Handle process_handle);
|
||||
internal DMN_LNX_ProcessCtx * dmn_lnx_process_ctx_from_handle(DMN_Handle process_ctx_handle);
|
||||
internal DMN_LNX_Thread * dmn_lnx_thread_from_handle(DMN_Handle thread_handle);
|
||||
internal DMN_LNX_Module * dmn_lnx_module_from_handle(DMN_Handle module_handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Process Helpers
|
||||
|
||||
internal void dmn_lnx_process_trap_probes(DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_process_untrap_probes(DMN_LNX_Process *process);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Thread Helpers
|
||||
|
||||
internal U64 dmn_lnx_thread_read_ip(DMN_LNX_Thread *thread);
|
||||
internal U64 dmn_lnx_thread_read_sp(DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_thread_write_ip(DMN_LNX_Thread *thread, U64 ip);
|
||||
internal void dmn_lnx_thread_write_sp(DMN_LNX_Thread *thread, U64 sp);
|
||||
internal B32 dmn_lnx_thread_read_reg_block(DMN_LNX_Thread *thread);
|
||||
internal B32 dmn_lnx_thread_write_reg_block(DMN_LNX_Thread *thread);
|
||||
internal B32 dmn_lnx_set_single_step_flag(DMN_LNX_Thread *thread, B32 is_on);
|
||||
|
||||
////////////////////////////////
|
||||
//~ List Helpers
|
||||
|
||||
internal void dmn_lnx_thread_ptr_list_push_node(DMN_LNX_ThreadPtrList *list, DMN_LNX_ThreadPtrNode *n);
|
||||
internal DMN_LNX_ThreadPtrNode * dmn_lnx_thread_ptr_list_push(Arena *arena, DMN_LNX_ThreadPtrList *list, DMN_LNX_Thread *v);
|
||||
internal DMN_LNX_ModulePtrNode * dmn_lnx_module_ptr_list_push(Arena *arena, DMN_LNX_ModulePtrList *list, DMN_LNX_Module *v);
|
||||
internal DMN_LNX_ProcessPtrNode * dmn_lnx_process_ptr_list_push(Arena *arena, DMN_LNX_ProcessPtrList *list, DMN_LNX_Process *v);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Debug Event Pushers
|
||||
|
||||
internal void dmn_lnx_push_event_create_process(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_push_event_exit_process(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_push_event_create_thread(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_push_event_exit_thread(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 exit_code);
|
||||
internal void dmn_lnx_push_event_load_module(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, DMN_LNX_Module *module);
|
||||
internal void dmn_lnx_push_event_unload_module(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process, DMN_LNX_Module *module);
|
||||
internal void dmn_lnx_push_event_handshake_complete(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process);
|
||||
internal void dmn_lnx_push_event_breakpoint(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 address);
|
||||
internal void dmn_lnx_push_event_single_step(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread);
|
||||
internal void dmn_lnx_push_event_exception(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 signo);
|
||||
internal void dmn_lnx_push_event_halt(Arena *arena, DMN_EventList *events);
|
||||
internal void dmn_lnx_push_event_not_attached(Arena *arena, DMN_EventList *events);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Debug Event
|
||||
|
||||
internal DMN_LNX_Thread * dmn_lnx_event_create_thread(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process, pid_t tid);
|
||||
internal void dmn_lnx_event_exit_thread(Arena *arena, DMN_EventList *events, pid_t tid, U64 exit_code);
|
||||
internal DMN_LNX_Process * dmn_lnx_event_create_process(Arena *arena, DMN_EventList *events, pid_t pid, DMN_LNX_Process *parent_process, DMN_LNX_CreateProcessFlags flags);
|
||||
internal void dmn_lnx_event_exit_process(Arena *arena, DMN_EventList *events, pid_t pid);
|
||||
internal void dmn_lnx_event_load_module(Arena *arena, DMN_EventList *events, DMN_LNX_Thread *thread, U64 name_space_id, U64 new_link_map_vaddr);
|
||||
internal void dmn_lnx_event_unload_module(Arena *arena, DMN_EventList *events, DMN_LNX_Process *process, U64 rdebug_vaddr);
|
||||
internal void dmn_lnx_event_breakpoint(Arena *arena, DMN_EventList *events, DMN_ActiveTrap *user_traps, pid_t tid);
|
||||
internal void dmn_lnx_event_data_breakpoint(Arena *arena, DMN_EventList *events, pid_t tid);
|
||||
internal void dmn_lnx_event_halt(Arena *arena, DMN_EventList *events);
|
||||
internal void dmn_lnx_event_single_step(Arena *arena, DMN_EventList *events, pid_t tid);
|
||||
internal void dmn_lnx_event_exception(Arena *arena, DMN_EventList *events, pid_t tid, U64 signo);
|
||||
internal DMN_LNX_Process * dmn_lnx_event_attach(Arena *arena, DMN_EventList *events, pid_t pid);
|
||||
|
||||
#endif // DEMON_CORE_LINUX_H
|
||||
|
||||
+719
-719
File diff suppressed because it is too large
Load Diff
@@ -1,61 +1,61 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_GFX_LINUX_H
|
||||
#define OS_GFX_LINUX_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/extensions/sync.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/keysymdef.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Window State
|
||||
|
||||
typedef struct OS_LNX_Window OS_LNX_Window;
|
||||
struct OS_LNX_Window
|
||||
{
|
||||
OS_LNX_Window *next;
|
||||
OS_LNX_Window *prev;
|
||||
Window window;
|
||||
XIC xic;
|
||||
XID counter_xid;
|
||||
U64 counter_value;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: State Bundle
|
||||
|
||||
typedef struct OS_LNX_GfxState OS_LNX_GfxState;
|
||||
struct OS_LNX_GfxState
|
||||
{
|
||||
Arena *arena;
|
||||
Display *display;
|
||||
XIM xim;
|
||||
OS_LNX_Window *first_window;
|
||||
OS_LNX_Window *last_window;
|
||||
OS_LNX_Window *free_window;
|
||||
Atom wm_delete_window_atom;
|
||||
Atom wm_sync_request_atom;
|
||||
Atom wm_sync_request_counter_atom;
|
||||
Cursor cursors[OS_Cursor_COUNT];
|
||||
OS_Cursor last_set_cursor;
|
||||
OS_GfxInfo gfx_info;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global OS_LNX_GfxState *os_lnx_gfx_state = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
internal OS_LNX_Window *os_lnx_window_from_x11window(Window window);
|
||||
|
||||
#endif // OS_GFX_LINUX_H
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_GFX_LINUX_H
|
||||
#define OS_GFX_LINUX_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/extensions/sync.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/keysymdef.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Window State
|
||||
|
||||
typedef struct OS_LNX_Window OS_LNX_Window;
|
||||
struct OS_LNX_Window
|
||||
{
|
||||
OS_LNX_Window *next;
|
||||
OS_LNX_Window *prev;
|
||||
Window window;
|
||||
XIC xic;
|
||||
XID counter_xid;
|
||||
U64 counter_value;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: State Bundle
|
||||
|
||||
typedef struct OS_LNX_GfxState OS_LNX_GfxState;
|
||||
struct OS_LNX_GfxState
|
||||
{
|
||||
Arena *arena;
|
||||
Display *display;
|
||||
XIM xim;
|
||||
OS_LNX_Window *first_window;
|
||||
OS_LNX_Window *last_window;
|
||||
OS_LNX_Window *free_window;
|
||||
Atom wm_delete_window_atom;
|
||||
Atom wm_sync_request_atom;
|
||||
Atom wm_sync_request_counter_atom;
|
||||
Cursor cursors[OS_Cursor_COUNT];
|
||||
OS_Cursor last_set_cursor;
|
||||
OS_GfxInfo gfx_info;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global OS_LNX_GfxState *os_lnx_gfx_state = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
internal OS_LNX_Window *os_lnx_window_from_x11window(Window window);
|
||||
|
||||
#endif // OS_GFX_LINUX_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,215 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_CORE_LINUX_H
|
||||
#define OS_CORE_LINUX_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes
|
||||
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <execinfo.h>
|
||||
#include <fcntl.h>
|
||||
#include <features.h>
|
||||
#include <linux/limits.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <spawn.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pid_t gettid(void);
|
||||
int pthread_setname_np(pthread_t thread, const char *name);
|
||||
int pthread_getname_np(pthread_t thread, char *name, size_t size);
|
||||
|
||||
typedef struct tm tm;
|
||||
typedef struct timespec timespec;
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
#define OS_LNX_RETRY_ON_EINTR(expr) \
|
||||
(__extension__({ \
|
||||
__typeof__(expr) __ret; \
|
||||
do { \
|
||||
__ret = (expr); \
|
||||
} while ((__ret == -1) && errno == EINTR); \
|
||||
__ret; \
|
||||
}))
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Register Layouts
|
||||
//
|
||||
// These are defined in <sys/user.h>, but only for one architecture at a time
|
||||
|
||||
typedef struct OS_LNX_GprsX64 OS_LNX_GprsX64;
|
||||
struct OS_LNX_GprsX64
|
||||
{
|
||||
U64 r15;
|
||||
U64 r14;
|
||||
U64 r13;
|
||||
U64 r12;
|
||||
U64 rbp;
|
||||
U64 rbx;
|
||||
U64 r11;
|
||||
U64 r10;
|
||||
U64 r9;
|
||||
U64 r8;
|
||||
U64 rax;
|
||||
U64 rcx;
|
||||
U64 rdx;
|
||||
U64 rsi;
|
||||
U64 rdi;
|
||||
U64 orig_rax;
|
||||
U64 rip;
|
||||
U64 cs;
|
||||
U64 rflags;
|
||||
U64 rsp;
|
||||
U64 ss;
|
||||
U64 fsbase;
|
||||
U64 gsbase;
|
||||
U64 ds;
|
||||
U64 es;
|
||||
U64 fs;
|
||||
U64 gs;
|
||||
};
|
||||
|
||||
typedef struct OS_LNX_UserX64 OS_LNX_UserX64;
|
||||
struct OS_LNX_UserX64
|
||||
{
|
||||
OS_LNX_GprsX64 regs;
|
||||
S32 u_fpvalid;
|
||||
U32 _pad0;
|
||||
X64_FXSave i387;
|
||||
U64 u_tsize;
|
||||
U64 u_dsize;
|
||||
U64 u_ssize;
|
||||
U64 start_code;
|
||||
U64 start_stack;
|
||||
U64 signal;
|
||||
U32 reserved;
|
||||
U32 _pad1;
|
||||
U64 u_ar0;
|
||||
U64 u_fpstate;
|
||||
U64 magic;
|
||||
U8 u_comm[32];
|
||||
U64 u_debugreg[8];
|
||||
};
|
||||
StaticAssert(sizeof(OS_LNX_UserX64) == 912, g_os_lnx_user_x64_size_check);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: File Iterator
|
||||
|
||||
typedef struct OS_LNX_FileIter OS_LNX_FileIter;
|
||||
struct OS_LNX_FileIter
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *dp;
|
||||
String8 path;
|
||||
};
|
||||
StaticAssert(sizeof(Member(OS_FileIter, memory)) >= sizeof(OS_LNX_FileIter), os_lnx_file_iter_size_check);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Safe Call Handler Chain
|
||||
|
||||
typedef struct OS_LNX_SafeCallChain OS_LNX_SafeCallChain;
|
||||
struct OS_LNX_SafeCallChain
|
||||
{
|
||||
OS_LNX_SafeCallChain *next;
|
||||
ThreadEntryPointFunctionType *fail_handler;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entities
|
||||
|
||||
typedef enum OS_LNX_EntityKind
|
||||
{
|
||||
OS_LNX_EntityKind_Thread,
|
||||
OS_LNX_EntityKind_Mutex,
|
||||
OS_LNX_EntityKind_RWMutex,
|
||||
OS_LNX_EntityKind_ConditionVariable,
|
||||
OS_LNX_EntityKind_Barrier,
|
||||
}
|
||||
OS_LNX_EntityKind;
|
||||
|
||||
typedef struct OS_LNX_Entity OS_LNX_Entity;
|
||||
struct OS_LNX_Entity
|
||||
{
|
||||
OS_LNX_Entity *next;
|
||||
OS_LNX_EntityKind kind;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
pthread_t handle;
|
||||
ThreadEntryPointFunctionType *func;
|
||||
void *ptr;
|
||||
} thread;
|
||||
pthread_mutex_t mutex_handle;
|
||||
pthread_rwlock_t rwmutex_handle;
|
||||
struct
|
||||
{
|
||||
pthread_cond_t cond_handle;
|
||||
pthread_mutex_t rwlock_mutex_handle;
|
||||
} cv;
|
||||
pthread_barrier_t barrier;
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: State
|
||||
|
||||
typedef struct OS_LNX_State OS_LNX_State;
|
||||
struct OS_LNX_State
|
||||
{
|
||||
Arena *arena;
|
||||
OS_SystemInfo system_info;
|
||||
OS_ProcessInfo process_info;
|
||||
pthread_mutex_t entity_mutex;
|
||||
Arena *entity_arena;
|
||||
OS_LNX_Entity *entity_free;
|
||||
U64 default_env_count;
|
||||
char **default_env;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global OS_LNX_State os_lnx_state = {0};
|
||||
thread_static OS_LNX_SafeCallChain *os_lnx_safe_call_chain = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Helpers
|
||||
|
||||
internal DateTime os_lnx_date_time_from_tm(tm in, U32 msec);
|
||||
internal tm os_lnx_tm_from_date_time(DateTime dt);
|
||||
internal timespec os_lnx_timespec_from_date_time(DateTime dt);
|
||||
internal DenseTime os_lnx_dense_time_from_timespec(timespec in);
|
||||
internal FileProperties os_lnx_file_properties_from_stat(struct stat *s);
|
||||
internal void os_lnx_safe_call_sig_handler(int x);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entities
|
||||
|
||||
internal OS_LNX_Entity *os_lnx_entity_alloc(OS_LNX_EntityKind kind);
|
||||
internal void os_lnx_entity_release(OS_LNX_Entity *entity);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Entry Point
|
||||
|
||||
internal void *os_lnx_thread_entry_point(void *ptr);
|
||||
|
||||
#endif // OS_CORE_LINUX_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,88 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef LINUX_H
|
||||
#define LINUX_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Get all these linux includes
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/limits.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): File Iterator
|
||||
|
||||
struct LNX_FileIter{
|
||||
int fd;
|
||||
DIR *dir;
|
||||
};
|
||||
StaticAssert(sizeof(Member(OS_FileIter, memory)) >= sizeof(LNX_FileIter), file_iter_memory_size);
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Threading Entities
|
||||
|
||||
enum LNX_EntityKind{
|
||||
LNX_EntityKind_Null,
|
||||
LNX_EntityKind_Thread,
|
||||
LNX_EntityKind_Mutex,
|
||||
LNX_EntityKind_ConditionVariable,
|
||||
};
|
||||
|
||||
struct LNX_Entity{
|
||||
LNX_Entity *next;
|
||||
LNX_EntityKind kind;
|
||||
volatile U32 reference_mask;
|
||||
union{
|
||||
struct{
|
||||
ThreadEntryPointFunctionType *func;
|
||||
void *ptr;
|
||||
pthread_t handle;
|
||||
} thread;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Safe Call Chain
|
||||
|
||||
struct LNX_SafeCallChain{
|
||||
LNX_SafeCallChain *next;
|
||||
ThreadEntryPointFunctionType *fail_handler;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(allen): Helpers
|
||||
|
||||
internal B32 lnx_write_list_to_file_descriptor(int fd, String8List list);
|
||||
|
||||
internal void lnx_date_time_from_tm(DateTime *out, struct tm *in, U32 msec);
|
||||
internal void lnx_tm_from_date_time(struct tm *out, DateTime *in);
|
||||
internal void lnx_dense_time_from_timespec(DenseTime *out, struct timespec *in);
|
||||
internal void lnx_file_properties_from_stat(FileProperties *out, struct stat *in);
|
||||
|
||||
internal String8 lnx_string_from_signal(int signum);
|
||||
internal String8 lnx_string_from_errno(int error_number);
|
||||
|
||||
internal LNX_Entity* lnx_alloc_entity(LNX_EntityKind kind);
|
||||
internal void lnx_free_entity(LNX_Entity *entity);
|
||||
internal void* lnx_thread_base(void *ptr);
|
||||
|
||||
internal void lnx_safe_call_sig_handler(int);
|
||||
|
||||
#endif //LINUX_H
|
||||
@@ -1,279 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type Functions (Helpers, Implemented Once)
|
||||
|
||||
internal OS_Handle
|
||||
os_handle_zero(void)
|
||||
{
|
||||
OS_Handle handle = {0};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_handle_match(OS_Handle a, OS_Handle b)
|
||||
{
|
||||
return a.u64[0] == b.u64[0];
|
||||
}
|
||||
|
||||
internal void
|
||||
os_handle_list_push(Arena *arena, OS_HandleList *handles, OS_Handle handle)
|
||||
{
|
||||
OS_HandleNode *n = push_array(arena, OS_HandleNode, 1);
|
||||
n->v = handle;
|
||||
SLLQueuePush(handles->first, handles->last, n);
|
||||
handles->count += 1;
|
||||
}
|
||||
|
||||
internal OS_HandleArray
|
||||
os_handle_array_from_list(Arena *arena, OS_HandleList *list)
|
||||
{
|
||||
OS_HandleArray result = {0};
|
||||
result.count = list->count;
|
||||
result.v = push_array_no_zero(arena, OS_Handle, result.count);
|
||||
U64 idx = 0;
|
||||
for(OS_HandleNode *n = list->first; n != 0; n = n->next, idx += 1)
|
||||
{
|
||||
result.v[idx] = n->v;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
|
||||
|
||||
internal String8
|
||||
os_data_from_file_path(Arena *arena, String8 path)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
|
||||
FileProperties props = os_properties_from_file(file);
|
||||
String8 data = os_string_from_file_range(arena, file, r1u64(0, props.size));
|
||||
os_file_close(file);
|
||||
return data;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_write_data_to_file_path(String8 path, String8 data)
|
||||
{
|
||||
B32 good = 0;
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write, path);
|
||||
if(!os_handle_match(file, os_handle_zero()))
|
||||
{
|
||||
U64 bytes_written = os_file_write(file, r1u64(0, data.size), data.str);
|
||||
good = (bytes_written == data.size);
|
||||
os_file_close(file);
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_write_data_list_to_file_path(String8 path, String8List list)
|
||||
{
|
||||
B32 good = 0;
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write, path);
|
||||
if(!os_handle_match(file, os_handle_zero()))
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U64 write_buffer_size = KB(64);
|
||||
U8 *write_buffer = push_array_no_zero(scratch.arena, U8, write_buffer_size);
|
||||
U64 write_buffer_write_pos = 0;
|
||||
U64 write_buffer_read_pos = 0;
|
||||
U64 file_off = 0;
|
||||
{
|
||||
for(String8Node *n = list.first; n != 0; n = n->next)
|
||||
{
|
||||
for(U64 n_off = 0; n_off < n->string.size;)
|
||||
{
|
||||
U64 write_buffer_unconsumed_size = (write_buffer_write_pos - write_buffer_read_pos);
|
||||
U64 write_buffer_available_size = (write_buffer_size - write_buffer_unconsumed_size);
|
||||
if(write_buffer_available_size == 0)
|
||||
{
|
||||
U64 file_write_size = os_file_write(file, r1u64(file_off, file_off+write_buffer_size), write_buffer);
|
||||
if(file_write_size != write_buffer_size)
|
||||
{
|
||||
goto dbl_break;
|
||||
}
|
||||
file_off += write_buffer_size;
|
||||
write_buffer_read_pos += write_buffer_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
U64 bytes_to_copy = Min(write_buffer_available_size, n->string.size - n_off);
|
||||
write_buffer_write_pos += ring_write(write_buffer, write_buffer_size, write_buffer_write_pos, n->string.str + n_off, bytes_to_copy);
|
||||
n_off += bytes_to_copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(write_buffer_write_pos > write_buffer_read_pos)
|
||||
{
|
||||
U64 file_write_size = os_file_write(file, r1u64(file_off, file_off + (write_buffer_write_pos-write_buffer_read_pos)), write_buffer);
|
||||
file_off += file_write_size;
|
||||
}
|
||||
}
|
||||
dbl_break:;
|
||||
good = (file_off == list.total_size);
|
||||
os_file_close(file);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_append_data_to_file_path(String8 path, String8 data)
|
||||
{
|
||||
B32 good = 0;
|
||||
if(data.size != 0)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append, path);
|
||||
if(!os_handle_match(file, os_handle_zero()))
|
||||
{
|
||||
U64 pos = os_properties_from_file(file).size;
|
||||
U64 bytes_written = os_file_write(file, r1u64(pos, pos+data.size), data.str);
|
||||
good = (bytes_written == data.size);
|
||||
os_file_close(file);
|
||||
}
|
||||
}
|
||||
return good;
|
||||
}
|
||||
|
||||
internal OS_FileID
|
||||
os_id_from_file_path(String8 path)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
|
||||
OS_FileID id = os_id_from_file(file);
|
||||
os_file_close(file);
|
||||
return id;
|
||||
}
|
||||
|
||||
internal S64
|
||||
os_file_id_compare(OS_FileID a, OS_FileID b)
|
||||
{
|
||||
S64 cmp = MemoryCompare((void*)&a.v[0], (void*)&b.v[0], sizeof(a.v));
|
||||
return cmp;
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range)
|
||||
{
|
||||
U64 pre_pos = arena_pos(arena);
|
||||
String8 result;
|
||||
result.size = dim_1u64(range);
|
||||
result.str = push_array_no_zero(arena, U8, result.size);
|
||||
U64 actual_read_size = os_file_read(file, range, result.str);
|
||||
if(actual_read_size < result.size)
|
||||
{
|
||||
arena_pop_to(arena, pre_pos + actual_read_size);
|
||||
result.size = actual_read_size;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_file_read_cstring(Arena *arena, OS_Handle file, U64 off)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8List block_list = {0};
|
||||
for(U64 cursor = off, stride = 256;; cursor += stride)
|
||||
{
|
||||
U8 *raw_block = push_array_no_zero(scratch.arena, U8, stride);
|
||||
U64 read_size = os_file_read(file, r1u64(cursor, cursor + stride), raw_block);
|
||||
String8 block = str8_cstring_capped(raw_block, raw_block+read_size);
|
||||
str8_list_push(scratch.arena, &block_list, block);
|
||||
if(read_size != stride || (block.size+1 <= read_size && block.str[block.size] == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
String8 result = str8_list_join(arena, &block_list, 0);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process Launcher Helpers
|
||||
|
||||
internal OS_Handle
|
||||
os_cmd_line_launch(String8 string)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
U8 split_chars[] = {' '};
|
||||
String8List parts = str8_split(scratch.arena, string, split_chars, ArrayCount(split_chars), 0);
|
||||
OS_Handle handle = {0};
|
||||
if(parts.node_count != 0)
|
||||
{
|
||||
// rjf: unpack exe part
|
||||
String8 exe = parts.first->string;
|
||||
String8 exe_folder = str8_chop_last_slash(exe);
|
||||
if(exe_folder.size == 0)
|
||||
{
|
||||
exe_folder = os_get_current_path(scratch.arena);
|
||||
}
|
||||
|
||||
// rjf: find stdout delimiter
|
||||
String8Node *stdout_delimiter_n = 0;
|
||||
for(String8Node *n = parts.first; n != 0; n = n->next)
|
||||
{
|
||||
if(str8_match(n->string, str8_lit(">"), 0))
|
||||
{
|
||||
stdout_delimiter_n = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: read stdout path
|
||||
String8 stdout_path = {0};
|
||||
if(stdout_delimiter_n && stdout_delimiter_n->next)
|
||||
{
|
||||
stdout_path = stdout_delimiter_n->next->string;
|
||||
}
|
||||
|
||||
// rjf: open stdout handle
|
||||
OS_Handle stdout_handle = {0};
|
||||
if(stdout_path.size != 0)
|
||||
{
|
||||
OS_Handle file = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Read, stdout_path);
|
||||
os_file_close(file);
|
||||
stdout_handle = os_file_open(OS_AccessFlag_Write|OS_AccessFlag_Append|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite|OS_AccessFlag_Inherited, stdout_path);
|
||||
}
|
||||
|
||||
// rjf: form command line
|
||||
String8List cmdline = {0};
|
||||
for(String8Node *n = parts.first; n != stdout_delimiter_n && n != 0; n = n->next)
|
||||
{
|
||||
str8_list_push(scratch.arena, &cmdline, n->string);
|
||||
}
|
||||
|
||||
// rjf: launch
|
||||
OS_ProcessLaunchParams params = {0};
|
||||
params.cmd_line = cmdline;
|
||||
params.path = exe_folder;
|
||||
params.inherit_env = 1;
|
||||
params.stdout_file = stdout_handle;
|
||||
handle = os_process_launch(¶ms);
|
||||
|
||||
// rjf: close stdout handle
|
||||
{
|
||||
if(stdout_path.size != 0)
|
||||
{
|
||||
os_file_close(stdout_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
os_cmd_line_launchf(char *fmt, ...)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 string = push_str8fv(scratch.arena, fmt, args);
|
||||
OS_Handle result = os_cmd_line_launch(string);
|
||||
va_end(args);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,324 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_CORE_H
|
||||
#define OS_CORE_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: System Info
|
||||
|
||||
typedef struct OS_SystemInfo OS_SystemInfo;
|
||||
struct OS_SystemInfo
|
||||
{
|
||||
U32 logical_processor_count;
|
||||
U64 page_size;
|
||||
U64 large_page_size;
|
||||
U64 allocation_granularity;
|
||||
String8 machine_name;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process Info
|
||||
|
||||
typedef struct OS_ProcessInfo OS_ProcessInfo;
|
||||
struct OS_ProcessInfo
|
||||
{
|
||||
U32 pid;
|
||||
B32 large_pages_allowed;
|
||||
String8 binary_path;
|
||||
String8 initial_path;
|
||||
String8 user_program_data_path;
|
||||
String8List module_load_paths;
|
||||
String8List environment;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Access Flags
|
||||
|
||||
typedef U32 OS_AccessFlags;
|
||||
enum
|
||||
{
|
||||
OS_AccessFlag_Read = (1<<0),
|
||||
OS_AccessFlag_Write = (1<<1),
|
||||
OS_AccessFlag_Execute = (1<<2),
|
||||
OS_AccessFlag_Append = (1<<3),
|
||||
OS_AccessFlag_ShareRead = (1<<4),
|
||||
OS_AccessFlag_ShareWrite = (1<<5),
|
||||
OS_AccessFlag_Inherited = (1<<6),
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Files
|
||||
|
||||
typedef U32 OS_FileIterFlags;
|
||||
enum
|
||||
{
|
||||
OS_FileIterFlag_SkipFolders = (1 << 0),
|
||||
OS_FileIterFlag_SkipFiles = (1 << 1),
|
||||
OS_FileIterFlag_SkipHiddenFiles = (1 << 2),
|
||||
OS_FileIterFlag_Done = (1 << 31),
|
||||
};
|
||||
|
||||
typedef struct OS_FileIter OS_FileIter;
|
||||
struct OS_FileIter
|
||||
{
|
||||
OS_FileIterFlags flags;
|
||||
U8 memory[800];
|
||||
};
|
||||
|
||||
typedef struct OS_FileInfo OS_FileInfo;
|
||||
struct OS_FileInfo
|
||||
{
|
||||
String8 name;
|
||||
FileProperties props;
|
||||
};
|
||||
|
||||
// nick: on-disk file identifier
|
||||
typedef struct OS_FileID OS_FileID;
|
||||
struct OS_FileID
|
||||
{
|
||||
U64 v[3];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type
|
||||
|
||||
typedef struct OS_Handle OS_Handle;
|
||||
struct OS_Handle
|
||||
{
|
||||
U64 u64[1];
|
||||
};
|
||||
|
||||
typedef struct OS_HandleNode OS_HandleNode;
|
||||
struct OS_HandleNode
|
||||
{
|
||||
OS_HandleNode *next;
|
||||
OS_Handle v;
|
||||
};
|
||||
|
||||
typedef struct OS_HandleList OS_HandleList;
|
||||
struct OS_HandleList
|
||||
{
|
||||
OS_HandleNode *first;
|
||||
OS_HandleNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct OS_HandleArray OS_HandleArray;
|
||||
struct OS_HandleArray
|
||||
{
|
||||
OS_Handle *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process Launch Parameters
|
||||
|
||||
typedef struct OS_ProcessLaunchParams OS_ProcessLaunchParams;
|
||||
struct OS_ProcessLaunchParams
|
||||
{
|
||||
String8List cmd_line;
|
||||
String8 path;
|
||||
String8List env;
|
||||
B32 inherit_env;
|
||||
B32 debug_subprocesses;
|
||||
B32 consoleless;
|
||||
OS_Handle stdout_file;
|
||||
OS_Handle stderr_file;
|
||||
OS_Handle stdin_file;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type Functions (Helpers, Implemented Once)
|
||||
|
||||
internal OS_Handle os_handle_zero(void);
|
||||
internal B32 os_handle_match(OS_Handle a, OS_Handle b);
|
||||
internal void os_handle_list_push(Arena *arena, OS_HandleList *handles, OS_Handle handle);
|
||||
internal OS_HandleArray os_handle_array_from_list(Arena *arena, OS_HandleList *list);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Filesystem Helpers (Helpers, Implemented Once)
|
||||
|
||||
internal String8 os_data_from_file_path(Arena *arena, String8 path);
|
||||
internal B32 os_write_data_to_file_path(String8 path, String8 data);
|
||||
internal B32 os_write_data_list_to_file_path(String8 path, String8List list);
|
||||
internal B32 os_append_data_to_file_path(String8 path, String8 data);
|
||||
internal OS_FileID os_id_from_file_path(String8 path);
|
||||
internal S64 os_file_id_compare(OS_FileID a, OS_FileID b);
|
||||
internal String8 os_string_from_file_range(Arena *arena, OS_Handle file, Rng1U64 range);
|
||||
internal String8 os_file_read_cstring(Arena *arena, OS_Handle file, U64 off);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Process Launcher Helpers
|
||||
|
||||
internal OS_Handle os_cmd_line_launch(String8 string);
|
||||
internal OS_Handle os_cmd_line_launchf(char *fmt, ...);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks System/Process Info (Implemented Per-OS)
|
||||
|
||||
internal OS_SystemInfo *os_get_system_info(void);
|
||||
internal OS_ProcessInfo *os_get_process_info(void);
|
||||
internal String8 os_get_current_path(Arena *arena);
|
||||
internal U32 os_get_process_start_time_unix(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Memory Allocation (Implemented Per-OS)
|
||||
|
||||
//- rjf: basic
|
||||
internal void *os_reserve(U64 size);
|
||||
internal B32 os_commit(void *ptr, U64 size);
|
||||
internal void os_decommit(void *ptr, U64 size);
|
||||
internal void os_release(void *ptr, U64 size);
|
||||
|
||||
//- rjf: large pages
|
||||
internal void *os_reserve_large(U64 size);
|
||||
internal B32 os_commit_large(void *ptr, U64 size);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Thread Info (Implemented Per-OS)
|
||||
|
||||
internal U32 os_tid(void);
|
||||
internal void os_set_thread_name(String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Aborting (Implemented Per-OS)
|
||||
|
||||
internal void os_abort(S32 exit_code);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks File System (Implemented Per-OS)
|
||||
|
||||
//- rjf: files
|
||||
internal OS_Handle os_file_open(OS_AccessFlags flags, String8 path);
|
||||
internal void os_file_close(OS_Handle file);
|
||||
internal U64 os_file_read(OS_Handle file, Rng1U64 rng, void *out_data);
|
||||
#define os_file_read_struct(f, off, ptr) os_file_read((f), r1u64((off), (off)+sizeof(*(ptr))), (ptr))
|
||||
internal U64 os_file_write(OS_Handle file, Rng1U64 rng, void *data);
|
||||
internal B32 os_file_set_times(OS_Handle file, DateTime time);
|
||||
internal FileProperties os_properties_from_file(OS_Handle file);
|
||||
internal OS_FileID os_id_from_file(OS_Handle file);
|
||||
internal B32 os_file_reserve_size(OS_Handle file, U64 size);
|
||||
internal B32 os_delete_file_at_path(String8 path);
|
||||
internal B32 os_copy_file_path(String8 dst, String8 src);
|
||||
internal B32 os_move_file_path(String8 dst, String8 src);
|
||||
internal String8 os_full_path_from_path(Arena *arena, String8 path);
|
||||
internal B32 os_file_path_exists(String8 path);
|
||||
internal B32 os_folder_path_exists(String8 path);
|
||||
internal FileProperties os_properties_from_file_path(String8 path);
|
||||
|
||||
//- rjf: file maps
|
||||
internal OS_Handle os_file_map_open(OS_AccessFlags flags, OS_Handle file);
|
||||
internal void os_file_map_close(OS_Handle map);
|
||||
internal void * os_file_map_view_open(OS_Handle map, OS_AccessFlags flags, Rng1U64 range);
|
||||
internal void os_file_map_view_close(OS_Handle map, void *ptr, Rng1U64 range);
|
||||
|
||||
//- rjf: directory iteration
|
||||
internal OS_FileIter *os_file_iter_begin(Arena *arena, String8 path, OS_FileIterFlags flags);
|
||||
internal B32 os_file_iter_next(Arena *arena, OS_FileIter *iter, OS_FileInfo *info_out);
|
||||
internal void os_file_iter_end(OS_FileIter *iter);
|
||||
|
||||
//- rjf: directory creation
|
||||
internal B32 os_make_directory(String8 path);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shared Memory (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_shared_memory_alloc(U64 size, String8 name);
|
||||
internal OS_Handle os_shared_memory_open(String8 name);
|
||||
internal void os_shared_memory_close(OS_Handle handle);
|
||||
internal void * os_shared_memory_view_open(OS_Handle handle, Rng1U64 range);
|
||||
internal void os_shared_memory_view_close(OS_Handle handle, void *ptr, Rng1U64 range);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Time (Implemented Per-OS)
|
||||
|
||||
internal U64 os_now_microseconds(void);
|
||||
internal U32 os_now_unix(void);
|
||||
internal DateTime os_now_universal_time(void);
|
||||
internal DateTime os_universal_time_from_local(DateTime *local_time);
|
||||
internal DateTime os_local_time_from_universal(DateTime *universal_time);
|
||||
internal void os_sleep_milliseconds(U32 msec);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Child Processes (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_process_launch(OS_ProcessLaunchParams *params);
|
||||
internal B32 os_process_join(OS_Handle handle, U64 endt_us, U64 *exit_code_out);
|
||||
internal void os_process_detach(OS_Handle handle);
|
||||
internal B32 os_process_kill(OS_Handle handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Threads (Implemented Per-OS)
|
||||
|
||||
internal Thread os_thread_launch(ThreadEntryPointFunctionType *f, void *p);
|
||||
internal B32 os_thread_join(Thread handle, U64 endt_us);
|
||||
internal void os_thread_detach(Thread handle);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Synchronization Primitives (Implemented Per-OS)
|
||||
|
||||
//- rjf: recursive mutexes
|
||||
internal Mutex os_mutex_alloc(void);
|
||||
internal void os_mutex_release(Mutex mutex);
|
||||
internal void os_mutex_take(Mutex mutex);
|
||||
internal void os_mutex_drop(Mutex mutex);
|
||||
|
||||
//- rjf: reader/writer mutexes
|
||||
internal RWMutex os_rw_mutex_alloc(void);
|
||||
internal void os_rw_mutex_release(RWMutex mutex);
|
||||
internal void os_rw_mutex_take(RWMutex mutex, B32 write_mode);
|
||||
internal void os_rw_mutex_drop(RWMutex mutex, B32 write_mode);
|
||||
|
||||
//- rjf: condition variables
|
||||
internal CondVar os_cond_var_alloc(void);
|
||||
internal void os_cond_var_release(CondVar cv);
|
||||
// returns false on timeout, true on signal, (max_wait_ms = max_U64) -> no timeout
|
||||
internal B32 os_cond_var_wait(CondVar cv, Mutex mutex, U64 endt_us);
|
||||
internal B32 os_cond_var_wait_rw(CondVar cv, RWMutex mutex_rw, B32 write_mode, U64 endt_us);
|
||||
internal void os_cond_var_signal(CondVar cv);
|
||||
internal void os_cond_var_broadcast(CondVar cv);
|
||||
|
||||
//- rjf: cross-process semaphores
|
||||
internal Semaphore os_semaphore_alloc(U32 initial_count, U32 max_count, String8 name);
|
||||
internal void os_semaphore_release(Semaphore semaphore);
|
||||
internal Semaphore os_semaphore_open(String8 name);
|
||||
internal void os_semaphore_close(Semaphore semaphore);
|
||||
internal B32 os_semaphore_take(Semaphore semaphore, U64 endt_us);
|
||||
internal void os_semaphore_drop(Semaphore semaphore);
|
||||
|
||||
//- rjf: barriers
|
||||
internal Barrier os_barrier_alloc(U64 count);
|
||||
internal void os_barrier_release(Barrier barrier);
|
||||
internal void os_barrier_wait(Barrier barrier);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle os_library_open(String8 path);
|
||||
internal void os_library_close(OS_Handle lib);
|
||||
internal VoidProc *os_library_load_proc(OS_Handle lib, String8 name);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Safe Calls (Implemented Per-OS)
|
||||
|
||||
internal void os_safe_call(ThreadEntryPointFunctionType *func, ThreadEntryPointFunctionType *fail_handler, void *ptr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks GUIDs (Implemented Per-OS)
|
||||
|
||||
internal Guid os_make_guid(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Entry Points (Implemented Per-OS)
|
||||
|
||||
// NOTE(rjf): The implementation of `os_core` will define low-level entry
|
||||
// points if BUILD_ENTRY_DEFINING_UNIT is defined to 1. These will call
|
||||
// into the standard codebase program entry points, named "entry_point".
|
||||
|
||||
#if BUILD_ENTRY_DEFINING_UNIT
|
||||
raddbg_entry_point(entry_point);
|
||||
internal no_inline void entry_point(CmdLine *cmdline);
|
||||
#endif
|
||||
|
||||
#endif // OS_CORE_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
// #include "os/core/os_core.c"
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
# include "os/gfx/os_gfx.c"
|
||||
#endif
|
||||
|
||||
#if OS_WINDOWS
|
||||
// # include "os/core/win32/os_core_win32.c"
|
||||
#elif OS_LINUX
|
||||
# include "os/core/linux/os_core_linux.c"
|
||||
#else
|
||||
# error OS core layer not implemented for this operating system.
|
||||
#endif
|
||||
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
# if OS_GFX_STUB
|
||||
# include "os/gfx/stub/os_gfx_stub.c"
|
||||
# elif OS_WINDOWS
|
||||
# include "os/gfx/win32/os_gfx_win32.c"
|
||||
# elif OS_LINUX
|
||||
# include "os/gfx/linux/os_gfx_linux.c"
|
||||
# else
|
||||
# error OS graphical layer not implemented for this operating system.
|
||||
# endif
|
||||
#endif
|
||||
@@ -1,40 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_INC_H
|
||||
#define OS_INC_H
|
||||
|
||||
#if !defined(OS_FEATURE_GRAPHICAL)
|
||||
# define OS_FEATURE_GRAPHICAL 0
|
||||
#endif
|
||||
|
||||
#if !defined(OS_GFX_STUB)
|
||||
# define OS_GFX_STUB 0
|
||||
#endif
|
||||
|
||||
// #include "os/core/os_core.h"
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
# include "os/gfx/os_gfx.h"
|
||||
#endif
|
||||
|
||||
#if OS_WINDOWS
|
||||
// # include "os/core/win32/os_core_win32.h"
|
||||
#elif OS_LINUX
|
||||
# include "os/core/linux/os_core_linux.h"
|
||||
#else
|
||||
# error OS core layer not implemented for this operating system.
|
||||
#endif
|
||||
|
||||
#if OS_FEATURE_GRAPHICAL
|
||||
# if OS_GFX_STUB
|
||||
# include "os/gfx/stub/os_gfx_stub.h"
|
||||
# elif OS_WINDOWS
|
||||
# include "os/gfx/win32/os_gfx_win32.h"
|
||||
# elif OS_LINUX
|
||||
# include "os/gfx/linux/os_gfx_linux.h"
|
||||
# else
|
||||
# error OS graphical layer not implemented for this operating system.
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // OS_INC_H
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "linker/hash_table.h"
|
||||
#include "linker/lf_hash_table.h"
|
||||
#include "linker/base_ext/base_bit_array.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "rdi/rdi_local.h"
|
||||
#include "rdi_make/rdi_make_local.h"
|
||||
#include "coff/coff_inc.h"
|
||||
@@ -47,7 +46,6 @@
|
||||
#include "linker/hash_table.c"
|
||||
#include "linker/lf_hash_table.c"
|
||||
#include "linker/base_ext/base_bit_array.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "rdi/rdi_local.c"
|
||||
#include "rdi_make/rdi_make_local.c"
|
||||
#include "coff/coff_inc.c"
|
||||
|
||||
@@ -265,11 +265,11 @@
|
||||
#include "linker/hash_table.h"
|
||||
#include "linker/lf_hash_table.h"
|
||||
#include "linker/base_ext/base_bit_array.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "artifact_cache/artifact_cache.h"
|
||||
#include "rdi/rdi_local.h"
|
||||
#include "rdi_make/rdi_make_local.h"
|
||||
#include "mdesk/mdesk.h"
|
||||
#include "window_manager/window_manager_inc.h"
|
||||
#include "config/config_inc.h"
|
||||
#include "content/content.h"
|
||||
#include "file_stream/file_stream.h"
|
||||
@@ -318,11 +318,11 @@
|
||||
#include "linker/hash_table.c"
|
||||
#include "linker/lf_hash_table.c"
|
||||
#include "linker/base_ext/base_bit_array.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "artifact_cache/artifact_cache.c"
|
||||
#include "rdi/rdi_local.c"
|
||||
#include "rdi_make/rdi_make_local.c"
|
||||
#include "mdesk/mdesk.c"
|
||||
#include "window_manager/window_manager_inc.c"
|
||||
#include "config/config_inc.c"
|
||||
#include "content/content.c"
|
||||
#include "file_stream/file_stream.c"
|
||||
|
||||
@@ -79,7 +79,7 @@ r_ogl_os_init(CmdLine *cmdln)
|
||||
}
|
||||
|
||||
internal R_Handle
|
||||
r_ogl_os_window_equip(OS_Handle window)
|
||||
r_ogl_os_window_equip(OS_Window window)
|
||||
{
|
||||
OS_LNX_Window *window_os = (OS_LNX_Window *)window.u64[0];
|
||||
R_OGL_LNX_Window *w = r_ogl_lnx_state->free_window;
|
||||
@@ -163,7 +163,7 @@ r_ogl_os_window_equip(OS_Handle window)
|
||||
}
|
||||
|
||||
internal void
|
||||
r_ogl_os_window_unequip(OS_Handle os, R_Handle r)
|
||||
r_ogl_os_window_unequip(OS_Window os, R_Handle r)
|
||||
{
|
||||
R_OGL_LNX_Window *w = (R_OGL_LNX_Window *)r.u64[0];
|
||||
{
|
||||
@@ -173,7 +173,7 @@ r_ogl_os_window_unequip(OS_Handle os, R_Handle r)
|
||||
}
|
||||
|
||||
internal void
|
||||
r_ogl_os_select_window(OS_Handle os, R_Handle r)
|
||||
r_ogl_os_select_window(OS_Window os, R_Handle r)
|
||||
{
|
||||
OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0];
|
||||
R_OGL_LNX_Window *w_r = (R_OGL_LNX_Window *)r.u64[0];
|
||||
@@ -181,7 +181,7 @@ r_ogl_os_select_window(OS_Handle os, R_Handle r)
|
||||
}
|
||||
|
||||
internal void
|
||||
r_ogl_os_window_swap(OS_Handle os, R_Handle r)
|
||||
r_ogl_os_window_swap(OS_Window os, R_Handle r)
|
||||
{
|
||||
OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0];
|
||||
R_OGL_LNX_Window *w_r = (R_OGL_LNX_Window *)r.u64[0];
|
||||
|
||||
@@ -79,27 +79,27 @@ r_ogl_os_init(CmdLine *cmdln)
|
||||
}
|
||||
|
||||
internal R_Handle
|
||||
r_ogl_os_window_equip(OS_Handle window)
|
||||
r_ogl_os_window_equip(OS_Window window)
|
||||
{
|
||||
R_Handle result = {0};
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
r_ogl_os_window_unequip(OS_Handle os, R_Handle r)
|
||||
r_ogl_os_window_unequip(OS_Window os, R_Handle r)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal void
|
||||
r_ogl_os_select_window(OS_Handle os, R_Handle r)
|
||||
r_ogl_os_select_window(OS_Window os, R_Handle r)
|
||||
{
|
||||
OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0];
|
||||
glXMakeCurrent(os_lnx_gfx_state->display, w->window, r_ogl_lnx_ctx);
|
||||
}
|
||||
|
||||
internal void
|
||||
r_ogl_os_window_swap(OS_Handle os, R_Handle r)
|
||||
r_ogl_os_window_swap(OS_Window os, R_Handle r)
|
||||
{
|
||||
OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0];
|
||||
glXSwapBuffers(os_lnx_gfx_state->display, w->window);
|
||||
|
||||
@@ -201,14 +201,14 @@ r_init(CmdLine *cmdln)
|
||||
//- rjf: window setup/teardown
|
||||
|
||||
r_hook R_Handle
|
||||
r_window_equip(OS_Handle window)
|
||||
r_window_equip(OS_Window window)
|
||||
{
|
||||
R_Handle result = r_ogl_os_window_equip(window);
|
||||
return result;
|
||||
}
|
||||
|
||||
r_hook void
|
||||
r_window_unequip(OS_Handle window, R_Handle window_equip)
|
||||
r_window_unequip(OS_Window window, R_Handle window_equip)
|
||||
{
|
||||
r_ogl_os_window_unequip(window, window_equip);
|
||||
}
|
||||
@@ -341,7 +341,7 @@ r_end_frame(void)
|
||||
}
|
||||
|
||||
r_hook void
|
||||
r_window_begin_frame(OS_Handle os, R_Handle r)
|
||||
r_window_begin_frame(OS_Window os, R_Handle r)
|
||||
{
|
||||
r_ogl_os_select_window(os, r);
|
||||
|
||||
@@ -358,7 +358,7 @@ r_window_begin_frame(OS_Handle os, R_Handle r)
|
||||
}
|
||||
|
||||
r_hook void
|
||||
r_window_end_frame(OS_Handle os, R_Handle r)
|
||||
r_window_end_frame(OS_Window os, R_Handle r)
|
||||
{
|
||||
for(R_OGL_FlushBuffer *flush_buffer = r_ogl_state->first_buffer_to_flush; flush_buffer != 0; flush_buffer = flush_buffer->next)
|
||||
{
|
||||
@@ -372,7 +372,7 @@ r_window_end_frame(OS_Handle os, R_Handle r)
|
||||
//- rjf: render pass submission
|
||||
|
||||
r_hook void
|
||||
r_window_submit(OS_Handle window, R_Handle window_equip, R_PassList *passes)
|
||||
r_window_submit(OS_Window window, R_Handle window_equip, R_PassList *passes)
|
||||
{
|
||||
Rng2F32 viewport_rect = os_client_rect_from_window(window);
|
||||
Vec2F32 viewport_dim = dim_2f32(viewport_rect);
|
||||
|
||||
@@ -224,9 +224,9 @@ internal void r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id
|
||||
|
||||
internal VoidProc *r_ogl_os_load_procedure(char *name);
|
||||
internal void r_ogl_os_init(CmdLine *cmdln);
|
||||
internal R_Handle r_ogl_os_window_equip(OS_Handle window);
|
||||
internal void r_ogl_os_window_unequip(OS_Handle os, R_Handle r);
|
||||
internal void r_ogl_os_select_window(OS_Handle os, R_Handle r);
|
||||
internal void r_ogl_os_window_swap(OS_Handle os, R_Handle r);
|
||||
internal R_Handle r_ogl_os_window_equip(OS_Window window);
|
||||
internal void r_ogl_os_window_unequip(OS_Window os, R_Handle r);
|
||||
internal void r_ogl_os_select_window(OS_Window os, R_Handle r);
|
||||
internal void r_ogl_os_window_swap(OS_Window os, R_Handle r);
|
||||
|
||||
#endif // RENDER_OPENGL_H
|
||||
|
||||
@@ -101,7 +101,7 @@ r_ogl_os_init(CmdLine *cmdline)
|
||||
}
|
||||
|
||||
internal R_Handle
|
||||
r_ogl_os_window_equip(OS_Handle window)
|
||||
r_ogl_os_window_equip(OS_Window window)
|
||||
{
|
||||
//- rjf: unpack window
|
||||
OS_W32_Window *w = os_w32_window_from_handle(window);
|
||||
@@ -155,12 +155,12 @@ r_ogl_os_window_equip(OS_Handle window)
|
||||
}
|
||||
|
||||
internal void
|
||||
r_ogl_os_window_unequip(OS_Handle os, R_Handle r)
|
||||
r_ogl_os_window_unequip(OS_Window os, R_Handle r)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
r_ogl_os_select_window(OS_Handle os, R_Handle r)
|
||||
r_ogl_os_select_window(OS_Window os, R_Handle r)
|
||||
{
|
||||
OS_W32_Window *w = os_w32_window_from_handle(os);
|
||||
if(w != 0)
|
||||
@@ -172,7 +172,7 @@ r_ogl_os_select_window(OS_Handle os, R_Handle r)
|
||||
}
|
||||
|
||||
internal void
|
||||
r_ogl_os_window_swap(OS_Handle os, R_Handle r)
|
||||
r_ogl_os_window_swap(OS_Window os, R_Handle r)
|
||||
{
|
||||
OS_W32_Window *w = os_w32_window_from_handle(os);
|
||||
if(w != 0)
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
//- rjf: [h]
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "content/content.h"
|
||||
#include "artifact_cache/artifact_cache.h"
|
||||
#include "file_stream/file_stream.h"
|
||||
@@ -21,7 +20,6 @@
|
||||
|
||||
//- rjf: [c]
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "content/content.c"
|
||||
#include "artifact_cache/artifact_cache.c"
|
||||
#include "file_stream/file_stream.c"
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
//- rjf: [h]
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "render/render_inc.h"
|
||||
#include "font_provider/font_provider_inc.h"
|
||||
#include "font_cache/font_cache.h"
|
||||
@@ -20,7 +19,6 @@
|
||||
|
||||
//- rjf: [c]
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "render/render_inc.c"
|
||||
#include "font_provider/font_provider_inc.c"
|
||||
#include "font_cache/font_cache.c"
|
||||
|
||||
+4
-21
@@ -69,6 +69,7 @@ stap_list_from_string(Arena *arena, String8 string)
|
||||
internal String8
|
||||
stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
|
||||
{
|
||||
ARCH_Info *arch_info = arch_info_from_arch(Arch_x64);
|
||||
String8 error = str8_lit("unknown parse error");
|
||||
U64 sep_pos = str8_find_needle(string, 0, str8_lit("@"), 0);
|
||||
if (sep_pos < string.size) {
|
||||
@@ -200,14 +201,9 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
|
||||
index_str = str8_skip(index_str, 1);
|
||||
|
||||
// parse base
|
||||
B8 base_is_alias = 0;
|
||||
U32 base_reg_code = 0;
|
||||
if (base_str.size) {
|
||||
base_reg_code = regs_reg_code_from_name(Arch_x64, base_str);
|
||||
if (base_reg_code == 0) {
|
||||
base_reg_code = regs_alias_code_from_name(Arch_x64, base_str);
|
||||
base_is_alias = base_reg_code != 0;
|
||||
}
|
||||
base_reg_code = arch_reg_code_from_name(arch_info, base_str);
|
||||
if (base_reg_code == 0) {
|
||||
error = str8_lit("unknown base register");
|
||||
goto operand_parse_exit;
|
||||
@@ -215,14 +211,9 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
|
||||
}
|
||||
|
||||
// parse index
|
||||
B8 index_is_alias = 0;
|
||||
U32 index_reg_code = 0;
|
||||
if (index_str.size) {
|
||||
index_reg_code = regs_reg_code_from_name(Arch_x64, index_str);
|
||||
if (index_reg_code == 0) {
|
||||
index_reg_code = regs_alias_code_from_name(Arch_x64, index_str);
|
||||
index_is_alias = index_reg_code != 0;
|
||||
}
|
||||
index_reg_code = arch_reg_code_from_name(arch_info, index_str);
|
||||
if (index_reg_code == 0) {
|
||||
error = str8_lit("unknown index register");
|
||||
}
|
||||
@@ -247,9 +238,7 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
|
||||
arg.type = STAP_ArgType_MemoryRef;
|
||||
arg.memory_ref.disp = disp;
|
||||
arg.memory_ref.base.reg_code = base_reg_code;
|
||||
arg.memory_ref.base.is_alias = base_is_alias;
|
||||
arg.memory_ref.index.reg_code = index_reg_code;
|
||||
arg.memory_ref.index.is_alias = index_is_alias;
|
||||
arg.memory_ref.scale = scale;
|
||||
}
|
||||
// $imm
|
||||
@@ -296,19 +285,13 @@ stap_parse_args_x64(String8 string, STAP_Arg *arg_out)
|
||||
goto operand_parse_exit;
|
||||
}
|
||||
|
||||
B8 is_reg_alias = 0;
|
||||
U32 reg_code = regs_reg_code_from_name(Arch_x64, reg_str);
|
||||
if (reg_code == 0) {
|
||||
reg_code = regs_alias_code_from_name(Arch_x64, reg_str);
|
||||
is_reg_alias = reg_code != 0;
|
||||
}
|
||||
U32 reg_code = arch_reg_code_from_name(arch_info, reg_str);
|
||||
if (reg_code == 0) {
|
||||
error = str8_lit("invalid register name");
|
||||
goto operand_parse_exit;
|
||||
}
|
||||
|
||||
arg.type = STAP_ArgType_Reg;
|
||||
arg.reg.is_alias = is_reg_alias;
|
||||
arg.reg.reg_code = reg_code;
|
||||
} else {
|
||||
goto operand_parse_exit;
|
||||
|
||||
@@ -29,17 +29,14 @@ typedef struct STAP_Arg
|
||||
U64 imm;
|
||||
struct {
|
||||
U32 reg_code;
|
||||
B8 is_alias;
|
||||
} reg;
|
||||
struct {
|
||||
S64 disp;
|
||||
struct {
|
||||
U32 reg_code;
|
||||
B8 is_alias;
|
||||
} base;
|
||||
struct {
|
||||
U32 reg_code;
|
||||
B8 is_alias;
|
||||
} index;
|
||||
U64 scale;
|
||||
} memory_ref;
|
||||
|
||||
@@ -5,12 +5,10 @@
|
||||
#define BUILD_CONSOLE_INTERFACE 1
|
||||
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "arch/arch_inc.h"
|
||||
#include "stap/stap_parse.h"
|
||||
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "arch/arch_inc.c"
|
||||
#include "stap/stap_parse.c"
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
// Headers
|
||||
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "coff/coff.h"
|
||||
#include "coff/coff_parse.h"
|
||||
|
||||
@@ -16,7 +15,6 @@
|
||||
// Implementations
|
||||
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "coff/coff.c"
|
||||
#include "coff/coff_parse.c"
|
||||
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
#include "linker/hash_table.h"
|
||||
#include "linker/lf_hash_table.h"
|
||||
#include "linker/base_ext/base_bit_array.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "artifact_cache/artifact_cache.h"
|
||||
#include "rdi/rdi_local.h"
|
||||
#include "rdi_make/rdi_make_local.h"
|
||||
#include "mdesk/mdesk.h"
|
||||
#include "window_manager/window_manager_inc.h"
|
||||
#include "config/config_inc.h"
|
||||
#include "content/content.h"
|
||||
#include "file_stream/file_stream.h"
|
||||
@@ -98,11 +98,11 @@
|
||||
#include "linker/hash_table.c"
|
||||
#include "linker/lf_hash_table.c"
|
||||
#include "linker/base_ext/base_bit_array.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "artifact_cache/artifact_cache.c"
|
||||
#include "rdi/rdi_local.c"
|
||||
#include "rdi_make/rdi_make_local.c"
|
||||
#include "mdesk/mdesk.c"
|
||||
#include "window_manager/window_manager_inc.c"
|
||||
#include "config/config_inc.c"
|
||||
#include "content/content.c"
|
||||
#include "file_stream/file_stream.c"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,359 +1,359 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef DEMON_CORE_WIN32_H
|
||||
#define DEMON_CORE_WIN32_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Windows Includes
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32 Exception Codes
|
||||
|
||||
#define DMN_W32_EXCEPTION_BREAKPOINT 0x80000003u
|
||||
#define DMN_W32_EXCEPTION_SINGLE_STEP 0x80000004u
|
||||
#define DMN_W32_EXCEPTION_LONG_JUMP 0x80000026u
|
||||
#define DMN_W32_EXCEPTION_ACCESS_VIOLATION 0xC0000005u
|
||||
#define DMN_W32_EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu
|
||||
#define DMN_W32_EXCEPTION_DATA_TYPE_MISALIGNMENT 0x80000002u
|
||||
#define DMN_W32_EXCEPTION_GUARD_PAGE_VIOLATION 0x80000001u
|
||||
#define DMN_W32_EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008Du
|
||||
#define DMN_W32_EXCEPTION_FLT_DEVIDE_BY_ZERO 0xC000008Eu
|
||||
#define DMN_W32_EXCEPTION_FLT_INEXACT_RESULT 0xC000008Fu
|
||||
#define DMN_W32_EXCEPTION_FLT_INVALID_OPERATION 0xC0000090u
|
||||
#define DMN_W32_EXCEPTION_FLT_OVERFLOW 0xC0000091u
|
||||
#define DMN_W32_EXCEPTION_FLT_STACK_CHECK 0xC0000092u
|
||||
#define DMN_W32_EXCEPTION_FLT_UNDERFLOW 0xC0000093u
|
||||
#define DMN_W32_EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094u
|
||||
#define DMN_W32_EXCEPTION_INT_OVERFLOW 0xC0000095u
|
||||
#define DMN_W32_EXCEPTION_PRIVILEGED_INSTRUCTION 0xC0000096u
|
||||
#define DMN_W32_EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001Du
|
||||
#define DMN_W32_EXCEPTION_IN_PAGE_ERROR 0xC0000006u
|
||||
#define DMN_W32_EXCEPTION_INVALID_DISPOSITION 0xC0000026u
|
||||
#define DMN_W32_EXCEPTION_NONCONTINUABLE 0xC0000025u
|
||||
#define DMN_W32_EXCEPTION_STACK_OVERFLOW 0xC00000FDu
|
||||
#define DMN_W32_EXCEPTION_INVALID_HANDLE 0xC0000008u
|
||||
#define DMN_W32_EXCEPTION_UNWIND_CONSOLIDATE 0x80000029u
|
||||
#define DMN_W32_EXCEPTION_DLL_NOT_FOUND 0xC0000135u
|
||||
#define DMN_W32_EXCEPTION_ORDINAL_NOT_FOUND 0xC0000138u
|
||||
#define DMN_W32_EXCEPTION_ENTRY_POINT_NOT_FOUND 0xC0000139u
|
||||
#define DMN_W32_EXCEPTION_DLL_INIT_FAILED 0xC0000142u
|
||||
#define DMN_W32_EXCEPTION_CONTROL_C_EXIT 0xC000013Au
|
||||
#define DMN_W32_EXCEPTION_FLT_MULTIPLE_FAULTS 0xC00002B4u
|
||||
#define DMN_W32_EXCEPTION_FLT_MULTIPLE_TRAPS 0xC00002B5u
|
||||
#define DMN_W32_EXCEPTION_NAT_CONSUMPTION 0xC00002C9u
|
||||
#define DMN_W32_EXCEPTION_HEAP_CORRUPTION 0xC0000374u
|
||||
#define DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN 0xC0000409u
|
||||
#define DMN_W32_EXCEPTION_INVALID_CRUNTIME_PARAM 0xC0000417u
|
||||
#define DMN_W32_EXCEPTION_ASSERT_FAILURE 0xC0000420u
|
||||
#define DMN_W32_EXCEPTION_NO_MEMORY 0xC0000017u
|
||||
#define DMN_W32_EXCEPTION_THROW 0xE06D7363u
|
||||
#define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u
|
||||
#define DMN_w32_EXCEPTION_CLRDBG_NOTIFICATION 0x04242420u
|
||||
#define DMN_w32_EXCEPTION_CLR 0xE0434352u
|
||||
#define DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR 0x00524144u
|
||||
#define DMN_W32_EXCEPTION_RADDBG_SET_BREAKPOINT 0x00524145u
|
||||
#define DMN_W32_EXCEPTION_RADDBG_SET_VADDR_RANGE_NOTE 0x00524156u
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32 Exception ExceptionInformation Codes
|
||||
//
|
||||
// used as a subcode, apparently in all cases, for DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN.
|
||||
// need to somehow pipe this through & interpret it correctly in outer layers... @fastfail
|
||||
|
||||
#define DMN_W32_FAST_FAIL_LEGACY_GS_VIOLATION 0
|
||||
#define DMN_W32_FAST_FAIL_VTGUARD_CHECK_FAILURE 1
|
||||
#define DMN_W32_FAST_FAIL_STACK_COOKIE_CHECK_FAILURE 2
|
||||
#define DMN_W32_FAST_FAIL_CORRUPT_LIST_ENTRY 3
|
||||
#define DMN_W32_FAST_FAIL_INCORRECT_STACK 4
|
||||
#define DMN_W32_FAST_FAIL_INVALID_ARG 5
|
||||
#define DMN_W32_FAST_FAIL_GS_COOKIE_INIT 6
|
||||
#define DMN_W32_FAST_FAIL_FATAL_APP_EXIT 7
|
||||
#define DMN_W32_FAST_FAIL_RANGE_CHECK_FAILURE 8
|
||||
#define DMN_W32_FAST_FAIL_UNSAFE_REGISTRY_ACCESS 9
|
||||
#define DMN_W32_FAST_FAIL_GUARD_ICALL_CHECK_FAILURE 10
|
||||
#define DMN_W32_FAST_FAIL_GUARD_WRITE_CHECK_FAILURE 11
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FIBER_SWITCH 12
|
||||
#define DMN_W32_FAST_FAIL_INVALID_SET_OF_CONTEXT 13
|
||||
#define DMN_W32_FAST_FAIL_INVALID_REFERENCE_COUNT 14
|
||||
#define DMN_W32_FAST_FAIL_INVALID_JUMP_BUFFER 18
|
||||
#define DMN_W32_FAST_FAIL_MRDATA_MODIFIED 19
|
||||
#define DMN_W32_FAST_FAIL_CERTIFICATION_FAILURE 20
|
||||
#define DMN_W32_FAST_FAIL_INVALID_EXCEPTION_CHAIN 21
|
||||
#define DMN_W32_FAST_FAIL_CRYPTO_LIBRARY 22
|
||||
#define DMN_W32_FAST_FAIL_INVALID_CALL_IN_DLL_CALLOUT 23
|
||||
#define DMN_W32_FAST_FAIL_INVALID_IMAGE_BASE 24
|
||||
#define DMN_W32_FAST_FAIL_DLOAD_PROTECTION_FAILURE 25
|
||||
#define DMN_W32_FAST_FAIL_UNSAFE_EXTENSION_CALL 26
|
||||
#define DMN_W32_FAST_FAIL_DEPRECATED_SERVICE_INVOKED 27
|
||||
#define DMN_W32_FAST_FAIL_INVALID_BUFFER_ACCESS 28
|
||||
#define DMN_W32_FAST_FAIL_INVALID_BALANCED_TREE 29
|
||||
#define DMN_W32_FAST_FAIL_INVALID_NEXT_THREAD 30
|
||||
#define DMN_W32_FAST_FAIL_GUARD_ICALL_CHECK_SUPPRESSED 31 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_APCS_DISABLED 32
|
||||
#define DMN_W32_FAST_FAIL_INVALID_IDLE_STATE 33
|
||||
#define DMN_W32_FAST_FAIL_MRDATA_PROTECTION_FAILURE 34
|
||||
#define DMN_W32_FAST_FAIL_UNEXPECTED_HEAP_EXCEPTION 35
|
||||
#define DMN_W32_FAST_FAIL_INVALID_LOCK_STATE 36
|
||||
#define DMN_W32_FAST_FAIL_GUARD_JUMPTABLE 37 // Known to compiler, must retain value 37
|
||||
#define DMN_W32_FAST_FAIL_INVALID_LONGJUMP_TARGET 38
|
||||
#define DMN_W32_FAST_FAIL_INVALID_DISPATCH_CONTEXT 39
|
||||
#define DMN_W32_FAST_FAIL_INVALID_THREAD 40
|
||||
#define DMN_W32_FAST_FAIL_INVALID_SYSCALL_NUMBER 41 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FILE_OPERATION 42 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_LPAC_ACCESS_DENIED 43 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_GUARD_SS_FAILURE 44
|
||||
#define DMN_W32_FAST_FAIL_LOADER_CONTINUITY_FAILURE 45 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_GUARD_EXPORT_SUPPRESSION_FAILURE 46
|
||||
#define DMN_W32_FAST_FAIL_INVALID_CONTROL_STACK 47
|
||||
#define DMN_W32_FAST_FAIL_SET_CONTEXT_DENIED 48
|
||||
#define DMN_W32_FAST_FAIL_INVALID_IAT 49
|
||||
#define DMN_W32_FAST_FAIL_HEAP_METADATA_CORRUPTION 50
|
||||
#define DMN_W32_FAST_FAIL_PAYLOAD_RESTRICTION_VIOLATION 51
|
||||
#define DMN_W32_FAST_FAIL_LOW_LABEL_ACCESS_DENIED 52 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_ENCLAVE_CALL_FAILURE 53
|
||||
#define DMN_W32_FAST_FAIL_UNHANDLED_LSS_EXCEPTON 54
|
||||
#define DMN_W32_FAST_FAIL_ADMINLESS_ACCESS_DENIED 55 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_UNEXPECTED_CALL 56
|
||||
#define DMN_W32_FAST_FAIL_CONTROL_INVALID_RETURN_ADDRESS 57
|
||||
#define DMN_W32_FAST_FAIL_UNEXPECTED_HOST_BEHAVIOR 58
|
||||
#define DMN_W32_FAST_FAIL_FLAGS_CORRUPTION 59
|
||||
#define DMN_W32_FAST_FAIL_VEH_CORRUPTION 60
|
||||
#define DMN_W32_FAST_FAIL_ETW_CORRUPTION 61
|
||||
#define DMN_W32_FAST_FAIL_RIO_ABORT 62
|
||||
#define DMN_W32_FAST_FAIL_INVALID_PFN 63
|
||||
#define DMN_W32_FAST_FAIL_GUARD_ICALL_CHECK_FAILURE_XFG 64
|
||||
#define DMN_W32_FAST_FAIL_CAST_GUARD 65 // Known to compiler, must retain value 65
|
||||
#define DMN_W32_FAST_FAIL_HOST_VISIBILITY_CHANGE 66
|
||||
#define DMN_W32_FAST_FAIL_KERNEL_CET_SHADOW_STACK_ASSIST 67
|
||||
#define DMN_W32_FAST_FAIL_PATCH_CALLBACK_FAILED 68
|
||||
#define DMN_W32_FAST_FAIL_NTDLL_PATCH_FAILED 69
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FLS_DATA 70
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FAST_FAIL_CODE 0xFFFFFFFF
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32 Register Codes
|
||||
|
||||
#define DMN_W32_CTX_X86 0x00010000
|
||||
#define DMN_W32_CTX_X64 0x00100000
|
||||
|
||||
#define DMN_W32_CTX_INTEL_CONTROL 0x0001 // segss, rsp, segcs, rip, and rflags
|
||||
#define DMN_W32_CTX_INTEL_INTEGER 0x0002 // rax, rcx, rdx, rbx, rbp, rsi, rdi, and r8-r15
|
||||
#define DMN_W32_CTX_INTEL_SEGMENTS 0x0004 // segds, seges, segfs, and seggs
|
||||
#define DMN_W32_CTX_INTEL_FLOATS 0x0008 // xmm0-xmm15
|
||||
#define DMN_W32_CTX_INTEL_DEBUG 0x0010 // dr0-dr3 and dr6-dr7
|
||||
#define DMN_W32_CTX_INTEL_EXTENDED 0x0020
|
||||
#define DMN_W32_CTX_INTEL_XSTATE 0x0040
|
||||
|
||||
#define DMN_W32_CTX_X86_ALL (DMN_W32_CTX_X86 | \
|
||||
DMN_W32_CTX_INTEL_CONTROL | DMN_W32_CTX_INTEL_INTEGER | \
|
||||
DMN_W32_CTX_INTEL_SEGMENTS | DMN_W32_CTX_INTEL_DEBUG | \
|
||||
DMN_W32_CTX_INTEL_EXTENDED)
|
||||
#define DMN_W32_CTX_X64_ALL (DMN_W32_CTX_X64 | \
|
||||
DMN_W32_CTX_INTEL_CONTROL | DMN_W32_CTX_INTEL_INTEGER | \
|
||||
DMN_W32_CTX_INTEL_SEGMENTS | DMN_W32_CTX_INTEL_FLOATS | \
|
||||
DMN_W32_CTX_INTEL_DEBUG)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Per-Entity State
|
||||
|
||||
typedef enum DMN_W32_EntityKind
|
||||
{
|
||||
DMN_W32_EntityKind_Null,
|
||||
DMN_W32_EntityKind_Root,
|
||||
DMN_W32_EntityKind_Process,
|
||||
DMN_W32_EntityKind_Thread,
|
||||
DMN_W32_EntityKind_Module,
|
||||
DMN_W32_EntityKind_COUNT
|
||||
}
|
||||
DMN_W32_EntityKind;
|
||||
|
||||
typedef struct DMN_W32_Entity DMN_W32_Entity;
|
||||
struct DMN_W32_Entity
|
||||
{
|
||||
DMN_W32_Entity *first;
|
||||
DMN_W32_Entity *last;
|
||||
DMN_W32_Entity *next;
|
||||
DMN_W32_Entity *prev;
|
||||
DMN_W32_Entity *parent;
|
||||
DMN_W32_EntityKind kind;
|
||||
U32 gen;
|
||||
U64 id;
|
||||
HANDLE handle;
|
||||
Arch arch;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
U64 injection_address;
|
||||
B32 did_first_bp;
|
||||
}
|
||||
proc;
|
||||
struct
|
||||
{
|
||||
U64 thread_local_base;
|
||||
U64 last_name_hash;
|
||||
U64 name_gather_time_us;
|
||||
}
|
||||
thread;
|
||||
struct
|
||||
{
|
||||
Rng1U64 vaddr_range;
|
||||
U64 address_of_name_pointer;
|
||||
B32 is_main;
|
||||
B32 name_is_unicode;
|
||||
}
|
||||
module;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct DMN_W32_EntityNode DMN_W32_EntityNode;
|
||||
struct DMN_W32_EntityNode
|
||||
{
|
||||
DMN_W32_EntityNode *next;
|
||||
DMN_W32_Entity *v;
|
||||
};
|
||||
|
||||
typedef struct DMN_W32_EntityIDHashNode DMN_W32_EntityIDHashNode;
|
||||
struct DMN_W32_EntityIDHashNode
|
||||
{
|
||||
DMN_W32_EntityIDHashNode *next;
|
||||
DMN_W32_EntityIDHashNode *prev;
|
||||
U64 id;
|
||||
DMN_W32_Entity *entity;
|
||||
};
|
||||
|
||||
typedef struct DMN_W32_EntityIDHashSlot DMN_W32_EntityIDHashSlot;
|
||||
struct DMN_W32_EntityIDHashSlot
|
||||
{
|
||||
DMN_W32_EntityIDHashNode *first;
|
||||
DMN_W32_EntityIDHashNode *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Injection Types
|
||||
|
||||
typedef struct DMN_W32_InjectedBreak DMN_W32_InjectedBreak;
|
||||
struct DMN_W32_InjectedBreak
|
||||
{
|
||||
U64 code;
|
||||
U64 user_data;
|
||||
};
|
||||
|
||||
#define DMN_W32_INJECTED_CODE_SIZE 32
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Image Info Types
|
||||
|
||||
typedef struct DMN_W32_ImageInfo DMN_W32_ImageInfo;
|
||||
struct DMN_W32_ImageInfo
|
||||
{
|
||||
Arch arch;
|
||||
U32 size;
|
||||
U64 tls_index;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Dynamically-Loaded Win32 Function Types
|
||||
|
||||
typedef HRESULT DMN_W32_GetThreadDescriptionFunctionType(HANDLE hThread, WCHAR **ppszThreadDescription);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Shared State Bundle
|
||||
|
||||
typedef struct DMN_W32_Shared DMN_W32_Shared;
|
||||
struct DMN_W32_Shared
|
||||
{
|
||||
// rjf: top-level info
|
||||
Arena *arena;
|
||||
String8List env_strings;
|
||||
|
||||
// rjf: access locking mechanism
|
||||
Mutex access_mutex;
|
||||
B32 access_run_state;
|
||||
|
||||
// rjf: detaching info
|
||||
Arena *detach_arena;
|
||||
DMN_HandleList detach_processes;
|
||||
|
||||
// rjf: entity state
|
||||
Arena *entities_arena;
|
||||
DMN_W32_Entity *entities_base;
|
||||
DMN_W32_Entity *entities_first_free;
|
||||
U64 entities_count;
|
||||
DMN_W32_EntityIDHashSlot *entities_id_hash_slots;
|
||||
U64 entities_id_hash_slots_count;
|
||||
DMN_W32_EntityIDHashNode *entities_id_hash_node_free;
|
||||
|
||||
// rjf: launch state
|
||||
B32 new_process_pending;
|
||||
|
||||
// rjf: run results
|
||||
B32 resume_needed;
|
||||
U32 resume_pid;
|
||||
U32 resume_tid;
|
||||
B32 exception_not_handled;
|
||||
|
||||
// rjf: halting info
|
||||
DMN_Handle halter_process;
|
||||
U32 halter_tid;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global DMN_W32_Shared *dmn_w32_shared = 0;
|
||||
global DMN_W32_Entity dmn_w32_entity_nil = {&dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil};
|
||||
global DMN_W32_GetThreadDescriptionFunctionType *dmn_w32_GetThreadDescription = 0;
|
||||
thread_static B32 dmn_w32_ctrl_thread = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
internal U64 dmn_w32_hash_from_string(String8 string);
|
||||
internal U64 dmn_w32_hash_from_id(U64 id);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity Helpers
|
||||
|
||||
//- rjf: entity <-> handle
|
||||
internal DMN_Handle dmn_w32_handle_from_entity(DMN_W32_Entity *entity);
|
||||
internal DMN_W32_Entity *dmn_w32_entity_from_handle(DMN_Handle handle);
|
||||
|
||||
//- rjf: entity allocation/deallocation
|
||||
internal DMN_W32_Entity *dmn_w32_entity_alloc(DMN_W32_Entity *parent, DMN_W32_EntityKind kind, U64 id);
|
||||
internal void dmn_w32_entity_release(DMN_W32_Entity *entity);
|
||||
|
||||
//- rjf: kind*id -> entity
|
||||
internal DMN_W32_Entity *dmn_w32_entity_from_kind_id(DMN_W32_EntityKind kind, U64 id);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Module Info Extraction
|
||||
|
||||
internal String8 dmn_w32_full_path_from_module(Arena *arena, DMN_W32_Entity *module);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32-Level Process/Thread Reads/Writes
|
||||
|
||||
//- rjf: processes
|
||||
internal U64 dmn_w32_process_read(HANDLE process, Rng1U64 range, void *dst);
|
||||
internal B32 dmn_w32_process_write(HANDLE process, Rng1U64 range, void *src);
|
||||
internal String8 dmn_w32_read_memory_str(Arena *arena, HANDLE process_handle, U64 address);
|
||||
internal String16 dmn_w32_read_memory_str16(Arena *arena, HANDLE process_handle, U64 address);
|
||||
#define dmn_w32_process_read_struct(process, vaddr, ptr) dmn_w32_process_read((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
|
||||
#define dmn_w32_process_write_struct(process, vaddr, ptr) dmn_w32_process_write((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
|
||||
internal DMN_W32_ImageInfo dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr);
|
||||
|
||||
//- rjf: threads
|
||||
internal B32 dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block);
|
||||
internal B32 dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block);
|
||||
|
||||
//- rjf: remote thread injection
|
||||
internal DWORD dmn_w32_inject_thread(HANDLE process, U64 start_address);
|
||||
|
||||
#endif // DEMON_CORE_WIN32_H
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef DEMON_CORE_WIN32_H
|
||||
#define DEMON_CORE_WIN32_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Windows Includes
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32 Exception Codes
|
||||
|
||||
#define DMN_W32_EXCEPTION_BREAKPOINT 0x80000003u
|
||||
#define DMN_W32_EXCEPTION_SINGLE_STEP 0x80000004u
|
||||
#define DMN_W32_EXCEPTION_LONG_JUMP 0x80000026u
|
||||
#define DMN_W32_EXCEPTION_ACCESS_VIOLATION 0xC0000005u
|
||||
#define DMN_W32_EXCEPTION_ARRAY_BOUNDS_EXCEEDED 0xC000008Cu
|
||||
#define DMN_W32_EXCEPTION_DATA_TYPE_MISALIGNMENT 0x80000002u
|
||||
#define DMN_W32_EXCEPTION_GUARD_PAGE_VIOLATION 0x80000001u
|
||||
#define DMN_W32_EXCEPTION_FLT_DENORMAL_OPERAND 0xC000008Du
|
||||
#define DMN_W32_EXCEPTION_FLT_DEVIDE_BY_ZERO 0xC000008Eu
|
||||
#define DMN_W32_EXCEPTION_FLT_INEXACT_RESULT 0xC000008Fu
|
||||
#define DMN_W32_EXCEPTION_FLT_INVALID_OPERATION 0xC0000090u
|
||||
#define DMN_W32_EXCEPTION_FLT_OVERFLOW 0xC0000091u
|
||||
#define DMN_W32_EXCEPTION_FLT_STACK_CHECK 0xC0000092u
|
||||
#define DMN_W32_EXCEPTION_FLT_UNDERFLOW 0xC0000093u
|
||||
#define DMN_W32_EXCEPTION_INT_DIVIDE_BY_ZERO 0xC0000094u
|
||||
#define DMN_W32_EXCEPTION_INT_OVERFLOW 0xC0000095u
|
||||
#define DMN_W32_EXCEPTION_PRIVILEGED_INSTRUCTION 0xC0000096u
|
||||
#define DMN_W32_EXCEPTION_ILLEGAL_INSTRUCTION 0xC000001Du
|
||||
#define DMN_W32_EXCEPTION_IN_PAGE_ERROR 0xC0000006u
|
||||
#define DMN_W32_EXCEPTION_INVALID_DISPOSITION 0xC0000026u
|
||||
#define DMN_W32_EXCEPTION_NONCONTINUABLE 0xC0000025u
|
||||
#define DMN_W32_EXCEPTION_STACK_OVERFLOW 0xC00000FDu
|
||||
#define DMN_W32_EXCEPTION_INVALID_HANDLE 0xC0000008u
|
||||
#define DMN_W32_EXCEPTION_UNWIND_CONSOLIDATE 0x80000029u
|
||||
#define DMN_W32_EXCEPTION_DLL_NOT_FOUND 0xC0000135u
|
||||
#define DMN_W32_EXCEPTION_ORDINAL_NOT_FOUND 0xC0000138u
|
||||
#define DMN_W32_EXCEPTION_ENTRY_POINT_NOT_FOUND 0xC0000139u
|
||||
#define DMN_W32_EXCEPTION_DLL_INIT_FAILED 0xC0000142u
|
||||
#define DMN_W32_EXCEPTION_CONTROL_C_EXIT 0xC000013Au
|
||||
#define DMN_W32_EXCEPTION_FLT_MULTIPLE_FAULTS 0xC00002B4u
|
||||
#define DMN_W32_EXCEPTION_FLT_MULTIPLE_TRAPS 0xC00002B5u
|
||||
#define DMN_W32_EXCEPTION_NAT_CONSUMPTION 0xC00002C9u
|
||||
#define DMN_W32_EXCEPTION_HEAP_CORRUPTION 0xC0000374u
|
||||
#define DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN 0xC0000409u
|
||||
#define DMN_W32_EXCEPTION_INVALID_CRUNTIME_PARAM 0xC0000417u
|
||||
#define DMN_W32_EXCEPTION_ASSERT_FAILURE 0xC0000420u
|
||||
#define DMN_W32_EXCEPTION_NO_MEMORY 0xC0000017u
|
||||
#define DMN_W32_EXCEPTION_THROW 0xE06D7363u
|
||||
#define DMN_W32_EXCEPTION_SET_THREAD_NAME 0x406d1388u
|
||||
#define DMN_w32_EXCEPTION_CLRDBG_NOTIFICATION 0x04242420u
|
||||
#define DMN_w32_EXCEPTION_CLR 0xE0434352u
|
||||
#define DMN_W32_EXCEPTION_RADDBG_SET_THREAD_COLOR 0x00524144u
|
||||
#define DMN_W32_EXCEPTION_RADDBG_SET_BREAKPOINT 0x00524145u
|
||||
#define DMN_W32_EXCEPTION_RADDBG_SET_VADDR_RANGE_NOTE 0x00524156u
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32 Exception ExceptionInformation Codes
|
||||
//
|
||||
// used as a subcode, apparently in all cases, for DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN.
|
||||
// need to somehow pipe this through & interpret it correctly in outer layers... @fastfail
|
||||
|
||||
#define DMN_W32_FAST_FAIL_LEGACY_GS_VIOLATION 0
|
||||
#define DMN_W32_FAST_FAIL_VTGUARD_CHECK_FAILURE 1
|
||||
#define DMN_W32_FAST_FAIL_STACK_COOKIE_CHECK_FAILURE 2
|
||||
#define DMN_W32_FAST_FAIL_CORRUPT_LIST_ENTRY 3
|
||||
#define DMN_W32_FAST_FAIL_INCORRECT_STACK 4
|
||||
#define DMN_W32_FAST_FAIL_INVALID_ARG 5
|
||||
#define DMN_W32_FAST_FAIL_GS_COOKIE_INIT 6
|
||||
#define DMN_W32_FAST_FAIL_FATAL_APP_EXIT 7
|
||||
#define DMN_W32_FAST_FAIL_RANGE_CHECK_FAILURE 8
|
||||
#define DMN_W32_FAST_FAIL_UNSAFE_REGISTRY_ACCESS 9
|
||||
#define DMN_W32_FAST_FAIL_GUARD_ICALL_CHECK_FAILURE 10
|
||||
#define DMN_W32_FAST_FAIL_GUARD_WRITE_CHECK_FAILURE 11
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FIBER_SWITCH 12
|
||||
#define DMN_W32_FAST_FAIL_INVALID_SET_OF_CONTEXT 13
|
||||
#define DMN_W32_FAST_FAIL_INVALID_REFERENCE_COUNT 14
|
||||
#define DMN_W32_FAST_FAIL_INVALID_JUMP_BUFFER 18
|
||||
#define DMN_W32_FAST_FAIL_MRDATA_MODIFIED 19
|
||||
#define DMN_W32_FAST_FAIL_CERTIFICATION_FAILURE 20
|
||||
#define DMN_W32_FAST_FAIL_INVALID_EXCEPTION_CHAIN 21
|
||||
#define DMN_W32_FAST_FAIL_CRYPTO_LIBRARY 22
|
||||
#define DMN_W32_FAST_FAIL_INVALID_CALL_IN_DLL_CALLOUT 23
|
||||
#define DMN_W32_FAST_FAIL_INVALID_IMAGE_BASE 24
|
||||
#define DMN_W32_FAST_FAIL_DLOAD_PROTECTION_FAILURE 25
|
||||
#define DMN_W32_FAST_FAIL_UNSAFE_EXTENSION_CALL 26
|
||||
#define DMN_W32_FAST_FAIL_DEPRECATED_SERVICE_INVOKED 27
|
||||
#define DMN_W32_FAST_FAIL_INVALID_BUFFER_ACCESS 28
|
||||
#define DMN_W32_FAST_FAIL_INVALID_BALANCED_TREE 29
|
||||
#define DMN_W32_FAST_FAIL_INVALID_NEXT_THREAD 30
|
||||
#define DMN_W32_FAST_FAIL_GUARD_ICALL_CHECK_SUPPRESSED 31 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_APCS_DISABLED 32
|
||||
#define DMN_W32_FAST_FAIL_INVALID_IDLE_STATE 33
|
||||
#define DMN_W32_FAST_FAIL_MRDATA_PROTECTION_FAILURE 34
|
||||
#define DMN_W32_FAST_FAIL_UNEXPECTED_HEAP_EXCEPTION 35
|
||||
#define DMN_W32_FAST_FAIL_INVALID_LOCK_STATE 36
|
||||
#define DMN_W32_FAST_FAIL_GUARD_JUMPTABLE 37 // Known to compiler, must retain value 37
|
||||
#define DMN_W32_FAST_FAIL_INVALID_LONGJUMP_TARGET 38
|
||||
#define DMN_W32_FAST_FAIL_INVALID_DISPATCH_CONTEXT 39
|
||||
#define DMN_W32_FAST_FAIL_INVALID_THREAD 40
|
||||
#define DMN_W32_FAST_FAIL_INVALID_SYSCALL_NUMBER 41 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FILE_OPERATION 42 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_LPAC_ACCESS_DENIED 43 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_GUARD_SS_FAILURE 44
|
||||
#define DMN_W32_FAST_FAIL_LOADER_CONTINUITY_FAILURE 45 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_GUARD_EXPORT_SUPPRESSION_FAILURE 46
|
||||
#define DMN_W32_FAST_FAIL_INVALID_CONTROL_STACK 47
|
||||
#define DMN_W32_FAST_FAIL_SET_CONTEXT_DENIED 48
|
||||
#define DMN_W32_FAST_FAIL_INVALID_IAT 49
|
||||
#define DMN_W32_FAST_FAIL_HEAP_METADATA_CORRUPTION 50
|
||||
#define DMN_W32_FAST_FAIL_PAYLOAD_RESTRICTION_VIOLATION 51
|
||||
#define DMN_W32_FAST_FAIL_LOW_LABEL_ACCESS_DENIED 52 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_ENCLAVE_CALL_FAILURE 53
|
||||
#define DMN_W32_FAST_FAIL_UNHANDLED_LSS_EXCEPTON 54
|
||||
#define DMN_W32_FAST_FAIL_ADMINLESS_ACCESS_DENIED 55 // Telemetry, nonfatal
|
||||
#define DMN_W32_FAST_FAIL_UNEXPECTED_CALL 56
|
||||
#define DMN_W32_FAST_FAIL_CONTROL_INVALID_RETURN_ADDRESS 57
|
||||
#define DMN_W32_FAST_FAIL_UNEXPECTED_HOST_BEHAVIOR 58
|
||||
#define DMN_W32_FAST_FAIL_FLAGS_CORRUPTION 59
|
||||
#define DMN_W32_FAST_FAIL_VEH_CORRUPTION 60
|
||||
#define DMN_W32_FAST_FAIL_ETW_CORRUPTION 61
|
||||
#define DMN_W32_FAST_FAIL_RIO_ABORT 62
|
||||
#define DMN_W32_FAST_FAIL_INVALID_PFN 63
|
||||
#define DMN_W32_FAST_FAIL_GUARD_ICALL_CHECK_FAILURE_XFG 64
|
||||
#define DMN_W32_FAST_FAIL_CAST_GUARD 65 // Known to compiler, must retain value 65
|
||||
#define DMN_W32_FAST_FAIL_HOST_VISIBILITY_CHANGE 66
|
||||
#define DMN_W32_FAST_FAIL_KERNEL_CET_SHADOW_STACK_ASSIST 67
|
||||
#define DMN_W32_FAST_FAIL_PATCH_CALLBACK_FAILED 68
|
||||
#define DMN_W32_FAST_FAIL_NTDLL_PATCH_FAILED 69
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FLS_DATA 70
|
||||
#define DMN_W32_FAST_FAIL_INVALID_FAST_FAIL_CODE 0xFFFFFFFF
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32 Register Codes
|
||||
|
||||
#define DMN_W32_CTX_X86 0x00010000
|
||||
#define DMN_W32_CTX_X64 0x00100000
|
||||
|
||||
#define DMN_W32_CTX_INTEL_CONTROL 0x0001 // segss, rsp, segcs, rip, and rflags
|
||||
#define DMN_W32_CTX_INTEL_INTEGER 0x0002 // rax, rcx, rdx, rbx, rbp, rsi, rdi, and r8-r15
|
||||
#define DMN_W32_CTX_INTEL_SEGMENTS 0x0004 // segds, seges, segfs, and seggs
|
||||
#define DMN_W32_CTX_INTEL_FLOATS 0x0008 // xmm0-xmm15
|
||||
#define DMN_W32_CTX_INTEL_DEBUG 0x0010 // dr0-dr3 and dr6-dr7
|
||||
#define DMN_W32_CTX_INTEL_EXTENDED 0x0020
|
||||
#define DMN_W32_CTX_INTEL_XSTATE 0x0040
|
||||
|
||||
#define DMN_W32_CTX_X86_ALL (DMN_W32_CTX_X86 | \
|
||||
DMN_W32_CTX_INTEL_CONTROL | DMN_W32_CTX_INTEL_INTEGER | \
|
||||
DMN_W32_CTX_INTEL_SEGMENTS | DMN_W32_CTX_INTEL_DEBUG | \
|
||||
DMN_W32_CTX_INTEL_EXTENDED)
|
||||
#define DMN_W32_CTX_X64_ALL (DMN_W32_CTX_X64 | \
|
||||
DMN_W32_CTX_INTEL_CONTROL | DMN_W32_CTX_INTEL_INTEGER | \
|
||||
DMN_W32_CTX_INTEL_SEGMENTS | DMN_W32_CTX_INTEL_FLOATS | \
|
||||
DMN_W32_CTX_INTEL_DEBUG)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Per-Entity State
|
||||
|
||||
typedef enum DMN_W32_EntityKind
|
||||
{
|
||||
DMN_W32_EntityKind_Null,
|
||||
DMN_W32_EntityKind_Root,
|
||||
DMN_W32_EntityKind_Process,
|
||||
DMN_W32_EntityKind_Thread,
|
||||
DMN_W32_EntityKind_Module,
|
||||
DMN_W32_EntityKind_COUNT
|
||||
}
|
||||
DMN_W32_EntityKind;
|
||||
|
||||
typedef struct DMN_W32_Entity DMN_W32_Entity;
|
||||
struct DMN_W32_Entity
|
||||
{
|
||||
DMN_W32_Entity *first;
|
||||
DMN_W32_Entity *last;
|
||||
DMN_W32_Entity *next;
|
||||
DMN_W32_Entity *prev;
|
||||
DMN_W32_Entity *parent;
|
||||
DMN_W32_EntityKind kind;
|
||||
U32 gen;
|
||||
U64 id;
|
||||
HANDLE handle;
|
||||
Arch arch;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
U64 injection_address;
|
||||
B32 did_first_bp;
|
||||
}
|
||||
proc;
|
||||
struct
|
||||
{
|
||||
U64 thread_local_base;
|
||||
U64 last_name_hash;
|
||||
U64 name_gather_time_us;
|
||||
}
|
||||
thread;
|
||||
struct
|
||||
{
|
||||
Rng1U64 vaddr_range;
|
||||
U64 address_of_name_pointer;
|
||||
B32 is_main;
|
||||
B32 name_is_unicode;
|
||||
}
|
||||
module;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct DMN_W32_EntityNode DMN_W32_EntityNode;
|
||||
struct DMN_W32_EntityNode
|
||||
{
|
||||
DMN_W32_EntityNode *next;
|
||||
DMN_W32_Entity *v;
|
||||
};
|
||||
|
||||
typedef struct DMN_W32_EntityIDHashNode DMN_W32_EntityIDHashNode;
|
||||
struct DMN_W32_EntityIDHashNode
|
||||
{
|
||||
DMN_W32_EntityIDHashNode *next;
|
||||
DMN_W32_EntityIDHashNode *prev;
|
||||
U64 id;
|
||||
DMN_W32_Entity *entity;
|
||||
};
|
||||
|
||||
typedef struct DMN_W32_EntityIDHashSlot DMN_W32_EntityIDHashSlot;
|
||||
struct DMN_W32_EntityIDHashSlot
|
||||
{
|
||||
DMN_W32_EntityIDHashNode *first;
|
||||
DMN_W32_EntityIDHashNode *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Injection Types
|
||||
|
||||
typedef struct DMN_W32_InjectedBreak DMN_W32_InjectedBreak;
|
||||
struct DMN_W32_InjectedBreak
|
||||
{
|
||||
U64 code;
|
||||
U64 user_data;
|
||||
};
|
||||
|
||||
#define DMN_W32_INJECTED_CODE_SIZE 32
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Image Info Types
|
||||
|
||||
typedef struct DMN_W32_ImageInfo DMN_W32_ImageInfo;
|
||||
struct DMN_W32_ImageInfo
|
||||
{
|
||||
Arch arch;
|
||||
U32 size;
|
||||
U64 tls_index;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Dynamically-Loaded Win32 Function Types
|
||||
|
||||
typedef HRESULT DMN_W32_GetThreadDescriptionFunctionType(HANDLE hThread, WCHAR **ppszThreadDescription);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Shared State Bundle
|
||||
|
||||
typedef struct DMN_W32_Shared DMN_W32_Shared;
|
||||
struct DMN_W32_Shared
|
||||
{
|
||||
// rjf: top-level info
|
||||
Arena *arena;
|
||||
String8List env_strings;
|
||||
|
||||
// rjf: access locking mechanism
|
||||
Mutex access_mutex;
|
||||
B32 access_run_state;
|
||||
|
||||
// rjf: detaching info
|
||||
Arena *detach_arena;
|
||||
DMN_HandleList detach_processes;
|
||||
|
||||
// rjf: entity state
|
||||
Arena *entities_arena;
|
||||
DMN_W32_Entity *entities_base;
|
||||
DMN_W32_Entity *entities_first_free;
|
||||
U64 entities_count;
|
||||
DMN_W32_EntityIDHashSlot *entities_id_hash_slots;
|
||||
U64 entities_id_hash_slots_count;
|
||||
DMN_W32_EntityIDHashNode *entities_id_hash_node_free;
|
||||
|
||||
// rjf: launch state
|
||||
B32 new_process_pending;
|
||||
|
||||
// rjf: run results
|
||||
B32 resume_needed;
|
||||
U32 resume_pid;
|
||||
U32 resume_tid;
|
||||
B32 exception_not_handled;
|
||||
|
||||
// rjf: halting info
|
||||
DMN_Handle halter_process;
|
||||
U32 halter_tid;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
global DMN_W32_Shared *dmn_w32_shared = 0;
|
||||
global DMN_W32_Entity dmn_w32_entity_nil = {&dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil, &dmn_w32_entity_nil};
|
||||
global DMN_W32_GetThreadDescriptionFunctionType *dmn_w32_GetThreadDescription = 0;
|
||||
thread_static B32 dmn_w32_ctrl_thread = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
internal U64 dmn_w32_hash_from_string(String8 string);
|
||||
internal U64 dmn_w32_hash_from_id(U64 id);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Entity Helpers
|
||||
|
||||
//- rjf: entity <-> handle
|
||||
internal DMN_Handle dmn_w32_handle_from_entity(DMN_W32_Entity *entity);
|
||||
internal DMN_W32_Entity *dmn_w32_entity_from_handle(DMN_Handle handle);
|
||||
|
||||
//- rjf: entity allocation/deallocation
|
||||
internal DMN_W32_Entity *dmn_w32_entity_alloc(DMN_W32_Entity *parent, DMN_W32_EntityKind kind, U64 id);
|
||||
internal void dmn_w32_entity_release(DMN_W32_Entity *entity);
|
||||
|
||||
//- rjf: kind*id -> entity
|
||||
internal DMN_W32_Entity *dmn_w32_entity_from_kind_id(DMN_W32_EntityKind kind, U64 id);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Module Info Extraction
|
||||
|
||||
internal String8 dmn_w32_full_path_from_module(Arena *arena, DMN_W32_Entity *module);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Win32-Level Process/Thread Reads/Writes
|
||||
|
||||
//- rjf: processes
|
||||
internal U64 dmn_w32_process_read(HANDLE process, Rng1U64 range, void *dst);
|
||||
internal B32 dmn_w32_process_write(HANDLE process, Rng1U64 range, void *src);
|
||||
internal String8 dmn_w32_read_memory_str(Arena *arena, HANDLE process_handle, U64 address);
|
||||
internal String16 dmn_w32_read_memory_str16(Arena *arena, HANDLE process_handle, U64 address);
|
||||
#define dmn_w32_process_read_struct(process, vaddr, ptr) dmn_w32_process_read((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
|
||||
#define dmn_w32_process_write_struct(process, vaddr, ptr) dmn_w32_process_write((process), r1u64((vaddr), (vaddr)+(sizeof(*ptr))), ptr)
|
||||
internal DMN_W32_ImageInfo dmn_w32_image_info_from_process_base_vaddr(HANDLE process, U64 base_vaddr);
|
||||
|
||||
//- rjf: threads
|
||||
internal B32 dmn_w32_thread_read_reg_block(Arch arch, HANDLE thread, void *reg_block);
|
||||
internal B32 dmn_w32_thread_write_reg_block(Arch arch, HANDLE thread, void *reg_block);
|
||||
|
||||
//- rjf: remote thread injection
|
||||
internal DWORD dmn_w32_inject_thread(HANDLE process, U64 start_address);
|
||||
|
||||
#endif // DEMON_CORE_WIN32_H
|
||||
+1687
-1687
File diff suppressed because it is too large
Load Diff
+123
-123
@@ -1,123 +1,123 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_GFX_WIN32_H
|
||||
#define OS_GFX_WIN32_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes / Libraries
|
||||
|
||||
#include <uxtheme.h>
|
||||
#include <dwmapi.h>
|
||||
#include <shellscalingapi.h>
|
||||
#pragma comment(lib, "gdi32")
|
||||
#pragma comment(lib, "dwmapi")
|
||||
#pragma comment(lib, "UxTheme")
|
||||
#pragma comment(lib, "comdlg32")
|
||||
#ifndef WM_NCUAHDRAWCAPTION
|
||||
#define WM_NCUAHDRAWCAPTION (0x00AE)
|
||||
#endif
|
||||
#ifndef WM_NCUAHDRAWFRAME
|
||||
#define WM_NCUAHDRAWFRAME (0x00AF)
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Windows
|
||||
|
||||
typedef struct OS_W32_TitleBarClientArea OS_W32_TitleBarClientArea;
|
||||
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;
|
||||
HDC hdc;
|
||||
WINDOWPLACEMENT last_window_placement;
|
||||
F32 dpi;
|
||||
B32 first_paint_done;
|
||||
B32 maximized;
|
||||
B32 custom_border;
|
||||
F32 custom_border_title_thickness;
|
||||
F32 custom_border_edge_thickness;
|
||||
B32 custom_border_composition_enabled;
|
||||
Arena *paint_arena;
|
||||
OS_W32_TitleBarClientArea *first_title_bar_client_area;
|
||||
OS_W32_TitleBarClientArea *last_title_bar_client_area;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Monitor Gathering Bundle
|
||||
|
||||
typedef struct OS_W32_MonitorGatherNode OS_W32_MonitorGatherNode;
|
||||
struct OS_W32_MonitorGatherNode
|
||||
{
|
||||
OS_W32_MonitorGatherNode *next;
|
||||
OS_Monitor v;
|
||||
};
|
||||
|
||||
typedef struct OS_W32_MonitorGatherBundle OS_W32_MonitorGatherBundle;
|
||||
struct OS_W32_MonitorGatherBundle
|
||||
{
|
||||
Arena *arena;
|
||||
OS_W32_MonitorGatherNode *first_monitor;
|
||||
OS_W32_MonitorGatherNode *last_monitor;
|
||||
U64 monitor_count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Global State
|
||||
|
||||
typedef struct OS_W32_GfxState OS_W32_GfxState;
|
||||
struct OS_W32_GfxState
|
||||
{
|
||||
Arena *arena;
|
||||
U32 gfx_thread_tid;
|
||||
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];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: 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;
|
||||
global B32 os_w32_resizing = 0;
|
||||
global B32 os_w32_new_window_custom_border = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
internal Rng2F32 os_w32_rng2f32_from_rect(RECT rect);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Windows
|
||||
|
||||
internal OS_Window os_w32_handle_from_window(OS_W32_Window *window);
|
||||
internal OS_W32_Window * os_w32_window_from_handle(OS_Window 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);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Monitors
|
||||
|
||||
internal BOOL os_w32_monitor_gather_enum_proc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM bundle_ptr);
|
||||
|
||||
#endif // OS_GFX_WIN32_H
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef WIN32_WINDOW_MANAGER_H
|
||||
#define WIN32_WINDOW_MANAGER_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Includes / Libraries
|
||||
|
||||
#include <uxtheme.h>
|
||||
#include <dwmapi.h>
|
||||
#include <shellscalingapi.h>
|
||||
#pragma comment(lib, "gdi32")
|
||||
#pragma comment(lib, "dwmapi")
|
||||
#pragma comment(lib, "UxTheme")
|
||||
#pragma comment(lib, "comdlg32")
|
||||
#ifndef WM_NCUAHDRAWCAPTION
|
||||
#define WM_NCUAHDRAWCAPTION (0x00AE)
|
||||
#endif
|
||||
#ifndef WM_NCUAHDRAWFRAME
|
||||
#define WM_NCUAHDRAWFRAME (0x00AF)
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Windows
|
||||
|
||||
typedef struct OS_W32_TitleBarClientArea OS_W32_TitleBarClientArea;
|
||||
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;
|
||||
HDC hdc;
|
||||
WINDOWPLACEMENT last_window_placement;
|
||||
F32 dpi;
|
||||
B32 first_paint_done;
|
||||
B32 maximized;
|
||||
B32 custom_border;
|
||||
F32 custom_border_title_thickness;
|
||||
F32 custom_border_edge_thickness;
|
||||
B32 custom_border_composition_enabled;
|
||||
Arena *paint_arena;
|
||||
OS_W32_TitleBarClientArea *first_title_bar_client_area;
|
||||
OS_W32_TitleBarClientArea *last_title_bar_client_area;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Monitor Gathering Bundle
|
||||
|
||||
typedef struct OS_W32_MonitorGatherNode OS_W32_MonitorGatherNode;
|
||||
struct OS_W32_MonitorGatherNode
|
||||
{
|
||||
OS_W32_MonitorGatherNode *next;
|
||||
OS_Monitor v;
|
||||
};
|
||||
|
||||
typedef struct OS_W32_MonitorGatherBundle OS_W32_MonitorGatherBundle;
|
||||
struct OS_W32_MonitorGatherBundle
|
||||
{
|
||||
Arena *arena;
|
||||
OS_W32_MonitorGatherNode *first_monitor;
|
||||
OS_W32_MonitorGatherNode *last_monitor;
|
||||
U64 monitor_count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Global State
|
||||
|
||||
typedef struct OS_W32_GfxState OS_W32_GfxState;
|
||||
struct OS_W32_GfxState
|
||||
{
|
||||
Arena *arena;
|
||||
U32 gfx_thread_tid;
|
||||
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];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: 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;
|
||||
global B32 os_w32_resizing = 0;
|
||||
global B32 os_w32_new_window_custom_border = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
internal Rng2F32 os_w32_rng2f32_from_rect(RECT rect);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Windows
|
||||
|
||||
internal OS_Window os_w32_handle_from_window(OS_W32_Window *window);
|
||||
internal OS_W32_Window * os_w32_window_from_handle(OS_Window 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);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Monitors
|
||||
|
||||
internal BOOL os_w32_monitor_gather_enum_proc(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM bundle_ptr);
|
||||
|
||||
#endif // WIN32_WINDOW_MANAGER_H
|
||||
+302
-302
@@ -1,302 +1,302 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
//- GENERATED CODE
|
||||
|
||||
C_LINKAGE_BEGIN
|
||||
String8 os_g_key_display_string_table[143] =
|
||||
{
|
||||
str8_lit_comp("Invalid Key"),
|
||||
str8_lit_comp("Escape"),
|
||||
str8_lit_comp("F1"),
|
||||
str8_lit_comp("F2"),
|
||||
str8_lit_comp("F3"),
|
||||
str8_lit_comp("F4"),
|
||||
str8_lit_comp("F5"),
|
||||
str8_lit_comp("F6"),
|
||||
str8_lit_comp("F7"),
|
||||
str8_lit_comp("F8"),
|
||||
str8_lit_comp("F9"),
|
||||
str8_lit_comp("F10"),
|
||||
str8_lit_comp("F11"),
|
||||
str8_lit_comp("F12"),
|
||||
str8_lit_comp("F13"),
|
||||
str8_lit_comp("F14"),
|
||||
str8_lit_comp("F15"),
|
||||
str8_lit_comp("F16"),
|
||||
str8_lit_comp("F17"),
|
||||
str8_lit_comp("F18"),
|
||||
str8_lit_comp("F19"),
|
||||
str8_lit_comp("F20"),
|
||||
str8_lit_comp("F21"),
|
||||
str8_lit_comp("F22"),
|
||||
str8_lit_comp("F23"),
|
||||
str8_lit_comp("F24"),
|
||||
str8_lit_comp("Tick"),
|
||||
str8_lit_comp("0"),
|
||||
str8_lit_comp("1"),
|
||||
str8_lit_comp("2"),
|
||||
str8_lit_comp("3"),
|
||||
str8_lit_comp("4"),
|
||||
str8_lit_comp("5"),
|
||||
str8_lit_comp("6"),
|
||||
str8_lit_comp("7"),
|
||||
str8_lit_comp("8"),
|
||||
str8_lit_comp("9"),
|
||||
str8_lit_comp("Minus"),
|
||||
str8_lit_comp("Equal"),
|
||||
str8_lit_comp("Backspace"),
|
||||
str8_lit_comp("Tab"),
|
||||
str8_lit_comp("Q"),
|
||||
str8_lit_comp("W"),
|
||||
str8_lit_comp("E"),
|
||||
str8_lit_comp("R"),
|
||||
str8_lit_comp("T"),
|
||||
str8_lit_comp("Y"),
|
||||
str8_lit_comp("U"),
|
||||
str8_lit_comp("I"),
|
||||
str8_lit_comp("O"),
|
||||
str8_lit_comp("P"),
|
||||
str8_lit_comp("Left Bracket"),
|
||||
str8_lit_comp("Right Bracket"),
|
||||
str8_lit_comp("Back Slash"),
|
||||
str8_lit_comp("Caps Lock"),
|
||||
str8_lit_comp("A"),
|
||||
str8_lit_comp("S"),
|
||||
str8_lit_comp("D"),
|
||||
str8_lit_comp("F"),
|
||||
str8_lit_comp("G"),
|
||||
str8_lit_comp("H"),
|
||||
str8_lit_comp("J"),
|
||||
str8_lit_comp("K"),
|
||||
str8_lit_comp("L"),
|
||||
str8_lit_comp("Semicolon"),
|
||||
str8_lit_comp("Quote"),
|
||||
str8_lit_comp("Return"),
|
||||
str8_lit_comp("Shift"),
|
||||
str8_lit_comp("Z"),
|
||||
str8_lit_comp("X"),
|
||||
str8_lit_comp("C"),
|
||||
str8_lit_comp("V"),
|
||||
str8_lit_comp("B"),
|
||||
str8_lit_comp("N"),
|
||||
str8_lit_comp("M"),
|
||||
str8_lit_comp("Comma"),
|
||||
str8_lit_comp("Period"),
|
||||
str8_lit_comp("Slash"),
|
||||
str8_lit_comp("Ctrl"),
|
||||
str8_lit_comp("Alt"),
|
||||
str8_lit_comp("Space"),
|
||||
str8_lit_comp("Menu"),
|
||||
str8_lit_comp("Scroll Lock"),
|
||||
str8_lit_comp("Pause"),
|
||||
str8_lit_comp("Insert"),
|
||||
str8_lit_comp("Home"),
|
||||
str8_lit_comp("Page Up"),
|
||||
str8_lit_comp("Delete"),
|
||||
str8_lit_comp("End"),
|
||||
str8_lit_comp("Page Down"),
|
||||
str8_lit_comp("Up"),
|
||||
str8_lit_comp("Left"),
|
||||
str8_lit_comp("Down"),
|
||||
str8_lit_comp("Right"),
|
||||
str8_lit_comp("Ex0"),
|
||||
str8_lit_comp("Ex1"),
|
||||
str8_lit_comp("Ex2"),
|
||||
str8_lit_comp("Ex3"),
|
||||
str8_lit_comp("Ex4"),
|
||||
str8_lit_comp("Ex5"),
|
||||
str8_lit_comp("Ex6"),
|
||||
str8_lit_comp("Ex7"),
|
||||
str8_lit_comp("Ex8"),
|
||||
str8_lit_comp("Ex9"),
|
||||
str8_lit_comp("Ex10"),
|
||||
str8_lit_comp("Ex11"),
|
||||
str8_lit_comp("Ex12"),
|
||||
str8_lit_comp("Ex13"),
|
||||
str8_lit_comp("Ex14"),
|
||||
str8_lit_comp("Ex15"),
|
||||
str8_lit_comp("Ex16"),
|
||||
str8_lit_comp("Ex17"),
|
||||
str8_lit_comp("Ex18"),
|
||||
str8_lit_comp("Ex19"),
|
||||
str8_lit_comp("Ex20"),
|
||||
str8_lit_comp("Ex21"),
|
||||
str8_lit_comp("Ex22"),
|
||||
str8_lit_comp("Ex23"),
|
||||
str8_lit_comp("Ex24"),
|
||||
str8_lit_comp("Ex25"),
|
||||
str8_lit_comp("Ex26"),
|
||||
str8_lit_comp("Ex27"),
|
||||
str8_lit_comp("Ex28"),
|
||||
str8_lit_comp("Ex29"),
|
||||
str8_lit_comp("Num Lock"),
|
||||
str8_lit_comp("Numpad Slash"),
|
||||
str8_lit_comp("Numpad Star"),
|
||||
str8_lit_comp("Numpad Minus"),
|
||||
str8_lit_comp("Numpad Plus"),
|
||||
str8_lit_comp("Numpad Period"),
|
||||
str8_lit_comp("Numpad 0"),
|
||||
str8_lit_comp("Numpad 1"),
|
||||
str8_lit_comp("Numpad 2"),
|
||||
str8_lit_comp("Numpad 3"),
|
||||
str8_lit_comp("Numpad 4"),
|
||||
str8_lit_comp("Numpad 5"),
|
||||
str8_lit_comp("Numpad 6"),
|
||||
str8_lit_comp("Numpad 7"),
|
||||
str8_lit_comp("Numpad 8"),
|
||||
str8_lit_comp("Numpad 9"),
|
||||
str8_lit_comp("Left Mouse Button"),
|
||||
str8_lit_comp("Middle Mouse Button"),
|
||||
str8_lit_comp("Right Mouse Button"),
|
||||
};
|
||||
|
||||
String8 os_g_key_cfg_string_table[143] =
|
||||
{
|
||||
str8_lit_comp("null"),
|
||||
str8_lit_comp("esc"),
|
||||
str8_lit_comp("f1"),
|
||||
str8_lit_comp("f2"),
|
||||
str8_lit_comp("f3"),
|
||||
str8_lit_comp("f4"),
|
||||
str8_lit_comp("f5"),
|
||||
str8_lit_comp("f6"),
|
||||
str8_lit_comp("f7"),
|
||||
str8_lit_comp("f8"),
|
||||
str8_lit_comp("f9"),
|
||||
str8_lit_comp("f10"),
|
||||
str8_lit_comp("f11"),
|
||||
str8_lit_comp("f12"),
|
||||
str8_lit_comp("f13"),
|
||||
str8_lit_comp("f14"),
|
||||
str8_lit_comp("f15"),
|
||||
str8_lit_comp("f16"),
|
||||
str8_lit_comp("f17"),
|
||||
str8_lit_comp("f18"),
|
||||
str8_lit_comp("f19"),
|
||||
str8_lit_comp("f20"),
|
||||
str8_lit_comp("f21"),
|
||||
str8_lit_comp("f22"),
|
||||
str8_lit_comp("f23"),
|
||||
str8_lit_comp("f24"),
|
||||
str8_lit_comp("tick"),
|
||||
str8_lit_comp("0"),
|
||||
str8_lit_comp("1"),
|
||||
str8_lit_comp("2"),
|
||||
str8_lit_comp("3"),
|
||||
str8_lit_comp("4"),
|
||||
str8_lit_comp("5"),
|
||||
str8_lit_comp("6"),
|
||||
str8_lit_comp("7"),
|
||||
str8_lit_comp("8"),
|
||||
str8_lit_comp("9"),
|
||||
str8_lit_comp("minus"),
|
||||
str8_lit_comp("equal"),
|
||||
str8_lit_comp("backspace"),
|
||||
str8_lit_comp("tab"),
|
||||
str8_lit_comp("q"),
|
||||
str8_lit_comp("w"),
|
||||
str8_lit_comp("e"),
|
||||
str8_lit_comp("r"),
|
||||
str8_lit_comp("t"),
|
||||
str8_lit_comp("y"),
|
||||
str8_lit_comp("u"),
|
||||
str8_lit_comp("i"),
|
||||
str8_lit_comp("o"),
|
||||
str8_lit_comp("p"),
|
||||
str8_lit_comp("left_bracket"),
|
||||
str8_lit_comp("right_bracket"),
|
||||
str8_lit_comp("backslash"),
|
||||
str8_lit_comp("caps_lock"),
|
||||
str8_lit_comp("a"),
|
||||
str8_lit_comp("s"),
|
||||
str8_lit_comp("d"),
|
||||
str8_lit_comp("f"),
|
||||
str8_lit_comp("g"),
|
||||
str8_lit_comp("h"),
|
||||
str8_lit_comp("j"),
|
||||
str8_lit_comp("k"),
|
||||
str8_lit_comp("l"),
|
||||
str8_lit_comp("semicolon"),
|
||||
str8_lit_comp("quote"),
|
||||
str8_lit_comp("return"),
|
||||
str8_lit_comp("shift"),
|
||||
str8_lit_comp("z"),
|
||||
str8_lit_comp("x"),
|
||||
str8_lit_comp("c"),
|
||||
str8_lit_comp("v"),
|
||||
str8_lit_comp("b"),
|
||||
str8_lit_comp("n"),
|
||||
str8_lit_comp("m"),
|
||||
str8_lit_comp("comma"),
|
||||
str8_lit_comp("period"),
|
||||
str8_lit_comp("slash"),
|
||||
str8_lit_comp("ctrl"),
|
||||
str8_lit_comp("alt"),
|
||||
str8_lit_comp("space"),
|
||||
str8_lit_comp("menu"),
|
||||
str8_lit_comp("scroll_lock"),
|
||||
str8_lit_comp("pause"),
|
||||
str8_lit_comp("insert"),
|
||||
str8_lit_comp("home"),
|
||||
str8_lit_comp("page_up"),
|
||||
str8_lit_comp("delete"),
|
||||
str8_lit_comp("end"),
|
||||
str8_lit_comp("page_down"),
|
||||
str8_lit_comp("up"),
|
||||
str8_lit_comp("left"),
|
||||
str8_lit_comp("down"),
|
||||
str8_lit_comp("right"),
|
||||
str8_lit_comp("ex0"),
|
||||
str8_lit_comp("ex1"),
|
||||
str8_lit_comp("ex2"),
|
||||
str8_lit_comp("ex3"),
|
||||
str8_lit_comp("ex4"),
|
||||
str8_lit_comp("ex5"),
|
||||
str8_lit_comp("ex6"),
|
||||
str8_lit_comp("ex7"),
|
||||
str8_lit_comp("ex8"),
|
||||
str8_lit_comp("ex9"),
|
||||
str8_lit_comp("ex10"),
|
||||
str8_lit_comp("ex11"),
|
||||
str8_lit_comp("ex12"),
|
||||
str8_lit_comp("ex13"),
|
||||
str8_lit_comp("ex14"),
|
||||
str8_lit_comp("ex15"),
|
||||
str8_lit_comp("ex16"),
|
||||
str8_lit_comp("ex17"),
|
||||
str8_lit_comp("ex18"),
|
||||
str8_lit_comp("ex19"),
|
||||
str8_lit_comp("ex20"),
|
||||
str8_lit_comp("ex21"),
|
||||
str8_lit_comp("ex22"),
|
||||
str8_lit_comp("ex23"),
|
||||
str8_lit_comp("ex24"),
|
||||
str8_lit_comp("ex25"),
|
||||
str8_lit_comp("ex26"),
|
||||
str8_lit_comp("ex27"),
|
||||
str8_lit_comp("ex28"),
|
||||
str8_lit_comp("ex29"),
|
||||
str8_lit_comp("num_lock"),
|
||||
str8_lit_comp("numpad_slash"),
|
||||
str8_lit_comp("numpad_star"),
|
||||
str8_lit_comp("numpad_minus"),
|
||||
str8_lit_comp("numpad_plus"),
|
||||
str8_lit_comp("numpad_period"),
|
||||
str8_lit_comp("numpad_0"),
|
||||
str8_lit_comp("numpad_1"),
|
||||
str8_lit_comp("numpad_2"),
|
||||
str8_lit_comp("numpad_3"),
|
||||
str8_lit_comp("numpad_4"),
|
||||
str8_lit_comp("numpad_5"),
|
||||
str8_lit_comp("numpad_6"),
|
||||
str8_lit_comp("numpad_7"),
|
||||
str8_lit_comp("numpad_8"),
|
||||
str8_lit_comp("numpad_9"),
|
||||
str8_lit_comp("left_mouse"),
|
||||
str8_lit_comp("middle_mouse"),
|
||||
str8_lit_comp("right_mouse"),
|
||||
};
|
||||
|
||||
C_LINKAGE_END
|
||||
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
//- GENERATED CODE
|
||||
|
||||
C_LINKAGE_BEGIN
|
||||
String8 os_g_key_display_string_table[143] =
|
||||
{
|
||||
str8_lit_comp("Invalid Key"),
|
||||
str8_lit_comp("Escape"),
|
||||
str8_lit_comp("F1"),
|
||||
str8_lit_comp("F2"),
|
||||
str8_lit_comp("F3"),
|
||||
str8_lit_comp("F4"),
|
||||
str8_lit_comp("F5"),
|
||||
str8_lit_comp("F6"),
|
||||
str8_lit_comp("F7"),
|
||||
str8_lit_comp("F8"),
|
||||
str8_lit_comp("F9"),
|
||||
str8_lit_comp("F10"),
|
||||
str8_lit_comp("F11"),
|
||||
str8_lit_comp("F12"),
|
||||
str8_lit_comp("F13"),
|
||||
str8_lit_comp("F14"),
|
||||
str8_lit_comp("F15"),
|
||||
str8_lit_comp("F16"),
|
||||
str8_lit_comp("F17"),
|
||||
str8_lit_comp("F18"),
|
||||
str8_lit_comp("F19"),
|
||||
str8_lit_comp("F20"),
|
||||
str8_lit_comp("F21"),
|
||||
str8_lit_comp("F22"),
|
||||
str8_lit_comp("F23"),
|
||||
str8_lit_comp("F24"),
|
||||
str8_lit_comp("Tick"),
|
||||
str8_lit_comp("0"),
|
||||
str8_lit_comp("1"),
|
||||
str8_lit_comp("2"),
|
||||
str8_lit_comp("3"),
|
||||
str8_lit_comp("4"),
|
||||
str8_lit_comp("5"),
|
||||
str8_lit_comp("6"),
|
||||
str8_lit_comp("7"),
|
||||
str8_lit_comp("8"),
|
||||
str8_lit_comp("9"),
|
||||
str8_lit_comp("Minus"),
|
||||
str8_lit_comp("Equal"),
|
||||
str8_lit_comp("Backspace"),
|
||||
str8_lit_comp("Tab"),
|
||||
str8_lit_comp("Q"),
|
||||
str8_lit_comp("W"),
|
||||
str8_lit_comp("E"),
|
||||
str8_lit_comp("R"),
|
||||
str8_lit_comp("T"),
|
||||
str8_lit_comp("Y"),
|
||||
str8_lit_comp("U"),
|
||||
str8_lit_comp("I"),
|
||||
str8_lit_comp("O"),
|
||||
str8_lit_comp("P"),
|
||||
str8_lit_comp("Left Bracket"),
|
||||
str8_lit_comp("Right Bracket"),
|
||||
str8_lit_comp("Back Slash"),
|
||||
str8_lit_comp("Caps Lock"),
|
||||
str8_lit_comp("A"),
|
||||
str8_lit_comp("S"),
|
||||
str8_lit_comp("D"),
|
||||
str8_lit_comp("F"),
|
||||
str8_lit_comp("G"),
|
||||
str8_lit_comp("H"),
|
||||
str8_lit_comp("J"),
|
||||
str8_lit_comp("K"),
|
||||
str8_lit_comp("L"),
|
||||
str8_lit_comp("Semicolon"),
|
||||
str8_lit_comp("Quote"),
|
||||
str8_lit_comp("Return"),
|
||||
str8_lit_comp("Shift"),
|
||||
str8_lit_comp("Z"),
|
||||
str8_lit_comp("X"),
|
||||
str8_lit_comp("C"),
|
||||
str8_lit_comp("V"),
|
||||
str8_lit_comp("B"),
|
||||
str8_lit_comp("N"),
|
||||
str8_lit_comp("M"),
|
||||
str8_lit_comp("Comma"),
|
||||
str8_lit_comp("Period"),
|
||||
str8_lit_comp("Slash"),
|
||||
str8_lit_comp("Ctrl"),
|
||||
str8_lit_comp("Alt"),
|
||||
str8_lit_comp("Space"),
|
||||
str8_lit_comp("Menu"),
|
||||
str8_lit_comp("Scroll Lock"),
|
||||
str8_lit_comp("Pause"),
|
||||
str8_lit_comp("Insert"),
|
||||
str8_lit_comp("Home"),
|
||||
str8_lit_comp("Page Up"),
|
||||
str8_lit_comp("Delete"),
|
||||
str8_lit_comp("End"),
|
||||
str8_lit_comp("Page Down"),
|
||||
str8_lit_comp("Up"),
|
||||
str8_lit_comp("Left"),
|
||||
str8_lit_comp("Down"),
|
||||
str8_lit_comp("Right"),
|
||||
str8_lit_comp("Ex0"),
|
||||
str8_lit_comp("Ex1"),
|
||||
str8_lit_comp("Ex2"),
|
||||
str8_lit_comp("Ex3"),
|
||||
str8_lit_comp("Ex4"),
|
||||
str8_lit_comp("Ex5"),
|
||||
str8_lit_comp("Ex6"),
|
||||
str8_lit_comp("Ex7"),
|
||||
str8_lit_comp("Ex8"),
|
||||
str8_lit_comp("Ex9"),
|
||||
str8_lit_comp("Ex10"),
|
||||
str8_lit_comp("Ex11"),
|
||||
str8_lit_comp("Ex12"),
|
||||
str8_lit_comp("Ex13"),
|
||||
str8_lit_comp("Ex14"),
|
||||
str8_lit_comp("Ex15"),
|
||||
str8_lit_comp("Ex16"),
|
||||
str8_lit_comp("Ex17"),
|
||||
str8_lit_comp("Ex18"),
|
||||
str8_lit_comp("Ex19"),
|
||||
str8_lit_comp("Ex20"),
|
||||
str8_lit_comp("Ex21"),
|
||||
str8_lit_comp("Ex22"),
|
||||
str8_lit_comp("Ex23"),
|
||||
str8_lit_comp("Ex24"),
|
||||
str8_lit_comp("Ex25"),
|
||||
str8_lit_comp("Ex26"),
|
||||
str8_lit_comp("Ex27"),
|
||||
str8_lit_comp("Ex28"),
|
||||
str8_lit_comp("Ex29"),
|
||||
str8_lit_comp("Num Lock"),
|
||||
str8_lit_comp("Numpad Slash"),
|
||||
str8_lit_comp("Numpad Star"),
|
||||
str8_lit_comp("Numpad Minus"),
|
||||
str8_lit_comp("Numpad Plus"),
|
||||
str8_lit_comp("Numpad Period"),
|
||||
str8_lit_comp("Numpad 0"),
|
||||
str8_lit_comp("Numpad 1"),
|
||||
str8_lit_comp("Numpad 2"),
|
||||
str8_lit_comp("Numpad 3"),
|
||||
str8_lit_comp("Numpad 4"),
|
||||
str8_lit_comp("Numpad 5"),
|
||||
str8_lit_comp("Numpad 6"),
|
||||
str8_lit_comp("Numpad 7"),
|
||||
str8_lit_comp("Numpad 8"),
|
||||
str8_lit_comp("Numpad 9"),
|
||||
str8_lit_comp("Left Mouse Button"),
|
||||
str8_lit_comp("Middle Mouse Button"),
|
||||
str8_lit_comp("Right Mouse Button"),
|
||||
};
|
||||
|
||||
String8 os_g_key_cfg_string_table[143] =
|
||||
{
|
||||
str8_lit_comp("null"),
|
||||
str8_lit_comp("esc"),
|
||||
str8_lit_comp("f1"),
|
||||
str8_lit_comp("f2"),
|
||||
str8_lit_comp("f3"),
|
||||
str8_lit_comp("f4"),
|
||||
str8_lit_comp("f5"),
|
||||
str8_lit_comp("f6"),
|
||||
str8_lit_comp("f7"),
|
||||
str8_lit_comp("f8"),
|
||||
str8_lit_comp("f9"),
|
||||
str8_lit_comp("f10"),
|
||||
str8_lit_comp("f11"),
|
||||
str8_lit_comp("f12"),
|
||||
str8_lit_comp("f13"),
|
||||
str8_lit_comp("f14"),
|
||||
str8_lit_comp("f15"),
|
||||
str8_lit_comp("f16"),
|
||||
str8_lit_comp("f17"),
|
||||
str8_lit_comp("f18"),
|
||||
str8_lit_comp("f19"),
|
||||
str8_lit_comp("f20"),
|
||||
str8_lit_comp("f21"),
|
||||
str8_lit_comp("f22"),
|
||||
str8_lit_comp("f23"),
|
||||
str8_lit_comp("f24"),
|
||||
str8_lit_comp("tick"),
|
||||
str8_lit_comp("0"),
|
||||
str8_lit_comp("1"),
|
||||
str8_lit_comp("2"),
|
||||
str8_lit_comp("3"),
|
||||
str8_lit_comp("4"),
|
||||
str8_lit_comp("5"),
|
||||
str8_lit_comp("6"),
|
||||
str8_lit_comp("7"),
|
||||
str8_lit_comp("8"),
|
||||
str8_lit_comp("9"),
|
||||
str8_lit_comp("minus"),
|
||||
str8_lit_comp("equal"),
|
||||
str8_lit_comp("backspace"),
|
||||
str8_lit_comp("tab"),
|
||||
str8_lit_comp("q"),
|
||||
str8_lit_comp("w"),
|
||||
str8_lit_comp("e"),
|
||||
str8_lit_comp("r"),
|
||||
str8_lit_comp("t"),
|
||||
str8_lit_comp("y"),
|
||||
str8_lit_comp("u"),
|
||||
str8_lit_comp("i"),
|
||||
str8_lit_comp("o"),
|
||||
str8_lit_comp("p"),
|
||||
str8_lit_comp("left_bracket"),
|
||||
str8_lit_comp("right_bracket"),
|
||||
str8_lit_comp("backslash"),
|
||||
str8_lit_comp("caps_lock"),
|
||||
str8_lit_comp("a"),
|
||||
str8_lit_comp("s"),
|
||||
str8_lit_comp("d"),
|
||||
str8_lit_comp("f"),
|
||||
str8_lit_comp("g"),
|
||||
str8_lit_comp("h"),
|
||||
str8_lit_comp("j"),
|
||||
str8_lit_comp("k"),
|
||||
str8_lit_comp("l"),
|
||||
str8_lit_comp("semicolon"),
|
||||
str8_lit_comp("quote"),
|
||||
str8_lit_comp("return"),
|
||||
str8_lit_comp("shift"),
|
||||
str8_lit_comp("z"),
|
||||
str8_lit_comp("x"),
|
||||
str8_lit_comp("c"),
|
||||
str8_lit_comp("v"),
|
||||
str8_lit_comp("b"),
|
||||
str8_lit_comp("n"),
|
||||
str8_lit_comp("m"),
|
||||
str8_lit_comp("comma"),
|
||||
str8_lit_comp("period"),
|
||||
str8_lit_comp("slash"),
|
||||
str8_lit_comp("ctrl"),
|
||||
str8_lit_comp("alt"),
|
||||
str8_lit_comp("space"),
|
||||
str8_lit_comp("menu"),
|
||||
str8_lit_comp("scroll_lock"),
|
||||
str8_lit_comp("pause"),
|
||||
str8_lit_comp("insert"),
|
||||
str8_lit_comp("home"),
|
||||
str8_lit_comp("page_up"),
|
||||
str8_lit_comp("delete"),
|
||||
str8_lit_comp("end"),
|
||||
str8_lit_comp("page_down"),
|
||||
str8_lit_comp("up"),
|
||||
str8_lit_comp("left"),
|
||||
str8_lit_comp("down"),
|
||||
str8_lit_comp("right"),
|
||||
str8_lit_comp("ex0"),
|
||||
str8_lit_comp("ex1"),
|
||||
str8_lit_comp("ex2"),
|
||||
str8_lit_comp("ex3"),
|
||||
str8_lit_comp("ex4"),
|
||||
str8_lit_comp("ex5"),
|
||||
str8_lit_comp("ex6"),
|
||||
str8_lit_comp("ex7"),
|
||||
str8_lit_comp("ex8"),
|
||||
str8_lit_comp("ex9"),
|
||||
str8_lit_comp("ex10"),
|
||||
str8_lit_comp("ex11"),
|
||||
str8_lit_comp("ex12"),
|
||||
str8_lit_comp("ex13"),
|
||||
str8_lit_comp("ex14"),
|
||||
str8_lit_comp("ex15"),
|
||||
str8_lit_comp("ex16"),
|
||||
str8_lit_comp("ex17"),
|
||||
str8_lit_comp("ex18"),
|
||||
str8_lit_comp("ex19"),
|
||||
str8_lit_comp("ex20"),
|
||||
str8_lit_comp("ex21"),
|
||||
str8_lit_comp("ex22"),
|
||||
str8_lit_comp("ex23"),
|
||||
str8_lit_comp("ex24"),
|
||||
str8_lit_comp("ex25"),
|
||||
str8_lit_comp("ex26"),
|
||||
str8_lit_comp("ex27"),
|
||||
str8_lit_comp("ex28"),
|
||||
str8_lit_comp("ex29"),
|
||||
str8_lit_comp("num_lock"),
|
||||
str8_lit_comp("numpad_slash"),
|
||||
str8_lit_comp("numpad_star"),
|
||||
str8_lit_comp("numpad_minus"),
|
||||
str8_lit_comp("numpad_plus"),
|
||||
str8_lit_comp("numpad_period"),
|
||||
str8_lit_comp("numpad_0"),
|
||||
str8_lit_comp("numpad_1"),
|
||||
str8_lit_comp("numpad_2"),
|
||||
str8_lit_comp("numpad_3"),
|
||||
str8_lit_comp("numpad_4"),
|
||||
str8_lit_comp("numpad_5"),
|
||||
str8_lit_comp("numpad_6"),
|
||||
str8_lit_comp("numpad_7"),
|
||||
str8_lit_comp("numpad_8"),
|
||||
str8_lit_comp("numpad_9"),
|
||||
str8_lit_comp("left_mouse"),
|
||||
str8_lit_comp("middle_mouse"),
|
||||
str8_lit_comp("right_mouse"),
|
||||
};
|
||||
|
||||
C_LINKAGE_END
|
||||
|
||||
+163
-163
@@ -1,163 +1,163 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
//- GENERATED CODE
|
||||
|
||||
#ifndef OS_GFX_META_H
|
||||
#define OS_GFX_META_H
|
||||
|
||||
typedef enum OS_Key
|
||||
{
|
||||
OS_Key_Null,
|
||||
OS_Key_Esc,
|
||||
OS_Key_F1,
|
||||
OS_Key_F2,
|
||||
OS_Key_F3,
|
||||
OS_Key_F4,
|
||||
OS_Key_F5,
|
||||
OS_Key_F6,
|
||||
OS_Key_F7,
|
||||
OS_Key_F8,
|
||||
OS_Key_F9,
|
||||
OS_Key_F10,
|
||||
OS_Key_F11,
|
||||
OS_Key_F12,
|
||||
OS_Key_F13,
|
||||
OS_Key_F14,
|
||||
OS_Key_F15,
|
||||
OS_Key_F16,
|
||||
OS_Key_F17,
|
||||
OS_Key_F18,
|
||||
OS_Key_F19,
|
||||
OS_Key_F20,
|
||||
OS_Key_F21,
|
||||
OS_Key_F22,
|
||||
OS_Key_F23,
|
||||
OS_Key_F24,
|
||||
OS_Key_Tick,
|
||||
OS_Key_0,
|
||||
OS_Key_1,
|
||||
OS_Key_2,
|
||||
OS_Key_3,
|
||||
OS_Key_4,
|
||||
OS_Key_5,
|
||||
OS_Key_6,
|
||||
OS_Key_7,
|
||||
OS_Key_8,
|
||||
OS_Key_9,
|
||||
OS_Key_Minus,
|
||||
OS_Key_Equal,
|
||||
OS_Key_Backspace,
|
||||
OS_Key_Tab,
|
||||
OS_Key_Q,
|
||||
OS_Key_W,
|
||||
OS_Key_E,
|
||||
OS_Key_R,
|
||||
OS_Key_T,
|
||||
OS_Key_Y,
|
||||
OS_Key_U,
|
||||
OS_Key_I,
|
||||
OS_Key_O,
|
||||
OS_Key_P,
|
||||
OS_Key_LeftBracket,
|
||||
OS_Key_RightBracket,
|
||||
OS_Key_BackSlash,
|
||||
OS_Key_CapsLock,
|
||||
OS_Key_A,
|
||||
OS_Key_S,
|
||||
OS_Key_D,
|
||||
OS_Key_F,
|
||||
OS_Key_G,
|
||||
OS_Key_H,
|
||||
OS_Key_J,
|
||||
OS_Key_K,
|
||||
OS_Key_L,
|
||||
OS_Key_Semicolon,
|
||||
OS_Key_Quote,
|
||||
OS_Key_Return,
|
||||
OS_Key_Shift,
|
||||
OS_Key_Z,
|
||||
OS_Key_X,
|
||||
OS_Key_C,
|
||||
OS_Key_V,
|
||||
OS_Key_B,
|
||||
OS_Key_N,
|
||||
OS_Key_M,
|
||||
OS_Key_Comma,
|
||||
OS_Key_Period,
|
||||
OS_Key_Slash,
|
||||
OS_Key_Ctrl,
|
||||
OS_Key_Alt,
|
||||
OS_Key_Space,
|
||||
OS_Key_Menu,
|
||||
OS_Key_ScrollLock,
|
||||
OS_Key_Pause,
|
||||
OS_Key_Insert,
|
||||
OS_Key_Home,
|
||||
OS_Key_PageUp,
|
||||
OS_Key_Delete,
|
||||
OS_Key_End,
|
||||
OS_Key_PageDown,
|
||||
OS_Key_Up,
|
||||
OS_Key_Left,
|
||||
OS_Key_Down,
|
||||
OS_Key_Right,
|
||||
OS_Key_Ex0,
|
||||
OS_Key_Ex1,
|
||||
OS_Key_Ex2,
|
||||
OS_Key_Ex3,
|
||||
OS_Key_Ex4,
|
||||
OS_Key_Ex5,
|
||||
OS_Key_Ex6,
|
||||
OS_Key_Ex7,
|
||||
OS_Key_Ex8,
|
||||
OS_Key_Ex9,
|
||||
OS_Key_Ex10,
|
||||
OS_Key_Ex11,
|
||||
OS_Key_Ex12,
|
||||
OS_Key_Ex13,
|
||||
OS_Key_Ex14,
|
||||
OS_Key_Ex15,
|
||||
OS_Key_Ex16,
|
||||
OS_Key_Ex17,
|
||||
OS_Key_Ex18,
|
||||
OS_Key_Ex19,
|
||||
OS_Key_Ex20,
|
||||
OS_Key_Ex21,
|
||||
OS_Key_Ex22,
|
||||
OS_Key_Ex23,
|
||||
OS_Key_Ex24,
|
||||
OS_Key_Ex25,
|
||||
OS_Key_Ex26,
|
||||
OS_Key_Ex27,
|
||||
OS_Key_Ex28,
|
||||
OS_Key_Ex29,
|
||||
OS_Key_NumLock,
|
||||
OS_Key_NumSlash,
|
||||
OS_Key_NumStar,
|
||||
OS_Key_NumMinus,
|
||||
OS_Key_NumPlus,
|
||||
OS_Key_NumPeriod,
|
||||
OS_Key_Num0,
|
||||
OS_Key_Num1,
|
||||
OS_Key_Num2,
|
||||
OS_Key_Num3,
|
||||
OS_Key_Num4,
|
||||
OS_Key_Num5,
|
||||
OS_Key_Num6,
|
||||
OS_Key_Num7,
|
||||
OS_Key_Num8,
|
||||
OS_Key_Num9,
|
||||
OS_Key_LeftMouseButton,
|
||||
OS_Key_MiddleMouseButton,
|
||||
OS_Key_RightMouseButton,
|
||||
OS_Key_COUNT,
|
||||
} OS_Key;
|
||||
|
||||
C_LINKAGE_BEGIN
|
||||
extern String8 os_g_key_display_string_table[143];
|
||||
extern String8 os_g_key_cfg_string_table[143];
|
||||
|
||||
C_LINKAGE_END
|
||||
|
||||
#endif // OS_GFX_META_H
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
//- GENERATED CODE
|
||||
|
||||
#ifndef WINDOW_MANAGER_META_H
|
||||
#define WINDOW_MANAGER_META_H
|
||||
|
||||
typedef enum OS_Key
|
||||
{
|
||||
OS_Key_Null,
|
||||
OS_Key_Esc,
|
||||
OS_Key_F1,
|
||||
OS_Key_F2,
|
||||
OS_Key_F3,
|
||||
OS_Key_F4,
|
||||
OS_Key_F5,
|
||||
OS_Key_F6,
|
||||
OS_Key_F7,
|
||||
OS_Key_F8,
|
||||
OS_Key_F9,
|
||||
OS_Key_F10,
|
||||
OS_Key_F11,
|
||||
OS_Key_F12,
|
||||
OS_Key_F13,
|
||||
OS_Key_F14,
|
||||
OS_Key_F15,
|
||||
OS_Key_F16,
|
||||
OS_Key_F17,
|
||||
OS_Key_F18,
|
||||
OS_Key_F19,
|
||||
OS_Key_F20,
|
||||
OS_Key_F21,
|
||||
OS_Key_F22,
|
||||
OS_Key_F23,
|
||||
OS_Key_F24,
|
||||
OS_Key_Tick,
|
||||
OS_Key_0,
|
||||
OS_Key_1,
|
||||
OS_Key_2,
|
||||
OS_Key_3,
|
||||
OS_Key_4,
|
||||
OS_Key_5,
|
||||
OS_Key_6,
|
||||
OS_Key_7,
|
||||
OS_Key_8,
|
||||
OS_Key_9,
|
||||
OS_Key_Minus,
|
||||
OS_Key_Equal,
|
||||
OS_Key_Backspace,
|
||||
OS_Key_Tab,
|
||||
OS_Key_Q,
|
||||
OS_Key_W,
|
||||
OS_Key_E,
|
||||
OS_Key_R,
|
||||
OS_Key_T,
|
||||
OS_Key_Y,
|
||||
OS_Key_U,
|
||||
OS_Key_I,
|
||||
OS_Key_O,
|
||||
OS_Key_P,
|
||||
OS_Key_LeftBracket,
|
||||
OS_Key_RightBracket,
|
||||
OS_Key_BackSlash,
|
||||
OS_Key_CapsLock,
|
||||
OS_Key_A,
|
||||
OS_Key_S,
|
||||
OS_Key_D,
|
||||
OS_Key_F,
|
||||
OS_Key_G,
|
||||
OS_Key_H,
|
||||
OS_Key_J,
|
||||
OS_Key_K,
|
||||
OS_Key_L,
|
||||
OS_Key_Semicolon,
|
||||
OS_Key_Quote,
|
||||
OS_Key_Return,
|
||||
OS_Key_Shift,
|
||||
OS_Key_Z,
|
||||
OS_Key_X,
|
||||
OS_Key_C,
|
||||
OS_Key_V,
|
||||
OS_Key_B,
|
||||
OS_Key_N,
|
||||
OS_Key_M,
|
||||
OS_Key_Comma,
|
||||
OS_Key_Period,
|
||||
OS_Key_Slash,
|
||||
OS_Key_Ctrl,
|
||||
OS_Key_Alt,
|
||||
OS_Key_Space,
|
||||
OS_Key_Menu,
|
||||
OS_Key_ScrollLock,
|
||||
OS_Key_Pause,
|
||||
OS_Key_Insert,
|
||||
OS_Key_Home,
|
||||
OS_Key_PageUp,
|
||||
OS_Key_Delete,
|
||||
OS_Key_End,
|
||||
OS_Key_PageDown,
|
||||
OS_Key_Up,
|
||||
OS_Key_Left,
|
||||
OS_Key_Down,
|
||||
OS_Key_Right,
|
||||
OS_Key_Ex0,
|
||||
OS_Key_Ex1,
|
||||
OS_Key_Ex2,
|
||||
OS_Key_Ex3,
|
||||
OS_Key_Ex4,
|
||||
OS_Key_Ex5,
|
||||
OS_Key_Ex6,
|
||||
OS_Key_Ex7,
|
||||
OS_Key_Ex8,
|
||||
OS_Key_Ex9,
|
||||
OS_Key_Ex10,
|
||||
OS_Key_Ex11,
|
||||
OS_Key_Ex12,
|
||||
OS_Key_Ex13,
|
||||
OS_Key_Ex14,
|
||||
OS_Key_Ex15,
|
||||
OS_Key_Ex16,
|
||||
OS_Key_Ex17,
|
||||
OS_Key_Ex18,
|
||||
OS_Key_Ex19,
|
||||
OS_Key_Ex20,
|
||||
OS_Key_Ex21,
|
||||
OS_Key_Ex22,
|
||||
OS_Key_Ex23,
|
||||
OS_Key_Ex24,
|
||||
OS_Key_Ex25,
|
||||
OS_Key_Ex26,
|
||||
OS_Key_Ex27,
|
||||
OS_Key_Ex28,
|
||||
OS_Key_Ex29,
|
||||
OS_Key_NumLock,
|
||||
OS_Key_NumSlash,
|
||||
OS_Key_NumStar,
|
||||
OS_Key_NumMinus,
|
||||
OS_Key_NumPlus,
|
||||
OS_Key_NumPeriod,
|
||||
OS_Key_Num0,
|
||||
OS_Key_Num1,
|
||||
OS_Key_Num2,
|
||||
OS_Key_Num3,
|
||||
OS_Key_Num4,
|
||||
OS_Key_Num5,
|
||||
OS_Key_Num6,
|
||||
OS_Key_Num7,
|
||||
OS_Key_Num8,
|
||||
OS_Key_Num9,
|
||||
OS_Key_LeftMouseButton,
|
||||
OS_Key_MiddleMouseButton,
|
||||
OS_Key_RightMouseButton,
|
||||
OS_Key_COUNT,
|
||||
} OS_Key;
|
||||
|
||||
C_LINKAGE_BEGIN
|
||||
extern String8 os_g_key_display_string_table[143];
|
||||
extern String8 os_g_key_cfg_string_table[143];
|
||||
|
||||
C_LINKAGE_END
|
||||
|
||||
#endif // WINDOW_MANAGER_META_H
|
||||
@@ -1,300 +1,300 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Generated Code
|
||||
|
||||
#include "generated/os_gfx.meta.c"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type Helpers
|
||||
|
||||
internal OS_Window
|
||||
os_window_zero(void)
|
||||
{
|
||||
OS_Window result = {0};
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_match(OS_Window a, OS_Window b)
|
||||
{
|
||||
B32 result = MemoryMatchStruct(&a, &b);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_monitor_match(OS_Monitor a, OS_Monitor b)
|
||||
{
|
||||
B32 result = MemoryMatchStruct(&a, &b);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Event Functions (Helpers, Implemented Once)
|
||||
|
||||
internal String8
|
||||
os_string_from_event_kind(OS_EventKind kind)
|
||||
{
|
||||
String8 result = {0};
|
||||
switch(kind)
|
||||
{
|
||||
case OS_EventKind_Null:
|
||||
case OS_EventKind_COUNT:
|
||||
{}break;
|
||||
case OS_EventKind_Press: {result = str8_lit("Press");}break;
|
||||
case OS_EventKind_Release: {result = str8_lit("Release");}break;
|
||||
case OS_EventKind_MouseMove: {result = str8_lit("MouseMove");}break;
|
||||
case OS_EventKind_Text: {result = str8_lit("Text");}break;
|
||||
case OS_EventKind_Scroll: {result = str8_lit("Scroll");}break;
|
||||
case OS_EventKind_WindowLoseFocus: {result = str8_lit("WindowLoseFocus");}break;
|
||||
case OS_EventKind_WindowClose: {result = str8_lit("WindowClose");}break;
|
||||
case OS_EventKind_FileDrop: {result = str8_lit("FileDrop");}break;
|
||||
case OS_EventKind_Wakeup: {result = str8_lit("Wakeup");}break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8List
|
||||
os_string_list_from_modifiers(Arena *arena, OS_Modifiers modifiers)
|
||||
{
|
||||
String8List result = {0};
|
||||
if(modifiers & OS_Modifier_Ctrl) { str8_list_push(arena, &result, str8_lit("Ctrl")); }
|
||||
if(modifiers & OS_Modifier_Shift) { str8_list_push(arena, &result, str8_lit("Shift")); }
|
||||
if(modifiers & OS_Modifier_Alt) { str8_list_push(arena, &result, str8_lit("Alt")); }
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_string_from_modifiers_key(Arena *arena, OS_Modifiers modifiers, OS_Key key)
|
||||
{
|
||||
String8 result = {0};
|
||||
if(key != OS_Key_Null)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8List mods = os_string_list_from_modifiers(scratch.arena, modifiers);
|
||||
String8 key_string = os_g_key_display_string_table[key];
|
||||
str8_list_push(scratch.arena, &mods, key_string);
|
||||
StringJoin join = {0};
|
||||
join.sep = str8_lit(" + ");
|
||||
result = str8_list_join(arena, &mods, &join);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U32
|
||||
os_codepoint_from_modifiers_and_key(OS_Modifiers modifiers, OS_Key key)
|
||||
{
|
||||
U32 result = 0;
|
||||
|
||||
// rjf: special-case map
|
||||
local_persist read_only struct {U32 character; OS_Key key; OS_Modifiers modifiers;} map[] =
|
||||
{
|
||||
{'!', OS_Key_1, OS_Modifier_Shift},
|
||||
{'@', OS_Key_2, OS_Modifier_Shift},
|
||||
{'#', OS_Key_3, OS_Modifier_Shift},
|
||||
{'$', OS_Key_4, OS_Modifier_Shift},
|
||||
{'%', OS_Key_5, OS_Modifier_Shift},
|
||||
{'^', OS_Key_6, OS_Modifier_Shift},
|
||||
{'&', OS_Key_7, OS_Modifier_Shift},
|
||||
{'*', OS_Key_8, OS_Modifier_Shift},
|
||||
{'(', OS_Key_9, OS_Modifier_Shift},
|
||||
{')', OS_Key_0, OS_Modifier_Shift},
|
||||
{'_', OS_Key_Minus, OS_Modifier_Shift},
|
||||
{'_', OS_Key_Minus, OS_Modifier_Shift},
|
||||
{'-', OS_Key_Minus, 0},
|
||||
{'=', OS_Key_Equal, 0},
|
||||
{'+', OS_Key_Equal, OS_Modifier_Shift},
|
||||
{'`', OS_Key_Tick, 0},
|
||||
{'~', OS_Key_Tick, OS_Modifier_Shift},
|
||||
{'[', OS_Key_LeftBracket, 0},
|
||||
{']', OS_Key_RightBracket, 0},
|
||||
{'{', OS_Key_LeftBracket, OS_Modifier_Shift},
|
||||
{'}', OS_Key_RightBracket, OS_Modifier_Shift},
|
||||
{'\\', OS_Key_BackSlash, 0},
|
||||
{'|', OS_Key_BackSlash, OS_Modifier_Shift},
|
||||
{';', OS_Key_Semicolon, 0},
|
||||
{':', OS_Key_Semicolon, OS_Modifier_Shift},
|
||||
{'\'', OS_Key_Quote, 0},
|
||||
{'"', OS_Key_Quote, OS_Modifier_Shift},
|
||||
{'.', OS_Key_Period, 0},
|
||||
{',', OS_Key_Comma, 0},
|
||||
{'<', OS_Key_Period, OS_Modifier_Shift},
|
||||
{'>', OS_Key_Comma, OS_Modifier_Shift},
|
||||
{'/', OS_Key_Slash, 0},
|
||||
{'?', OS_Key_Slash, OS_Modifier_Shift},
|
||||
{'a', OS_Key_A, 0},
|
||||
{'b', OS_Key_B, 0},
|
||||
{'c', OS_Key_C, 0},
|
||||
{'d', OS_Key_D, 0},
|
||||
{'e', OS_Key_E, 0},
|
||||
{'f', OS_Key_F, 0},
|
||||
{'g', OS_Key_G, 0},
|
||||
{'h', OS_Key_H, 0},
|
||||
{'i', OS_Key_I, 0},
|
||||
{'j', OS_Key_J, 0},
|
||||
{'k', OS_Key_K, 0},
|
||||
{'l', OS_Key_L, 0},
|
||||
{'m', OS_Key_M, 0},
|
||||
{'n', OS_Key_N, 0},
|
||||
{'o', OS_Key_O, 0},
|
||||
{'p', OS_Key_P, 0},
|
||||
{'q', OS_Key_Q, 0},
|
||||
{'r', OS_Key_R, 0},
|
||||
{'s', OS_Key_S, 0},
|
||||
{'t', OS_Key_T, 0},
|
||||
{'u', OS_Key_U, 0},
|
||||
{'v', OS_Key_V, 0},
|
||||
{'w', OS_Key_W, 0},
|
||||
{'x', OS_Key_X, 0},
|
||||
{'y', OS_Key_Y, 0},
|
||||
{'z', OS_Key_Z, 0},
|
||||
{'A', OS_Key_A, OS_Modifier_Shift},
|
||||
{'B', OS_Key_B, OS_Modifier_Shift},
|
||||
{'C', OS_Key_C, OS_Modifier_Shift},
|
||||
{'D', OS_Key_D, OS_Modifier_Shift},
|
||||
{'E', OS_Key_E, OS_Modifier_Shift},
|
||||
{'F', OS_Key_F, OS_Modifier_Shift},
|
||||
{'G', OS_Key_G, OS_Modifier_Shift},
|
||||
{'H', OS_Key_H, OS_Modifier_Shift},
|
||||
{'I', OS_Key_I, OS_Modifier_Shift},
|
||||
{'J', OS_Key_J, OS_Modifier_Shift},
|
||||
{'K', OS_Key_K, OS_Modifier_Shift},
|
||||
{'L', OS_Key_L, OS_Modifier_Shift},
|
||||
{'M', OS_Key_M, OS_Modifier_Shift},
|
||||
{'N', OS_Key_N, OS_Modifier_Shift},
|
||||
{'O', OS_Key_O, OS_Modifier_Shift},
|
||||
{'P', OS_Key_P, OS_Modifier_Shift},
|
||||
{'Q', OS_Key_Q, OS_Modifier_Shift},
|
||||
{'R', OS_Key_R, OS_Modifier_Shift},
|
||||
{'S', OS_Key_S, OS_Modifier_Shift},
|
||||
{'T', OS_Key_T, OS_Modifier_Shift},
|
||||
{'U', OS_Key_U, OS_Modifier_Shift},
|
||||
{'V', OS_Key_V, OS_Modifier_Shift},
|
||||
{'W', OS_Key_W, OS_Modifier_Shift},
|
||||
{'X', OS_Key_X, OS_Modifier_Shift},
|
||||
{'Y', OS_Key_Y, OS_Modifier_Shift},
|
||||
{'Z', OS_Key_Z, OS_Modifier_Shift},
|
||||
{' ', OS_Key_Space, 0},
|
||||
};
|
||||
|
||||
// rjf: check numeric
|
||||
if(OS_Key_0 <= key && key <= OS_Key_9)
|
||||
{
|
||||
result = '0' + (key - OS_Key_0);
|
||||
}
|
||||
|
||||
// rjf: check special-case map
|
||||
for(U64 idx = 0; idx < ArrayCount(map); idx += 1)
|
||||
{
|
||||
if(map[idx].key == key && map[idx].modifiers == modifiers)
|
||||
{
|
||||
result = map[idx].character;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_eat_event(OS_EventList *events, OS_Event *event)
|
||||
{
|
||||
DLLRemove(events->first, events->last, event);
|
||||
events->count -= 1;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_key_press(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key)
|
||||
{
|
||||
B32 result = 0;
|
||||
for(OS_Event *event = events->first; event != 0; event = event->next)
|
||||
{
|
||||
if((os_window_match(event->window, window) || os_window_match(window, os_window_zero())) &&
|
||||
event->kind == OS_EventKind_Press && event->key == key && event->modifiers == modifiers)
|
||||
{
|
||||
result = 1;
|
||||
os_eat_event(events, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_key_release(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key)
|
||||
{
|
||||
B32 result = 0;
|
||||
for(OS_Event *event = events->first; event != 0; event = event->next)
|
||||
{
|
||||
if((os_window_match(event->window, window) || os_window_match(window, os_window_zero())) &&
|
||||
event->kind == OS_EventKind_Release && event->key == key && event->modifiers == modifiers)
|
||||
{
|
||||
result = 1;
|
||||
os_eat_event(events, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_text(OS_EventList *events, OS_Window window, U32 character)
|
||||
{
|
||||
B32 result = 0;
|
||||
for(OS_Event *event = events->first; event != 0; event = event->next)
|
||||
{
|
||||
if((os_window_match(event->window, window) || os_window_match(window, os_window_zero())) &&
|
||||
event->kind == OS_EventKind_Text && event->character == character)
|
||||
{
|
||||
result = 1;
|
||||
os_eat_event(events, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal OS_EventList
|
||||
os_event_list_copy(Arena *arena, OS_EventList *src)
|
||||
{
|
||||
OS_EventList dst = {0};
|
||||
for(OS_Event *s = src->first; s != 0; s = s->next)
|
||||
{
|
||||
OS_Event *d = push_array(arena, OS_Event, 1);
|
||||
MemoryCopyStruct(d, s);
|
||||
d->strings = str8_list_copy(arena, &s->strings);
|
||||
DLLPushBack(dst.first, dst.last, d);
|
||||
dst.count += 1;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_event_list_concat_in_place(OS_EventList *dst, OS_EventList *to_push)
|
||||
{
|
||||
if(dst->last && to_push->first)
|
||||
{
|
||||
dst->last->next = to_push->first;
|
||||
to_push->first->prev = dst->last;
|
||||
dst->last = to_push->last;
|
||||
dst->count += to_push->count;
|
||||
}
|
||||
else if(!dst->last && to_push->first)
|
||||
{
|
||||
MemoryCopyStruct(dst, to_push);
|
||||
}
|
||||
MemoryZeroStruct(to_push);
|
||||
}
|
||||
|
||||
internal OS_Event *
|
||||
os_event_list_push_new(Arena *arena, OS_EventList *evts, OS_EventKind kind)
|
||||
{
|
||||
OS_Event *evt = push_array(arena, OS_Event, 1);
|
||||
DLLPushBack(evts->first, evts->last, evt);
|
||||
evts->count += 1;
|
||||
evt->timestamp_us = now_time_us();
|
||||
evt->kind = kind;
|
||||
return evt;
|
||||
}
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Generated Code
|
||||
|
||||
#include "window_manager/generated/window_manager.meta.c"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type Helpers
|
||||
|
||||
internal OS_Window
|
||||
os_window_zero(void)
|
||||
{
|
||||
OS_Window result = {0};
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_match(OS_Window a, OS_Window b)
|
||||
{
|
||||
B32 result = MemoryMatchStruct(&a, &b);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_monitor_match(OS_Monitor a, OS_Monitor b)
|
||||
{
|
||||
B32 result = MemoryMatchStruct(&a, &b);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Event Functions (Helpers, Implemented Once)
|
||||
|
||||
internal String8
|
||||
os_string_from_event_kind(OS_EventKind kind)
|
||||
{
|
||||
String8 result = {0};
|
||||
switch(kind)
|
||||
{
|
||||
case OS_EventKind_Null:
|
||||
case OS_EventKind_COUNT:
|
||||
{}break;
|
||||
case OS_EventKind_Press: {result = str8_lit("Press");}break;
|
||||
case OS_EventKind_Release: {result = str8_lit("Release");}break;
|
||||
case OS_EventKind_MouseMove: {result = str8_lit("MouseMove");}break;
|
||||
case OS_EventKind_Text: {result = str8_lit("Text");}break;
|
||||
case OS_EventKind_Scroll: {result = str8_lit("Scroll");}break;
|
||||
case OS_EventKind_WindowLoseFocus: {result = str8_lit("WindowLoseFocus");}break;
|
||||
case OS_EventKind_WindowClose: {result = str8_lit("WindowClose");}break;
|
||||
case OS_EventKind_FileDrop: {result = str8_lit("FileDrop");}break;
|
||||
case OS_EventKind_Wakeup: {result = str8_lit("Wakeup");}break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8List
|
||||
os_string_list_from_modifiers(Arena *arena, OS_Modifiers modifiers)
|
||||
{
|
||||
String8List result = {0};
|
||||
if(modifiers & OS_Modifier_Ctrl) { str8_list_push(arena, &result, str8_lit("Ctrl")); }
|
||||
if(modifiers & OS_Modifier_Shift) { str8_list_push(arena, &result, str8_lit("Shift")); }
|
||||
if(modifiers & OS_Modifier_Alt) { str8_list_push(arena, &result, str8_lit("Alt")); }
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_string_from_modifiers_key(Arena *arena, OS_Modifiers modifiers, OS_Key key)
|
||||
{
|
||||
String8 result = {0};
|
||||
if(key != OS_Key_Null)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8List mods = os_string_list_from_modifiers(scratch.arena, modifiers);
|
||||
String8 key_string = os_g_key_display_string_table[key];
|
||||
str8_list_push(scratch.arena, &mods, key_string);
|
||||
StringJoin join = {0};
|
||||
join.sep = str8_lit(" + ");
|
||||
result = str8_list_join(arena, &mods, &join);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U32
|
||||
os_codepoint_from_modifiers_and_key(OS_Modifiers modifiers, OS_Key key)
|
||||
{
|
||||
U32 result = 0;
|
||||
|
||||
// rjf: special-case map
|
||||
local_persist read_only struct {U32 character; OS_Key key; OS_Modifiers modifiers;} map[] =
|
||||
{
|
||||
{'!', OS_Key_1, OS_Modifier_Shift},
|
||||
{'@', OS_Key_2, OS_Modifier_Shift},
|
||||
{'#', OS_Key_3, OS_Modifier_Shift},
|
||||
{'$', OS_Key_4, OS_Modifier_Shift},
|
||||
{'%', OS_Key_5, OS_Modifier_Shift},
|
||||
{'^', OS_Key_6, OS_Modifier_Shift},
|
||||
{'&', OS_Key_7, OS_Modifier_Shift},
|
||||
{'*', OS_Key_8, OS_Modifier_Shift},
|
||||
{'(', OS_Key_9, OS_Modifier_Shift},
|
||||
{')', OS_Key_0, OS_Modifier_Shift},
|
||||
{'_', OS_Key_Minus, OS_Modifier_Shift},
|
||||
{'_', OS_Key_Minus, OS_Modifier_Shift},
|
||||
{'-', OS_Key_Minus, 0},
|
||||
{'=', OS_Key_Equal, 0},
|
||||
{'+', OS_Key_Equal, OS_Modifier_Shift},
|
||||
{'`', OS_Key_Tick, 0},
|
||||
{'~', OS_Key_Tick, OS_Modifier_Shift},
|
||||
{'[', OS_Key_LeftBracket, 0},
|
||||
{']', OS_Key_RightBracket, 0},
|
||||
{'{', OS_Key_LeftBracket, OS_Modifier_Shift},
|
||||
{'}', OS_Key_RightBracket, OS_Modifier_Shift},
|
||||
{'\\', OS_Key_BackSlash, 0},
|
||||
{'|', OS_Key_BackSlash, OS_Modifier_Shift},
|
||||
{';', OS_Key_Semicolon, 0},
|
||||
{':', OS_Key_Semicolon, OS_Modifier_Shift},
|
||||
{'\'', OS_Key_Quote, 0},
|
||||
{'"', OS_Key_Quote, OS_Modifier_Shift},
|
||||
{'.', OS_Key_Period, 0},
|
||||
{',', OS_Key_Comma, 0},
|
||||
{'<', OS_Key_Period, OS_Modifier_Shift},
|
||||
{'>', OS_Key_Comma, OS_Modifier_Shift},
|
||||
{'/', OS_Key_Slash, 0},
|
||||
{'?', OS_Key_Slash, OS_Modifier_Shift},
|
||||
{'a', OS_Key_A, 0},
|
||||
{'b', OS_Key_B, 0},
|
||||
{'c', OS_Key_C, 0},
|
||||
{'d', OS_Key_D, 0},
|
||||
{'e', OS_Key_E, 0},
|
||||
{'f', OS_Key_F, 0},
|
||||
{'g', OS_Key_G, 0},
|
||||
{'h', OS_Key_H, 0},
|
||||
{'i', OS_Key_I, 0},
|
||||
{'j', OS_Key_J, 0},
|
||||
{'k', OS_Key_K, 0},
|
||||
{'l', OS_Key_L, 0},
|
||||
{'m', OS_Key_M, 0},
|
||||
{'n', OS_Key_N, 0},
|
||||
{'o', OS_Key_O, 0},
|
||||
{'p', OS_Key_P, 0},
|
||||
{'q', OS_Key_Q, 0},
|
||||
{'r', OS_Key_R, 0},
|
||||
{'s', OS_Key_S, 0},
|
||||
{'t', OS_Key_T, 0},
|
||||
{'u', OS_Key_U, 0},
|
||||
{'v', OS_Key_V, 0},
|
||||
{'w', OS_Key_W, 0},
|
||||
{'x', OS_Key_X, 0},
|
||||
{'y', OS_Key_Y, 0},
|
||||
{'z', OS_Key_Z, 0},
|
||||
{'A', OS_Key_A, OS_Modifier_Shift},
|
||||
{'B', OS_Key_B, OS_Modifier_Shift},
|
||||
{'C', OS_Key_C, OS_Modifier_Shift},
|
||||
{'D', OS_Key_D, OS_Modifier_Shift},
|
||||
{'E', OS_Key_E, OS_Modifier_Shift},
|
||||
{'F', OS_Key_F, OS_Modifier_Shift},
|
||||
{'G', OS_Key_G, OS_Modifier_Shift},
|
||||
{'H', OS_Key_H, OS_Modifier_Shift},
|
||||
{'I', OS_Key_I, OS_Modifier_Shift},
|
||||
{'J', OS_Key_J, OS_Modifier_Shift},
|
||||
{'K', OS_Key_K, OS_Modifier_Shift},
|
||||
{'L', OS_Key_L, OS_Modifier_Shift},
|
||||
{'M', OS_Key_M, OS_Modifier_Shift},
|
||||
{'N', OS_Key_N, OS_Modifier_Shift},
|
||||
{'O', OS_Key_O, OS_Modifier_Shift},
|
||||
{'P', OS_Key_P, OS_Modifier_Shift},
|
||||
{'Q', OS_Key_Q, OS_Modifier_Shift},
|
||||
{'R', OS_Key_R, OS_Modifier_Shift},
|
||||
{'S', OS_Key_S, OS_Modifier_Shift},
|
||||
{'T', OS_Key_T, OS_Modifier_Shift},
|
||||
{'U', OS_Key_U, OS_Modifier_Shift},
|
||||
{'V', OS_Key_V, OS_Modifier_Shift},
|
||||
{'W', OS_Key_W, OS_Modifier_Shift},
|
||||
{'X', OS_Key_X, OS_Modifier_Shift},
|
||||
{'Y', OS_Key_Y, OS_Modifier_Shift},
|
||||
{'Z', OS_Key_Z, OS_Modifier_Shift},
|
||||
{' ', OS_Key_Space, 0},
|
||||
};
|
||||
|
||||
// rjf: check numeric
|
||||
if(OS_Key_0 <= key && key <= OS_Key_9)
|
||||
{
|
||||
result = '0' + (key - OS_Key_0);
|
||||
}
|
||||
|
||||
// rjf: check special-case map
|
||||
for(U64 idx = 0; idx < ArrayCount(map); idx += 1)
|
||||
{
|
||||
if(map[idx].key == key && map[idx].modifiers == modifiers)
|
||||
{
|
||||
result = map[idx].character;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_eat_event(OS_EventList *events, OS_Event *event)
|
||||
{
|
||||
DLLRemove(events->first, events->last, event);
|
||||
events->count -= 1;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_key_press(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key)
|
||||
{
|
||||
B32 result = 0;
|
||||
for(OS_Event *event = events->first; event != 0; event = event->next)
|
||||
{
|
||||
if((os_window_match(event->window, window) || os_window_match(window, os_window_zero())) &&
|
||||
event->kind == OS_EventKind_Press && event->key == key && event->modifiers == modifiers)
|
||||
{
|
||||
result = 1;
|
||||
os_eat_event(events, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_key_release(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key)
|
||||
{
|
||||
B32 result = 0;
|
||||
for(OS_Event *event = events->first; event != 0; event = event->next)
|
||||
{
|
||||
if((os_window_match(event->window, window) || os_window_match(window, os_window_zero())) &&
|
||||
event->kind == OS_EventKind_Release && event->key == key && event->modifiers == modifiers)
|
||||
{
|
||||
result = 1;
|
||||
os_eat_event(events, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_text(OS_EventList *events, OS_Window window, U32 character)
|
||||
{
|
||||
B32 result = 0;
|
||||
for(OS_Event *event = events->first; event != 0; event = event->next)
|
||||
{
|
||||
if((os_window_match(event->window, window) || os_window_match(window, os_window_zero())) &&
|
||||
event->kind == OS_EventKind_Text && event->character == character)
|
||||
{
|
||||
result = 1;
|
||||
os_eat_event(events, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal OS_EventList
|
||||
os_event_list_copy(Arena *arena, OS_EventList *src)
|
||||
{
|
||||
OS_EventList dst = {0};
|
||||
for(OS_Event *s = src->first; s != 0; s = s->next)
|
||||
{
|
||||
OS_Event *d = push_array(arena, OS_Event, 1);
|
||||
MemoryCopyStruct(d, s);
|
||||
d->strings = str8_list_copy(arena, &s->strings);
|
||||
DLLPushBack(dst.first, dst.last, d);
|
||||
dst.count += 1;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_event_list_concat_in_place(OS_EventList *dst, OS_EventList *to_push)
|
||||
{
|
||||
if(dst->last && to_push->first)
|
||||
{
|
||||
dst->last->next = to_push->first;
|
||||
to_push->first->prev = dst->last;
|
||||
dst->last = to_push->last;
|
||||
dst->count += to_push->count;
|
||||
}
|
||||
else if(!dst->last && to_push->first)
|
||||
{
|
||||
MemoryCopyStruct(dst, to_push);
|
||||
}
|
||||
MemoryZeroStruct(to_push);
|
||||
}
|
||||
|
||||
internal OS_Event *
|
||||
os_event_list_push_new(Arena *arena, OS_EventList *evts, OS_EventKind kind)
|
||||
{
|
||||
OS_Event *evt = push_array(arena, OS_Event, 1);
|
||||
DLLPushBack(evts->first, evts->last, evt);
|
||||
evts->count += 1;
|
||||
evt->timestamp_us = now_time_us();
|
||||
evt->kind = kind;
|
||||
return evt;
|
||||
}
|
||||
@@ -1,246 +1,246 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_GFX_H
|
||||
#define OS_GFX_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Graphics System Info
|
||||
|
||||
typedef struct OS_GfxInfo OS_GfxInfo;
|
||||
struct OS_GfxInfo
|
||||
{
|
||||
F32 double_click_time;
|
||||
F32 caret_blink_time;
|
||||
F32 default_refresh_rate;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Window Types
|
||||
|
||||
typedef U32 OS_WindowFlags;
|
||||
enum
|
||||
{
|
||||
OS_WindowFlag_CustomBorder = (1<<0),
|
||||
OS_WindowFlag_UseDefaultPosition = (1<<1),
|
||||
};
|
||||
|
||||
typedef struct OS_Window OS_Window;
|
||||
struct OS_Window
|
||||
{
|
||||
U64 u64[1];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: External Window Types
|
||||
|
||||
typedef struct OS_ExternalWindow OS_ExternalWindow;
|
||||
struct OS_ExternalWindow
|
||||
{
|
||||
U64 u64[1];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Monitor Types
|
||||
|
||||
typedef struct OS_Monitor OS_Monitor;
|
||||
struct OS_Monitor
|
||||
{
|
||||
U64 u64[1];
|
||||
};
|
||||
|
||||
typedef struct OS_MonitorArray OS_MonitorArray;
|
||||
struct OS_MonitorArray
|
||||
{
|
||||
OS_Monitor *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: 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;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Generated Code
|
||||
|
||||
#include "os/gfx/generated/os_gfx.meta.h"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Event Types
|
||||
|
||||
typedef enum OS_EventKind
|
||||
{
|
||||
OS_EventKind_Null,
|
||||
OS_EventKind_Press,
|
||||
OS_EventKind_Release,
|
||||
OS_EventKind_MouseMove,
|
||||
OS_EventKind_Text,
|
||||
OS_EventKind_Scroll,
|
||||
OS_EventKind_WindowLoseFocus,
|
||||
OS_EventKind_WindowClose,
|
||||
OS_EventKind_FileDrop,
|
||||
OS_EventKind_Wakeup,
|
||||
OS_EventKind_COUNT
|
||||
}
|
||||
OS_EventKind;
|
||||
|
||||
typedef U32 OS_Modifiers;
|
||||
enum
|
||||
{
|
||||
OS_Modifier_Ctrl = (1<<0),
|
||||
OS_Modifier_Shift = (1<<1),
|
||||
OS_Modifier_Alt = (1<<2),
|
||||
};
|
||||
|
||||
typedef struct OS_Event OS_Event;
|
||||
struct OS_Event
|
||||
{
|
||||
OS_Event *next;
|
||||
OS_Event *prev;
|
||||
U64 timestamp_us;
|
||||
OS_Window window;
|
||||
OS_EventKind kind;
|
||||
OS_Modifiers modifiers;
|
||||
OS_Key key;
|
||||
B32 is_repeat;
|
||||
B32 right_sided;
|
||||
U32 character;
|
||||
U32 repeat_count;
|
||||
Vec2F32 pos;
|
||||
Vec2F32 delta;
|
||||
String8List strings;
|
||||
};
|
||||
|
||||
typedef struct OS_EventList OS_EventList;
|
||||
struct OS_EventList
|
||||
{
|
||||
U64 count;
|
||||
OS_Event *first;
|
||||
OS_Event *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Application-Defined Frame Hook Forward Declaration
|
||||
|
||||
internal B32 frame(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type Helpers
|
||||
|
||||
internal OS_Window os_window_zero(void);
|
||||
internal B32 os_window_match(OS_Window a, OS_Window b);
|
||||
internal B32 os_monitor_match(OS_Monitor a, OS_Monitor b);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Event Functions (Helpers, Implemented Once)
|
||||
|
||||
internal String8 os_string_from_event_kind(OS_EventKind kind);
|
||||
internal String8List os_string_list_from_modifiers(Arena *arena, OS_Modifiers flags);
|
||||
internal String8 os_string_from_modifiers_key(Arena *arena, OS_Modifiers modifiers, OS_Key key);
|
||||
internal U32 os_codepoint_from_modifiers_and_key(OS_Modifiers flags, OS_Key key);
|
||||
internal void os_eat_event(OS_EventList *events, OS_Event *event);
|
||||
internal B32 os_key_press(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key);
|
||||
internal B32 os_key_release(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key);
|
||||
internal B32 os_text(OS_EventList *events, OS_Window window, U32 character);
|
||||
internal OS_EventList os_event_list_copy(Arena *arena, OS_EventList *src);
|
||||
internal void os_event_list_concat_in_place(OS_EventList *dst, OS_EventList *to_push);
|
||||
internal OS_Event *os_event_list_push_new(Arena *arena, OS_EventList *evts, OS_EventKind kind);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Main Initialization API (Implemented Per-OS)
|
||||
|
||||
internal void os_gfx_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Graphics System Info (Implemented Per-OS)
|
||||
|
||||
internal OS_GfxInfo *os_get_gfx_info(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Clipboards (Implemented Per-OS)
|
||||
|
||||
internal void os_set_clipboard_text(String8 string);
|
||||
internal String8 os_get_clipboard_text(Arena *arena);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_Window os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title);
|
||||
internal void os_window_close(OS_Window window);
|
||||
internal void os_window_set_title(OS_Window window, String8 title);
|
||||
internal void os_window_first_paint(OS_Window window);
|
||||
internal void os_window_focus(OS_Window window);
|
||||
internal B32 os_window_is_focused(OS_Window window);
|
||||
internal B32 os_window_is_fullscreen(OS_Window window);
|
||||
internal void os_window_set_fullscreen(OS_Window window, B32 fullscreen);
|
||||
internal B32 os_window_is_maximized(OS_Window window);
|
||||
internal void os_window_set_maximized(OS_Window window, B32 maximized);
|
||||
internal B32 os_window_is_minimized(OS_Window window);
|
||||
internal void os_window_set_minimized(OS_Window window, B32 minimized);
|
||||
internal void os_window_bring_to_front(OS_Window window);
|
||||
internal void os_window_set_monitor(OS_Window window, OS_Monitor monitor);
|
||||
internal void os_window_clear_custom_border_data(OS_Window handle);
|
||||
internal void os_window_push_custom_title_bar(OS_Window handle, F32 thickness);
|
||||
internal void os_window_push_custom_edges(OS_Window handle, F32 thickness);
|
||||
internal void os_window_push_custom_title_bar_client_area(OS_Window handle, Rng2F32 rect);
|
||||
internal Rng2F32 os_rect_from_window(OS_Window window);
|
||||
internal Rng2F32 os_client_rect_from_window(OS_Window window);
|
||||
internal F32 os_dpi_from_window(OS_Window window);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks External Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_ExternalWindow os_focused_external_window(void);
|
||||
internal void os_focus_external_window(OS_ExternalWindow ext_window);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
||||
|
||||
internal OS_MonitorArray os_push_monitors_array(Arena *arena);
|
||||
internal OS_Monitor os_primary_monitor(void);
|
||||
internal OS_Monitor os_monitor_from_window(OS_Window window);
|
||||
internal String8 os_name_from_monitor(Arena *arena, OS_Monitor monitor);
|
||||
internal Vec2F32 os_dim_from_monitor(OS_Monitor monitor);
|
||||
internal F32 os_dpi_from_monitor(OS_Monitor monitor);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Events (Implemented Per-OS)
|
||||
|
||||
internal void os_send_wakeup_event(void);
|
||||
internal OS_EventList os_get_events(Arena *arena, B32 wait);
|
||||
internal OS_Modifiers os_get_modifiers(void);
|
||||
internal B32 os_key_is_down(OS_Key key);
|
||||
internal Vec2F32 os_mouse_from_window(OS_Window window);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Cursors (Implemented Per-OS)
|
||||
|
||||
internal void os_set_cursor(OS_Cursor cursor);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Native User-Facing Graphical Messages (Implemented Per-OS)
|
||||
|
||||
internal void os_graphical_message(B32 error, String8 title, String8 message);
|
||||
internal String8 os_graphical_pick_file(Arena *arena, String8 initial_path);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shell Operations
|
||||
|
||||
internal void os_show_in_filesystem_ui(String8 path);
|
||||
internal void os_open_in_browser(String8 url);
|
||||
|
||||
#endif // OS_GFX_H
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_GFX_H
|
||||
#define OS_GFX_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Graphics System Info
|
||||
|
||||
typedef struct OS_GfxInfo OS_GfxInfo;
|
||||
struct OS_GfxInfo
|
||||
{
|
||||
F32 double_click_time;
|
||||
F32 caret_blink_time;
|
||||
F32 default_refresh_rate;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Window Types
|
||||
|
||||
typedef U32 OS_WindowFlags;
|
||||
enum
|
||||
{
|
||||
OS_WindowFlag_CustomBorder = (1<<0),
|
||||
OS_WindowFlag_UseDefaultPosition = (1<<1),
|
||||
};
|
||||
|
||||
typedef struct OS_Window OS_Window;
|
||||
struct OS_Window
|
||||
{
|
||||
U64 u64[1];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: External Window Types
|
||||
|
||||
typedef struct OS_ExternalWindow OS_ExternalWindow;
|
||||
struct OS_ExternalWindow
|
||||
{
|
||||
U64 u64[1];
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Monitor Types
|
||||
|
||||
typedef struct OS_Monitor OS_Monitor;
|
||||
struct OS_Monitor
|
||||
{
|
||||
U64 u64[1];
|
||||
};
|
||||
|
||||
typedef struct OS_MonitorArray OS_MonitorArray;
|
||||
struct OS_MonitorArray
|
||||
{
|
||||
OS_Monitor *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: 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;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Generated Code
|
||||
|
||||
#include "window_manager/generated/window_manager.meta.h"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Event Types
|
||||
|
||||
typedef enum OS_EventKind
|
||||
{
|
||||
OS_EventKind_Null,
|
||||
OS_EventKind_Press,
|
||||
OS_EventKind_Release,
|
||||
OS_EventKind_MouseMove,
|
||||
OS_EventKind_Text,
|
||||
OS_EventKind_Scroll,
|
||||
OS_EventKind_WindowLoseFocus,
|
||||
OS_EventKind_WindowClose,
|
||||
OS_EventKind_FileDrop,
|
||||
OS_EventKind_Wakeup,
|
||||
OS_EventKind_COUNT
|
||||
}
|
||||
OS_EventKind;
|
||||
|
||||
typedef U32 OS_Modifiers;
|
||||
enum
|
||||
{
|
||||
OS_Modifier_Ctrl = (1<<0),
|
||||
OS_Modifier_Shift = (1<<1),
|
||||
OS_Modifier_Alt = (1<<2),
|
||||
};
|
||||
|
||||
typedef struct OS_Event OS_Event;
|
||||
struct OS_Event
|
||||
{
|
||||
OS_Event *next;
|
||||
OS_Event *prev;
|
||||
U64 timestamp_us;
|
||||
OS_Window window;
|
||||
OS_EventKind kind;
|
||||
OS_Modifiers modifiers;
|
||||
OS_Key key;
|
||||
B32 is_repeat;
|
||||
B32 right_sided;
|
||||
U32 character;
|
||||
U32 repeat_count;
|
||||
Vec2F32 pos;
|
||||
Vec2F32 delta;
|
||||
String8List strings;
|
||||
};
|
||||
|
||||
typedef struct OS_EventList OS_EventList;
|
||||
struct OS_EventList
|
||||
{
|
||||
U64 count;
|
||||
OS_Event *first;
|
||||
OS_Event *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Application-Defined Frame Hook Forward Declaration
|
||||
|
||||
internal B32 frame(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Handle Type Helpers
|
||||
|
||||
internal OS_Window os_window_zero(void);
|
||||
internal B32 os_window_match(OS_Window a, OS_Window b);
|
||||
internal B32 os_monitor_match(OS_Monitor a, OS_Monitor b);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Event Functions (Helpers, Implemented Once)
|
||||
|
||||
internal String8 os_string_from_event_kind(OS_EventKind kind);
|
||||
internal String8List os_string_list_from_modifiers(Arena *arena, OS_Modifiers flags);
|
||||
internal String8 os_string_from_modifiers_key(Arena *arena, OS_Modifiers modifiers, OS_Key key);
|
||||
internal U32 os_codepoint_from_modifiers_and_key(OS_Modifiers flags, OS_Key key);
|
||||
internal void os_eat_event(OS_EventList *events, OS_Event *event);
|
||||
internal B32 os_key_press(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key);
|
||||
internal B32 os_key_release(OS_EventList *events, OS_Window window, OS_Modifiers modifiers, OS_Key key);
|
||||
internal B32 os_text(OS_EventList *events, OS_Window window, U32 character);
|
||||
internal OS_EventList os_event_list_copy(Arena *arena, OS_EventList *src);
|
||||
internal void os_event_list_concat_in_place(OS_EventList *dst, OS_EventList *to_push);
|
||||
internal OS_Event *os_event_list_push_new(Arena *arena, OS_EventList *evts, OS_EventKind kind);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Main Initialization API (Implemented Per-OS)
|
||||
|
||||
internal void os_gfx_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Graphics System Info (Implemented Per-OS)
|
||||
|
||||
internal OS_GfxInfo *os_get_gfx_info(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Clipboards (Implemented Per-OS)
|
||||
|
||||
internal void os_set_clipboard_text(String8 string);
|
||||
internal String8 os_get_clipboard_text(Arena *arena);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_Window os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title);
|
||||
internal void os_window_close(OS_Window window);
|
||||
internal void os_window_set_title(OS_Window window, String8 title);
|
||||
internal void os_window_first_paint(OS_Window window);
|
||||
internal void os_window_focus(OS_Window window);
|
||||
internal B32 os_window_is_focused(OS_Window window);
|
||||
internal B32 os_window_is_fullscreen(OS_Window window);
|
||||
internal void os_window_set_fullscreen(OS_Window window, B32 fullscreen);
|
||||
internal B32 os_window_is_maximized(OS_Window window);
|
||||
internal void os_window_set_maximized(OS_Window window, B32 maximized);
|
||||
internal B32 os_window_is_minimized(OS_Window window);
|
||||
internal void os_window_set_minimized(OS_Window window, B32 minimized);
|
||||
internal void os_window_bring_to_front(OS_Window window);
|
||||
internal void os_window_set_monitor(OS_Window window, OS_Monitor monitor);
|
||||
internal void os_window_clear_custom_border_data(OS_Window handle);
|
||||
internal void os_window_push_custom_title_bar(OS_Window handle, F32 thickness);
|
||||
internal void os_window_push_custom_edges(OS_Window handle, F32 thickness);
|
||||
internal void os_window_push_custom_title_bar_client_area(OS_Window handle, Rng2F32 rect);
|
||||
internal Rng2F32 os_rect_from_window(OS_Window window);
|
||||
internal Rng2F32 os_client_rect_from_window(OS_Window window);
|
||||
internal F32 os_dpi_from_window(OS_Window window);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks External Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_ExternalWindow os_focused_external_window(void);
|
||||
internal void os_focus_external_window(OS_ExternalWindow ext_window);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
||||
|
||||
internal OS_MonitorArray os_push_monitors_array(Arena *arena);
|
||||
internal OS_Monitor os_primary_monitor(void);
|
||||
internal OS_Monitor os_monitor_from_window(OS_Window window);
|
||||
internal String8 os_name_from_monitor(Arena *arena, OS_Monitor monitor);
|
||||
internal Vec2F32 os_dim_from_monitor(OS_Monitor monitor);
|
||||
internal F32 os_dpi_from_monitor(OS_Monitor monitor);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Events (Implemented Per-OS)
|
||||
|
||||
internal void os_send_wakeup_event(void);
|
||||
internal OS_EventList os_get_events(Arena *arena, B32 wait);
|
||||
internal OS_Modifiers os_get_modifiers(void);
|
||||
internal B32 os_key_is_down(OS_Key key);
|
||||
internal Vec2F32 os_mouse_from_window(OS_Window window);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Cursors (Implemented Per-OS)
|
||||
|
||||
internal void os_set_cursor(OS_Cursor cursor);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Native User-Facing Graphical Messages (Implemented Per-OS)
|
||||
|
||||
internal void os_graphical_message(B32 error, String8 title, String8 message);
|
||||
internal String8 os_graphical_pick_file(Arena *arena, String8 initial_path);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shell Operations
|
||||
|
||||
internal void os_show_in_filesystem_ui(String8 path);
|
||||
internal void os_open_in_browser(String8 url);
|
||||
|
||||
#endif // OS_GFX_H
|
||||
@@ -1,172 +1,172 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Tables
|
||||
|
||||
@table(name, display_string, cfg_string)
|
||||
OS_KeyTable:
|
||||
{
|
||||
{Null "Invalid Key" "null" }
|
||||
{Esc "Escape" "esc" }
|
||||
{F1 "F1" "f1" }
|
||||
{F2 "F2" "f2" }
|
||||
{F3 "F3" "f3" }
|
||||
{F4 "F4" "f4" }
|
||||
{F5 "F5" "f5" }
|
||||
{F6 "F6" "f6" }
|
||||
{F7 "F7" "f7" }
|
||||
{F8 "F8" "f8" }
|
||||
{F9 "F9" "f9" }
|
||||
{F10 "F10" "f10" }
|
||||
{F11 "F11" "f11" }
|
||||
{F12 "F12" "f12" }
|
||||
{F13 "F13" "f13" }
|
||||
{F14 "F14" "f14" }
|
||||
{F15 "F15" "f15" }
|
||||
{F16 "F16" "f16" }
|
||||
{F17 "F17" "f17" }
|
||||
{F18 "F18" "f18" }
|
||||
{F19 "F19" "f19" }
|
||||
{F20 "F20" "f20" }
|
||||
{F21 "F21" "f21" }
|
||||
{F22 "F22" "f22" }
|
||||
{F23 "F23" "f23" }
|
||||
{F24 "F24" "f24" }
|
||||
{Tick "Tick" "tick" }
|
||||
{0 "0" "0" }
|
||||
{1 "1" "1" }
|
||||
{2 "2" "2" }
|
||||
{3 "3" "3" }
|
||||
{4 "4" "4" }
|
||||
{5 "5" "5" }
|
||||
{6 "6" "6" }
|
||||
{7 "7" "7" }
|
||||
{8 "8" "8" }
|
||||
{9 "9" "9" }
|
||||
{Minus "Minus" "minus" }
|
||||
{Equal "Equal" "equal" }
|
||||
{Backspace "Backspace" "backspace" }
|
||||
{Tab "Tab" "tab" }
|
||||
{Q "Q" "q" }
|
||||
{W "W" "w" }
|
||||
{E "E" "e" }
|
||||
{R "R" "r" }
|
||||
{T "T" "t" }
|
||||
{Y "Y" "y" }
|
||||
{U "U" "u" }
|
||||
{I "I" "i" }
|
||||
{O "O" "o" }
|
||||
{P "P" "p" }
|
||||
{LeftBracket "Left Bracket" "left_bracket" }
|
||||
{RightBracket "Right Bracket" "right_bracket" }
|
||||
{BackSlash "Back Slash" "backslash" }
|
||||
{CapsLock "Caps Lock" "caps_lock" }
|
||||
{A "A" "a" }
|
||||
{S "S" "s" }
|
||||
{D "D" "d" }
|
||||
{F "F" "f" }
|
||||
{G "G" "g" }
|
||||
{H "H" "h" }
|
||||
{J "J" "j" }
|
||||
{K "K" "k" }
|
||||
{L "L" "l" }
|
||||
{Semicolon "Semicolon" "semicolon" }
|
||||
{Quote "Quote" "quote" }
|
||||
{Return "Return" "return" }
|
||||
{Shift "Shift" "shift" }
|
||||
{Z "Z" "z" }
|
||||
{X "X" "x" }
|
||||
{C "C" "c" }
|
||||
{V "V" "v" }
|
||||
{B "B" "b" }
|
||||
{N "N" "n" }
|
||||
{M "M" "m" }
|
||||
{Comma "Comma" "comma" }
|
||||
{Period "Period" "period" }
|
||||
{Slash "Slash" "slash" }
|
||||
{Ctrl "Ctrl" "ctrl" }
|
||||
{Alt "Alt" "alt" }
|
||||
{Space "Space" "space" }
|
||||
{Menu "Menu" "menu" }
|
||||
{ScrollLock "Scroll Lock" "scroll_lock" }
|
||||
{Pause "Pause" "pause" }
|
||||
{Insert "Insert" "insert" }
|
||||
{Home "Home" "home" }
|
||||
{PageUp "Page Up" "page_up" }
|
||||
{Delete "Delete" "delete" }
|
||||
{End "End" "end" }
|
||||
{PageDown "Page Down" "page_down" }
|
||||
{Up "Up" "up" }
|
||||
{Left "Left" "left" }
|
||||
{Down "Down" "down" }
|
||||
{Right "Right" "right" }
|
||||
{Ex0 "Ex0" "ex0" }
|
||||
{Ex1 "Ex1" "ex1" }
|
||||
{Ex2 "Ex2" "ex2" }
|
||||
{Ex3 "Ex3" "ex3" }
|
||||
{Ex4 "Ex4" "ex4" }
|
||||
{Ex5 "Ex5" "ex5" }
|
||||
{Ex6 "Ex6" "ex6" }
|
||||
{Ex7 "Ex7" "ex7" }
|
||||
{Ex8 "Ex8" "ex8" }
|
||||
{Ex9 "Ex9" "ex9" }
|
||||
{Ex10 "Ex10" "ex10" }
|
||||
{Ex11 "Ex11" "ex11" }
|
||||
{Ex12 "Ex12" "ex12" }
|
||||
{Ex13 "Ex13" "ex13" }
|
||||
{Ex14 "Ex14" "ex14" }
|
||||
{Ex15 "Ex15" "ex15" }
|
||||
{Ex16 "Ex16" "ex16" }
|
||||
{Ex17 "Ex17" "ex17" }
|
||||
{Ex18 "Ex18" "ex18" }
|
||||
{Ex19 "Ex19" "ex19" }
|
||||
{Ex20 "Ex20" "ex20" }
|
||||
{Ex21 "Ex21" "ex21" }
|
||||
{Ex22 "Ex22" "ex22" }
|
||||
{Ex23 "Ex23" "ex23" }
|
||||
{Ex24 "Ex24" "ex24" }
|
||||
{Ex25 "Ex25" "ex25" }
|
||||
{Ex26 "Ex26" "ex26" }
|
||||
{Ex27 "Ex27" "ex27" }
|
||||
{Ex28 "Ex28" "ex28" }
|
||||
{Ex29 "Ex29" "ex29" }
|
||||
{NumLock "Num Lock" "num_lock" }
|
||||
{NumSlash "Numpad Slash" "numpad_slash" }
|
||||
{NumStar "Numpad Star" "numpad_star" }
|
||||
{NumMinus "Numpad Minus" "numpad_minus" }
|
||||
{NumPlus "Numpad Plus" "numpad_plus" }
|
||||
{NumPeriod "Numpad Period" "numpad_period" }
|
||||
{Num0 "Numpad 0" "numpad_0" }
|
||||
{Num1 "Numpad 1" "numpad_1" }
|
||||
{Num2 "Numpad 2" "numpad_2" }
|
||||
{Num3 "Numpad 3" "numpad_3" }
|
||||
{Num4 "Numpad 4" "numpad_4" }
|
||||
{Num5 "Numpad 5" "numpad_5" }
|
||||
{Num6 "Numpad 6" "numpad_6" }
|
||||
{Num7 "Numpad 7" "numpad_7" }
|
||||
{Num8 "Numpad 8" "numpad_8" }
|
||||
{Num9 "Numpad 9" "numpad_9" }
|
||||
{LeftMouseButton "Left Mouse Button" "left_mouse" }
|
||||
{MiddleMouseButton "Middle Mouse Button" "middle_mouse" }
|
||||
{RightMouseButton "Right Mouse Button" "right_mouse" }
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Generators
|
||||
|
||||
@enum OS_Key:
|
||||
{
|
||||
@expand(OS_KeyTable a) `$(a.name)`,
|
||||
COUNT,
|
||||
}
|
||||
|
||||
@data(String8) os_g_key_display_string_table:
|
||||
{
|
||||
@expand(OS_KeyTable a) `str8_lit_comp("$(a.display_string)")`;
|
||||
}
|
||||
|
||||
@data(String8) os_g_key_cfg_string_table:
|
||||
{
|
||||
@expand(OS_KeyTable a) `str8_lit_comp("$(a.cfg_string)")`;
|
||||
}
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Tables
|
||||
|
||||
@table(name, display_string, cfg_string)
|
||||
OS_KeyTable:
|
||||
{
|
||||
{Null "Invalid Key" "null" }
|
||||
{Esc "Escape" "esc" }
|
||||
{F1 "F1" "f1" }
|
||||
{F2 "F2" "f2" }
|
||||
{F3 "F3" "f3" }
|
||||
{F4 "F4" "f4" }
|
||||
{F5 "F5" "f5" }
|
||||
{F6 "F6" "f6" }
|
||||
{F7 "F7" "f7" }
|
||||
{F8 "F8" "f8" }
|
||||
{F9 "F9" "f9" }
|
||||
{F10 "F10" "f10" }
|
||||
{F11 "F11" "f11" }
|
||||
{F12 "F12" "f12" }
|
||||
{F13 "F13" "f13" }
|
||||
{F14 "F14" "f14" }
|
||||
{F15 "F15" "f15" }
|
||||
{F16 "F16" "f16" }
|
||||
{F17 "F17" "f17" }
|
||||
{F18 "F18" "f18" }
|
||||
{F19 "F19" "f19" }
|
||||
{F20 "F20" "f20" }
|
||||
{F21 "F21" "f21" }
|
||||
{F22 "F22" "f22" }
|
||||
{F23 "F23" "f23" }
|
||||
{F24 "F24" "f24" }
|
||||
{Tick "Tick" "tick" }
|
||||
{0 "0" "0" }
|
||||
{1 "1" "1" }
|
||||
{2 "2" "2" }
|
||||
{3 "3" "3" }
|
||||
{4 "4" "4" }
|
||||
{5 "5" "5" }
|
||||
{6 "6" "6" }
|
||||
{7 "7" "7" }
|
||||
{8 "8" "8" }
|
||||
{9 "9" "9" }
|
||||
{Minus "Minus" "minus" }
|
||||
{Equal "Equal" "equal" }
|
||||
{Backspace "Backspace" "backspace" }
|
||||
{Tab "Tab" "tab" }
|
||||
{Q "Q" "q" }
|
||||
{W "W" "w" }
|
||||
{E "E" "e" }
|
||||
{R "R" "r" }
|
||||
{T "T" "t" }
|
||||
{Y "Y" "y" }
|
||||
{U "U" "u" }
|
||||
{I "I" "i" }
|
||||
{O "O" "o" }
|
||||
{P "P" "p" }
|
||||
{LeftBracket "Left Bracket" "left_bracket" }
|
||||
{RightBracket "Right Bracket" "right_bracket" }
|
||||
{BackSlash "Back Slash" "backslash" }
|
||||
{CapsLock "Caps Lock" "caps_lock" }
|
||||
{A "A" "a" }
|
||||
{S "S" "s" }
|
||||
{D "D" "d" }
|
||||
{F "F" "f" }
|
||||
{G "G" "g" }
|
||||
{H "H" "h" }
|
||||
{J "J" "j" }
|
||||
{K "K" "k" }
|
||||
{L "L" "l" }
|
||||
{Semicolon "Semicolon" "semicolon" }
|
||||
{Quote "Quote" "quote" }
|
||||
{Return "Return" "return" }
|
||||
{Shift "Shift" "shift" }
|
||||
{Z "Z" "z" }
|
||||
{X "X" "x" }
|
||||
{C "C" "c" }
|
||||
{V "V" "v" }
|
||||
{B "B" "b" }
|
||||
{N "N" "n" }
|
||||
{M "M" "m" }
|
||||
{Comma "Comma" "comma" }
|
||||
{Period "Period" "period" }
|
||||
{Slash "Slash" "slash" }
|
||||
{Ctrl "Ctrl" "ctrl" }
|
||||
{Alt "Alt" "alt" }
|
||||
{Space "Space" "space" }
|
||||
{Menu "Menu" "menu" }
|
||||
{ScrollLock "Scroll Lock" "scroll_lock" }
|
||||
{Pause "Pause" "pause" }
|
||||
{Insert "Insert" "insert" }
|
||||
{Home "Home" "home" }
|
||||
{PageUp "Page Up" "page_up" }
|
||||
{Delete "Delete" "delete" }
|
||||
{End "End" "end" }
|
||||
{PageDown "Page Down" "page_down" }
|
||||
{Up "Up" "up" }
|
||||
{Left "Left" "left" }
|
||||
{Down "Down" "down" }
|
||||
{Right "Right" "right" }
|
||||
{Ex0 "Ex0" "ex0" }
|
||||
{Ex1 "Ex1" "ex1" }
|
||||
{Ex2 "Ex2" "ex2" }
|
||||
{Ex3 "Ex3" "ex3" }
|
||||
{Ex4 "Ex4" "ex4" }
|
||||
{Ex5 "Ex5" "ex5" }
|
||||
{Ex6 "Ex6" "ex6" }
|
||||
{Ex7 "Ex7" "ex7" }
|
||||
{Ex8 "Ex8" "ex8" }
|
||||
{Ex9 "Ex9" "ex9" }
|
||||
{Ex10 "Ex10" "ex10" }
|
||||
{Ex11 "Ex11" "ex11" }
|
||||
{Ex12 "Ex12" "ex12" }
|
||||
{Ex13 "Ex13" "ex13" }
|
||||
{Ex14 "Ex14" "ex14" }
|
||||
{Ex15 "Ex15" "ex15" }
|
||||
{Ex16 "Ex16" "ex16" }
|
||||
{Ex17 "Ex17" "ex17" }
|
||||
{Ex18 "Ex18" "ex18" }
|
||||
{Ex19 "Ex19" "ex19" }
|
||||
{Ex20 "Ex20" "ex20" }
|
||||
{Ex21 "Ex21" "ex21" }
|
||||
{Ex22 "Ex22" "ex22" }
|
||||
{Ex23 "Ex23" "ex23" }
|
||||
{Ex24 "Ex24" "ex24" }
|
||||
{Ex25 "Ex25" "ex25" }
|
||||
{Ex26 "Ex26" "ex26" }
|
||||
{Ex27 "Ex27" "ex27" }
|
||||
{Ex28 "Ex28" "ex28" }
|
||||
{Ex29 "Ex29" "ex29" }
|
||||
{NumLock "Num Lock" "num_lock" }
|
||||
{NumSlash "Numpad Slash" "numpad_slash" }
|
||||
{NumStar "Numpad Star" "numpad_star" }
|
||||
{NumMinus "Numpad Minus" "numpad_minus" }
|
||||
{NumPlus "Numpad Plus" "numpad_plus" }
|
||||
{NumPeriod "Numpad Period" "numpad_period" }
|
||||
{Num0 "Numpad 0" "numpad_0" }
|
||||
{Num1 "Numpad 1" "numpad_1" }
|
||||
{Num2 "Numpad 2" "numpad_2" }
|
||||
{Num3 "Numpad 3" "numpad_3" }
|
||||
{Num4 "Numpad 4" "numpad_4" }
|
||||
{Num5 "Numpad 5" "numpad_5" }
|
||||
{Num6 "Numpad 6" "numpad_6" }
|
||||
{Num7 "Numpad 7" "numpad_7" }
|
||||
{Num8 "Numpad 8" "numpad_8" }
|
||||
{Num9 "Numpad 9" "numpad_9" }
|
||||
{LeftMouseButton "Left Mouse Button" "left_mouse" }
|
||||
{MiddleMouseButton "Middle Mouse Button" "middle_mouse" }
|
||||
{RightMouseButton "Right Mouse Button" "right_mouse" }
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Generators
|
||||
|
||||
@enum OS_Key:
|
||||
{
|
||||
@expand(OS_KeyTable a) `$(a.name)`,
|
||||
COUNT,
|
||||
}
|
||||
|
||||
@data(String8) os_g_key_display_string_table:
|
||||
{
|
||||
@expand(OS_KeyTable a) `str8_lit_comp("$(a.display_string)")`;
|
||||
}
|
||||
|
||||
@data(String8) os_g_key_cfg_string_table:
|
||||
{
|
||||
@expand(OS_KeyTable a) `str8_lit_comp("$(a.cfg_string)")`;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#include "window_manager.c"
|
||||
#if WM_STUB
|
||||
# include "window_manager_stub.c"
|
||||
#elif OS_WINDOWS
|
||||
# include "win32/window_manager/win32_window_manager.c"
|
||||
#elif OS_LINUX
|
||||
# include "linux/window_manager/linux_window_manager.c"
|
||||
#else
|
||||
# error Window manager layer not implemented for this operating system.
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef WINDOW_MANAGER_INC_H
|
||||
#define WINDOW_MANAGER_INC_H
|
||||
|
||||
#include "window_manager.h"
|
||||
#if WM_STUB
|
||||
# include "window_manager_stub.h"
|
||||
#elif OS_WINDOWS
|
||||
# include "win32/window_manager/win32_window_manager.h"
|
||||
#elif OS_LINUX
|
||||
# include "linux/window_manager/linux_window_manager.h"
|
||||
#else
|
||||
# error Window manager layer not implemented for this operating system.
|
||||
#endif
|
||||
|
||||
#endif // WINDOW_MANAGER_INC_H
|
||||
@@ -1,279 +1,279 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Main Initialization API (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_gfx_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Graphics System Info (Implemented Per-OS)
|
||||
|
||||
internal OS_GfxInfo *
|
||||
os_get_gfx_info(void)
|
||||
{
|
||||
local_persist OS_GfxInfo g = {0};
|
||||
return &g;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Clipboards (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_set_clipboard_text(String8 string)
|
||||
{
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_get_clipboard_text(Arena *arena)
|
||||
{
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle
|
||||
os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_close(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_title(OS_Handle window, String8 title)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_first_paint(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_focus(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_focused(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_fullscreen(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_fullscreen(OS_Handle window, B32 fullscreen)
|
||||
{
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_maximized(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_maximized(OS_Handle window, B32 maximized)
|
||||
{
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_minimized(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_minimized(OS_Handle window, B32 minimized)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_bring_to_front(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_monitor(OS_Handle window, OS_Handle monitor)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_clear_custom_border_data(OS_Handle handle)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_title_bar(OS_Handle handle, F32 thickness)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_edges(OS_Handle handle, F32 thickness)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_title_bar_client_area(OS_Handle handle, Rng2F32 rect)
|
||||
{
|
||||
}
|
||||
|
||||
internal Rng2F32
|
||||
os_rect_from_window(OS_Handle window)
|
||||
{
|
||||
Rng2F32 rect = r2f32(v2f32(0, 0), v2f32(500, 500));
|
||||
return rect;
|
||||
}
|
||||
|
||||
internal Rng2F32
|
||||
os_client_rect_from_window(OS_Handle window)
|
||||
{
|
||||
Rng2F32 rect = r2f32(v2f32(0, 0), v2f32(500, 500));
|
||||
return rect;
|
||||
}
|
||||
|
||||
internal F32
|
||||
os_dpi_from_window(OS_Handle window)
|
||||
{
|
||||
return 96.f;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks External Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle
|
||||
os_focused_external_window(void)
|
||||
{
|
||||
OS_Handle result = {0};
|
||||
// TODO(rjf)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_focus_external_window(OS_Handle handle)
|
||||
{
|
||||
// TODO(rjf)
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
||||
|
||||
internal OS_HandleArray
|
||||
os_push_monitors_array(Arena *arena)
|
||||
{
|
||||
OS_HandleArray arr = {0};
|
||||
return arr;
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
os_primary_monitor(void)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
os_monitor_from_window(OS_Handle window)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_name_from_monitor(Arena *arena, OS_Handle monitor)
|
||||
{
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
os_dim_from_monitor(OS_Handle monitor)
|
||||
{
|
||||
Vec2F32 v = v2f32(1000, 1000);
|
||||
return v;
|
||||
}
|
||||
|
||||
internal F32
|
||||
os_dpi_from_monitor(OS_Handle monitor)
|
||||
{
|
||||
return 96.f;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Events (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_send_wakeup_event(void)
|
||||
{
|
||||
}
|
||||
|
||||
internal OS_EventList
|
||||
os_get_events(Arena *arena, B32 wait)
|
||||
{
|
||||
OS_EventList evts = {0};
|
||||
return evts;
|
||||
}
|
||||
|
||||
internal OS_Modifiers
|
||||
os_get_modifiers(void)
|
||||
{
|
||||
OS_Modifiers f = 0;
|
||||
return f;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_key_is_down(OS_Key key)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
os_mouse_from_window(OS_Handle window)
|
||||
{
|
||||
return v2f32(0, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Cursors (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_set_cursor(OS_Cursor cursor)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Native User-Facing Graphical Messages (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_graphical_message(B32 error, String8 title, String8 message)
|
||||
{
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_graphical_pick_file(Arena *arena, String8 initial_path)
|
||||
{
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shell Operations
|
||||
|
||||
internal void
|
||||
os_show_in_filesystem_ui(String8 path)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_open_in_browser(String8 url)
|
||||
{
|
||||
}
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Main Initialization API (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_gfx_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Graphics System Info (Implemented Per-OS)
|
||||
|
||||
internal OS_GfxInfo *
|
||||
os_get_gfx_info(void)
|
||||
{
|
||||
local_persist OS_GfxInfo g = {0};
|
||||
return &g;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Clipboards (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_set_clipboard_text(String8 string)
|
||||
{
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_get_clipboard_text(Arena *arena)
|
||||
{
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle
|
||||
os_window_open(Rng2F32 rect, OS_WindowFlags flags, String8 title)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_close(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_title(OS_Handle window, String8 title)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_first_paint(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_focus(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_focused(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_fullscreen(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_fullscreen(OS_Handle window, B32 fullscreen)
|
||||
{
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_maximized(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_maximized(OS_Handle window, B32 maximized)
|
||||
{
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_window_is_minimized(OS_Handle window)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_minimized(OS_Handle window, B32 minimized)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_bring_to_front(OS_Handle window)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_set_monitor(OS_Handle window, OS_Handle monitor)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_clear_custom_border_data(OS_Handle handle)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_title_bar(OS_Handle handle, F32 thickness)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_edges(OS_Handle handle, F32 thickness)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_window_push_custom_title_bar_client_area(OS_Handle handle, Rng2F32 rect)
|
||||
{
|
||||
}
|
||||
|
||||
internal Rng2F32
|
||||
os_rect_from_window(OS_Handle window)
|
||||
{
|
||||
Rng2F32 rect = r2f32(v2f32(0, 0), v2f32(500, 500));
|
||||
return rect;
|
||||
}
|
||||
|
||||
internal Rng2F32
|
||||
os_client_rect_from_window(OS_Handle window)
|
||||
{
|
||||
Rng2F32 rect = r2f32(v2f32(0, 0), v2f32(500, 500));
|
||||
return rect;
|
||||
}
|
||||
|
||||
internal F32
|
||||
os_dpi_from_window(OS_Handle window)
|
||||
{
|
||||
return 96.f;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks External Windows (Implemented Per-OS)
|
||||
|
||||
internal OS_Handle
|
||||
os_focused_external_window(void)
|
||||
{
|
||||
OS_Handle result = {0};
|
||||
// TODO(rjf)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
os_focus_external_window(OS_Handle handle)
|
||||
{
|
||||
// TODO(rjf)
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Monitors (Implemented Per-OS)
|
||||
|
||||
internal OS_HandleArray
|
||||
os_push_monitors_array(Arena *arena)
|
||||
{
|
||||
OS_HandleArray arr = {0};
|
||||
return arr;
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
os_primary_monitor(void)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal OS_Handle
|
||||
os_monitor_from_window(OS_Handle window)
|
||||
{
|
||||
OS_Handle handle = {1};
|
||||
return handle;
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_name_from_monitor(Arena *arena, OS_Handle monitor)
|
||||
{
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
os_dim_from_monitor(OS_Handle monitor)
|
||||
{
|
||||
Vec2F32 v = v2f32(1000, 1000);
|
||||
return v;
|
||||
}
|
||||
|
||||
internal F32
|
||||
os_dpi_from_monitor(OS_Handle monitor)
|
||||
{
|
||||
return 96.f;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Events (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_send_wakeup_event(void)
|
||||
{
|
||||
}
|
||||
|
||||
internal OS_EventList
|
||||
os_get_events(Arena *arena, B32 wait)
|
||||
{
|
||||
OS_EventList evts = {0};
|
||||
return evts;
|
||||
}
|
||||
|
||||
internal OS_Modifiers
|
||||
os_get_modifiers(void)
|
||||
{
|
||||
OS_Modifiers f = 0;
|
||||
return f;
|
||||
}
|
||||
|
||||
internal B32
|
||||
os_key_is_down(OS_Key key)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal Vec2F32
|
||||
os_mouse_from_window(OS_Handle window)
|
||||
{
|
||||
return v2f32(0, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Cursors (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_set_cursor(OS_Cursor cursor)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Native User-Facing Graphical Messages (Implemented Per-OS)
|
||||
|
||||
internal void
|
||||
os_graphical_message(B32 error, String8 title, String8 message)
|
||||
{
|
||||
}
|
||||
|
||||
internal String8
|
||||
os_graphical_pick_file(Arena *arena, String8 initial_path)
|
||||
{
|
||||
return str8_zero();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: @os_hooks Shell Operations
|
||||
|
||||
internal void
|
||||
os_show_in_filesystem_ui(String8 path)
|
||||
{
|
||||
}
|
||||
|
||||
internal void
|
||||
os_open_in_browser(String8 url)
|
||||
{
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_GFX_STUB_H
|
||||
#define OS_GFX_STUB_H
|
||||
|
||||
#endif // OS_GFX_STUB_H
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef OS_GFX_STUB_H
|
||||
#define OS_GFX_STUB_H
|
||||
|
||||
#endif // OS_GFX_STUB_H
|
||||
+23
-15
@@ -34,7 +34,8 @@ enum
|
||||
////////////////////////////////
|
||||
//~ fxsave/xsave
|
||||
|
||||
typedef struct AlignType(16) X64_FXSave
|
||||
typedef struct X64_FXSave X64_FXSave;
|
||||
struct AlignType(16) X64_FXSave
|
||||
{
|
||||
U16 fcw;
|
||||
U16 fsw;
|
||||
@@ -48,23 +49,25 @@ typedef struct AlignType(16) X64_FXSave
|
||||
U128 st_space[8];
|
||||
U128 xmm_space[16];
|
||||
U8 padding[96];
|
||||
} X64_FXSave;
|
||||
};
|
||||
StaticAssert(sizeof(X64_FXSave) == 512, g_x64_xsave_legacy_size_check);
|
||||
|
||||
typedef struct X64_XSaveHeader
|
||||
typedef struct X64_XSaveHeader X64_XSaveHeader;
|
||||
struct X64_XSaveHeader
|
||||
{
|
||||
U64 xstate_bv;
|
||||
U64 xcomp_bv;
|
||||
U8 reserved[48];
|
||||
} X64_XSaveHeader;
|
||||
};
|
||||
StaticAssert(sizeof(X64_XSaveHeader) == 64, g_x64_xsave_header_size_check);
|
||||
|
||||
typedef struct AlignType(64) X64_XSave
|
||||
typedef struct X64_XSave X64_XSave;
|
||||
struct AlignType(64) X64_XSave
|
||||
{
|
||||
X64_FXSave fxsave;
|
||||
X64_XSaveHeader header;
|
||||
// U8 ext_area[0];
|
||||
} X64_XSave;
|
||||
};
|
||||
StaticAssert(sizeof(X64_XSave) == 576, g_x64_xsave_size_check);
|
||||
|
||||
typedef U32 X64_XStateComponentIdx;
|
||||
@@ -90,7 +93,6 @@ enum
|
||||
X64_XStateComponentIdx_TILECFG = 17,
|
||||
X64_XStateComponentIdx_TILEDATA = 18,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
X64_XStateComponentFlag_FP = (1 << X64_XStateComponentIdx_FP),
|
||||
@@ -114,7 +116,8 @@ enum
|
||||
X64_XStateComponentFlag_TILEDATA = (1 << X64_XStateComponentIdx_TILEDATA),
|
||||
};
|
||||
|
||||
typedef struct
|
||||
typedef struct X64_XSaveLayout X64_XSaveLayout;
|
||||
struct X64_XSaveLayout
|
||||
{
|
||||
U64 x87_offset;
|
||||
U64 sse_offset;
|
||||
@@ -135,12 +138,12 @@ typedef struct
|
||||
U64 hwp_offset;
|
||||
U64 tile_cfg_offset;
|
||||
U64 tile_data_offset;
|
||||
} X64_XSaveLayout;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ Debug Status Register
|
||||
|
||||
typedef enum
|
||||
typedef enum X64_DebugStatusFlags
|
||||
{
|
||||
X64_DebugStatusFlag_B0 = (1 << 0),
|
||||
X64_DebugStatusFlag_B1 = (1 << 1),
|
||||
@@ -151,16 +154,19 @@ typedef enum
|
||||
X64_DebugStatusFlag_SingleStep = (1 << 14),
|
||||
X64_DebugStatusFlag_TaskSwitch = (1 << 15),
|
||||
X64_DebugStatusFlag_RTM = (1 << 16),
|
||||
} X64_DebugStatusFlags;
|
||||
}
|
||||
X64_DebugStatusFlags;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Debug Control Register
|
||||
|
||||
typedef enum X64_BreakpointType {
|
||||
typedef enum X64_BreakpointType
|
||||
{
|
||||
X64_BreakpointType_Null,
|
||||
X64_BreakpointType_Local,
|
||||
X64_BreakpointType_Global,
|
||||
} X64_BreakpointType;
|
||||
}
|
||||
X64_BreakpointType;
|
||||
|
||||
typedef enum X64_DebugBreakType
|
||||
{
|
||||
@@ -169,7 +175,8 @@ typedef enum X64_DebugBreakType
|
||||
X64_DebugBreakType_Write,
|
||||
X64_DebugBreakType_ReadWriteIO,
|
||||
X64_DebugBreakType_ReadWriteNoFetch,
|
||||
} X64_DebugBreakType;
|
||||
}
|
||||
X64_DebugBreakType;
|
||||
|
||||
typedef enum X64_DebugControlFlags
|
||||
{
|
||||
@@ -199,7 +206,8 @@ typedef enum X64_DebugControlFlags
|
||||
X64_DebugControlFlag_LEN1 = (3 << 22),
|
||||
X64_DebugControlFlag_LEN2 = (3 << 26),
|
||||
X64_DebugControlFlag_LEN3 = (3 << 30),
|
||||
} X64_DebugControlFlags;
|
||||
}
|
||||
X64_DebugControlFlags;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Generated
|
||||
|
||||
Reference in New Issue
Block a user