diff options
| author | 2025-02-22 10:27:03 -0500 | |
|---|---|---|
| committer | 2025-02-22 10:27:03 -0500 | |
| commit | 1993433dc36dfae6a6c4b32f613e64ba213fdc23 (patch) | |
| tree | 437168827e9e74d58c5f33481e9106b42a67759e /src | |
| parent | c0cd683e98f357d4b81cfd44444dbc909dcb2386 (diff) | |
| download | stela-1993433dc36dfae6a6c4b32f613e64ba213fdc23.tar.gz stela-1993433dc36dfae6a6c4b32f613e64ba213fdc23.tar.bz2 stela-1993433dc36dfae6a6c4b32f613e64ba213fdc23.zip | |
Initial Windows window, refactor global_init()
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src')
| -rw-r--r-- | src/window.h | 3 | ||||
| -rw-r--r-- | src/window_glfm.c | 5 | ||||
| -rw-r--r-- | src/window_glfw.c | 7 | ||||
| -rw-r--r-- | src/window_kms.c | 7 | ||||
| -rw-r--r-- | src/window_wayland.c | 4 | ||||
| -rw-r--r-- | src/window_win32.c | 355 | ||||
| -rw-r--r-- | src/window_win32.h | 19 | ||||
| -rw-r--r-- | src/window_x11.c | 4 |
8 files changed, 393 insertions, 11 deletions
diff --git a/src/window.h b/src/window.h index 7c71056..7df00a3 100644 --- a/src/window.h +++ b/src/window.h @@ -16,6 +16,7 @@ #include <al/types.h> #include <al/lib.h> +#include <al/str.h> #include <al/ring_buffer.h> #if defined STELA_API_VULKAN @@ -139,7 +140,7 @@ enum { #endif void stl_set_output_discovered_callback(void (*output_discovered)(void *, struct stl_monitor *), void *userdata); -bool stl_global_init(bool skip_graphics); +s32 stl_global_init(s32 argc, str *argv, s32 (*main)(s32, str *), bool skip_graphics); s32 stl_global_get_poll_fd(); void stl_global_process_events(); void stl_global_close(void); diff --git a/src/window_glfm.c b/src/window_glfm.c index 29ab44b..7668eca 100644 --- a/src/window_glfm.c +++ b/src/window_glfm.c @@ -8,8 +8,11 @@ void stl_set_output_discovered_callback(void (*output_discovered)(void *, struct (void)userdata; } -bool stl_global_init(bool skip_graphics) +s32 stl_global_init(s32 argc, str *argv, s32 (*main)(s32, str *), bool skip_graphics) { + (void)argc; + (void)argv; + (void)main; (void)skip_graphics; return false; } diff --git a/src/window_glfw.c b/src/window_glfw.c index 836e7c8..bfd266f 100644 --- a/src/window_glfw.c +++ b/src/window_glfw.c @@ -36,16 +36,19 @@ static void error_callback(s32 error_code, const char *description) al_log_error("glfw", "GLFW Error %d: %s.", error_code, description); } -bool stl_global_init(bool skip_graphics) +s32 stl_global_init(s32 argc, str *argv, s32 (*main)(s32, str *), bool skip_graphics) { (void)skip_graphics; + glfwSetErrorCallback(error_callback); if (!glfwInit()) { al_log_error("glfw", "Failed to initialize GLFW."); return false; } + global.master_window = NULL; - return true; + + return main(argc, argv); } s32 stl_global_get_poll_fd() diff --git a/src/window_kms.c b/src/window_kms.c index 58d68eb..3a4e1a7 100644 --- a/src/window_kms.c +++ b/src/window_kms.c @@ -1,5 +1,3 @@ -#include <al/log.h> - #include "window_kms.h" void stl_set_output_discovered_callback(void (*output_discovered)(void *, struct stl_monitor *), void *userdata) @@ -8,8 +6,11 @@ void stl_set_output_discovered_callback(void (*output_discovered)(void *, struct (void)userdata; } -bool stl_global_init(bool skip_graphics) +s32 stl_global_init(s32 argc, str *argv, s32 (*main)(s32, str *), bool skip_graphics) { + (void)argc; + (void)argv; + (void)main; (void)skip_graphics; return false; } diff --git a/src/window_wayland.c b/src/window_wayland.c index 6935f0e..64177b9 100644 --- a/src/window_wayland.c +++ b/src/window_wayland.c @@ -127,7 +127,7 @@ void stl_set_output_discovered_callback(void (*output_discovered)(void *, struct global.userdata = userdata; } -bool stl_global_init(bool skip_graphics) +s32 stl_global_init(s32 argc, str *argv, s32 (*main)(s32, str *), bool skip_graphics) { global.display = wl_display_connect(NULL); if (!global.display) { @@ -164,7 +164,7 @@ bool stl_global_init(bool skip_graphics) wl_display_roundtrip(global.display); wl_display_roundtrip(global.display); - return true; + return main(argc, argv); } s32 stl_global_get_poll_fd() diff --git a/src/window_win32.c b/src/window_win32.c new file mode 100644 index 0000000..5367c1a --- /dev/null +++ b/src/window_win32.c @@ -0,0 +1,355 @@ +#include "window_win32.h" +#include "common.h" + +// All extra Windows headers come after <nnwt/windows.h>. +#include <windowsx.h> + +void stl_set_output_discovered_callback(void (*output_discovered)(void *, struct stl_monitor *), void *userdata) +{ + (void)output_discovered; + (void)userdata; +} + +// https://github.com/cmuratori/dtc + +struct the_baby { + DWORD dwExStyle; + LPCWSTR lpClassName; + LPCWSTR lpWindowName; + DWORD dwStyle; + s32 X; + s32 Y; + s32 nWidth; + s32 nHeight; + HWND hWndParent; + HMENU hMenu; + HINSTANCE hInstance; + LPVOID lpParam; +}; + +#define CREATE_DANGEROUS_WINDOW (WM_USER + 0x1337) +#define DESTROY_DANGEROUS_WINDOW (WM_USER + 0x1338) +#define EXIT_PROCESS (WM_USER + 0x1339) +#define WAKE_WINDOW (WM_USER + 0x133a) + +static DWORD MainThreadID; +static struct stl_win32_global global; + +static LRESULT CALLBACK ServiceWndProc(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam) +{ + LRESULT Result = 0; + + switch (Message) { + case CREATE_DANGEROUS_WINDOW: { + struct the_baby *Baby = (struct the_baby *)WParam; + Result = (LRESULT)CreateWindowExW(Baby->dwExStyle, + Baby->lpClassName, + Baby->lpWindowName, + Baby->dwStyle, + Baby->X, + Baby->Y, + Baby->nWidth, + Baby->nHeight, + Baby->hWndParent, + Baby->hMenu, + Baby->hInstance, + Baby->lpParam); + break; + } + case DESTROY_DANGEROUS_WINDOW: + DestroyWindow((HWND)WParam); + break; + case EXIT_PROCESS: + PostQuitMessage(WParam); + break; + default: + Result = DefWindowProcW(Window, Message, WParam, LParam); + break; + } + + return Result; +} + +static DWORD WINAPI MainThread(LPVOID Param) +{ + (void)Param; + s32 ret = global.main(global.argc, global.argv); + SendMessageW(global.ServiceWindow, EXIT_PROCESS, (WPARAM)ret, 0); + return 0; +} + +s32 stl_global_init(s32 argc, str *argv, s32 (*main)(s32, str *), bool skip_graphics) +{ + (void)skip_graphics; + + WNDCLASSEXW WindowClass = { 0 }; + WindowClass.cbSize = sizeof(WindowClass); + WindowClass.lpfnWndProc = &ServiceWndProc; + WindowClass.hInstance = GetModuleHandleW(NULL); + WindowClass.hIcon = LoadIconA(NULL, IDI_APPLICATION); + WindowClass.hCursor = LoadCursorA(NULL, IDC_ARROW); + WindowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + WindowClass.lpszClassName = L"DTCClass"; + RegisterClassExW(&WindowClass); + + global.ServiceWindow = CreateWindowExW(0, WindowClass.lpszClassName, L"DTCService", 0, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, WindowClass.hInstance, 0); + global.argc = argc; + global.argv = argv; + global.main = main; + + CreateThread(0, 0, MainThread, NULL, 0, &MainThreadID); + + for (;;) { + MSG Message; + GetMessageW(&Message, 0, 0, 0); + TranslateMessage(&Message); + if (Message.message == WM_QUIT) { + return Message.wParam; + } + DispatchMessageW(&Message); + } + + return EXIT_FAILURE; +} + +s32 stl_global_get_poll_fd() +{ + return -1; +} + +void stl_global_process_events() +{ +} + +void stl_global_close(void) +{ +} + +static LRESULT CALLBACK DisplayWndProc(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam) +{ + LRESULT Result = 0; + + /* + if (Message == WM_CREATE) { + SetWindowLongPtrA(Window, GWLP_USERDATA, (LONG_PTR)((LPCREATESTRUCT)LParam)->lpCreateParams); + return Result; + } + struct stl_window_win32 *w32 = (struct stl_window_win32 *)GetWindowLongPtrA(Window, GWLP_USERDATA); + */ + + switch (Message) { + case WM_CLOSE: + PostThreadMessageW(MainThreadID, Message, (WPARAM)Window, LParam); + break; + case WM_MOUSEMOVE: + case WM_MOUSEWHEEL: + case WM_KEYDOWN: + case WM_KEYUP: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_SIZE: + PostThreadMessageW(MainThreadID, Message, WParam, LParam); + break; + default: + Result = DefWindowProcW(Window, Message, WParam, LParam); + break; + } + + return Result; +} + +static bool window_win32_create_window(struct stl_window *window, u32 width, u32 height, + const char *monitor, const char *name, u32 flags) +{ + struct stl_window_win32 *w32 = (struct stl_window_win32 *)window; + (void)monitor; + (void)flags; + + w32->w.width = width; + w32->w.width = height; + + WNDCLASSEXW WindowClass = { 0 }; + WindowClass.cbSize = sizeof(WindowClass); + WindowClass.lpfnWndProc = &DisplayWndProc; + WindowClass.hInstance = GetModuleHandleW(NULL); + WindowClass.hIcon = LoadIconA(NULL, IDI_APPLICATION); + WindowClass.hCursor = LoadCursorA(NULL, IDC_ARROW); + WindowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + WindowClass.lpszClassName = L"Dangerous Class"; + RegisterClassExW(&WindowClass); + + struct the_baby Baby = { 0 }; + Baby.dwExStyle = 0; + Baby.lpClassName = WindowClass.lpszClassName; + al_wstr_from_cstr(&w32->WindowName, (char *)name); + Baby.lpWindowName = w32->WindowName.data; + Baby.dwStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE; + Baby.X = CW_USEDEFAULT; + Baby.Y = CW_USEDEFAULT; + Baby.nWidth = width; + Baby.nHeight = height; + Baby.hInstance = WindowClass.hInstance; + Baby.lpParam = w32; + w32->Window = (HWND)SendMessageW(global.ServiceWindow, CREATE_DANGEROUS_WINDOW, (WPARAM)&Baby, 0); + w32->w.win32_window = w32->Window; + + return true; +} + +static void window_win32_resize_internal(struct stl_window *window, u32 width, u32 height) +{ + (void)window; + (void)width; + (void)height; +} + +static void window_win32_resize(struct stl_window *window, u32 width, u32 height) +{ + (void)window; + (void)width; + (void)height; +} + +static void window_win32_toggle_fullscreen(struct stl_window *window) +{ + (void)window; +} + +static void win32_handle_message(struct stl_window_win32 *w32, MSG *Message) +{ + switch (Message->message) { + case WM_CLOSE: + stl_window_send_should_close_event(&w32->w); + break; + case WM_MOUSEMOVE: + stl_window_send_pointer_pos_event(&w32->w, (f64)GET_X_LPARAM(Message->lParam), (f64)GET_Y_LPARAM(Message->lParam)); + break; + case WM_MOUSEWHEEL: + stl_window_send_scroll_event(&w32->w, -(f64)GET_WHEEL_DELTA_WPARAM(Message->wParam)); + break; + case WM_KEYDOWN: + stl_window_send_key_event(&w32->w, STELA_BUTTON_PRESSED, Message->wParam); + break; + case WM_KEYUP: + stl_window_send_key_event(&w32->w, STELA_BUTTON_RELEASED, Message->wParam); + break; + case WM_LBUTTONDOWN: + stl_window_send_mouse_button_event(&w32->w, STELA_BUTTON_PRESSED, STELA_MOUSE1); + break; + case WM_LBUTTONUP: + stl_window_send_mouse_button_event(&w32->w, STELA_BUTTON_RELEASED, STELA_MOUSE1); + break; + case WM_SIZE: + w32->w.width = LOWORD(Message->lParam); + w32->w.height = HIWORD(Message->lParam); + stl_window_send_resize_event(&w32->w, w32->w.width, w32->w.height); + break; + case WAKE_WINDOW: + default: + break; + } +} + +#ifdef STELA_POLL_INLINE +static bool window_win32_poll(struct stl_window *window, bool block) +{ + struct stl_window_win32 *w32 = (struct stl_window_win32 *)window; + if (block) { + MSG Message; + GetMessageW(&Message, 0, 0, 0); + win32_handle_message(w32, &Message); + } + return true; +} + +#ifdef STELA_PAUSE +static void window_win32_wake(struct stl_window *window) +{ + (void)window; + PostThreadMessageW(MainThreadID, WAKE_WINDOW, 0, 0); +} +#endif +#endif + +static void window_win32_process_events(struct stl_window *window) +{ + struct stl_window_win32 *w32 = (struct stl_window_win32 *)window; + MSG Message; + while (PeekMessage(&Message, 0, 0, 0, PM_REMOVE)) { + win32_handle_message(w32, &Message); + } +} + +#ifdef STELA_PAUSE +static bool window_win32_should_refresh(struct stl_window *window) +{ + return stl_should_refresh_common(window); +} +#endif + +static void window_win32_free(struct stl_window **window) +{ + struct stl_window_win32 *w32 = (struct stl_window_win32 *)window; + SendMessageW(global.ServiceWindow, DESTROY_DANGEROUS_WINDOW, (WPARAM)w32->Window, 0); + al_wstr_free(&w32->WindowName); +} + +#if defined STELA_API_VULKAN +#elif defined STELA_API_OPENGL +static bool window_win32_gl_loader_load(void *data) +{ + (void)data; + return true; +} + +static bool window_win32_gl_make_current(void *data) +{ + (void)data; + return true; +} + +static void window_win32_gl_release_current(void *data) +{ + (void)data; +} + +static void window_win32_gl_swap_buffers(void *data) +{ + struct stl_window_win32 *w32 = (struct stl_window_win32 *)data; + (void)w32; +} +#endif + +struct stl_window *stl_window_create(void *context) +{ + (void)context; + struct stl_window_win32 *w32 = al_alloc_object(struct stl_window_win32); + stl_window_common_init(&w32->w); + w32->w.fullscreen = true; + w32->w.create_window = window_win32_create_window; + w32->w.resize_internal = window_win32_resize_internal; + w32->w.resize = window_win32_resize; + w32->w.toggle_fullscreen = window_win32_toggle_fullscreen; +#ifdef STELA_POLL_INLINE + w32->w.poll = window_win32_poll; +#ifdef STELA_PAUSE + w32->w.wake = window_win32_wake; +#endif +#endif + w32->w.process_events = window_win32_process_events; +#ifdef STELA_PAUSE + w32->w.should_refresh = window_win32_should_refresh; +#endif + w32->w.free = window_win32_free; +#if defined STELA_API_VULKAN +#elif defined STELA_API_OPENGL + win32->w.get_gl_proc_address = NULL; + win32->w.gl_loader_load = window_win32_gl_loader_load; + win32->w.gl_make_current = window_win32_gl_make_current; + win32->w.gl_release_current = window_win32_gl_release_current; + win32->w.gl_swap_buffers = window_win32_gl_swap_buffers; +#elif defined STELA_API_DX11 +#endif + return (struct stl_window *)w32; +} diff --git a/src/window_win32.h b/src/window_win32.h new file mode 100644 index 0000000..59de230 --- /dev/null +++ b/src/window_win32.h @@ -0,0 +1,19 @@ +#pragma once + +#include <al/wstr.h> +#include <nnwt/windows.h> + +#include "window.h" + +struct stl_win32_global { + HWND ServiceWindow; + s32 argc; + str *argv; + s32 (*main)(s32, str *); +}; + +struct stl_window_win32 { + struct stl_window w; + HWND Window; + wstr WindowName; +}; diff --git a/src/window_x11.c b/src/window_x11.c index c1425ee..f0a4559 100644 --- a/src/window_x11.c +++ b/src/window_x11.c @@ -21,7 +21,7 @@ void stl_set_output_discovered_callback(void (*output_discovered)(void *, struct global.userdata = userdata; } -bool stl_global_init(bool skip_graphics) +s32 stl_global_init(s32 argc, str *argv, s32 (*main)(s32, str *), bool skip_graphics) { global.x11_d = XOpenDisplay(NULL); if (!global.x11_d) { @@ -70,7 +70,7 @@ bool stl_global_init(bool skip_graphics) } XRRFreeMonitors(info); - return true; + return main(argc, argv); } s32 stl_global_get_poll_fd() |