#include "pch.h" #include "platform_windows/windows_runtime_session.h" #include "app.h" #include "log.h" #include "platform_windows/windows_bootstrap_helpers.h" #include "platform_windows/windows_lifecycle_state.h" #include "platform_windows/windows_main_window_session.h" #include "platform_windows/windows_platform_services.h" #include "platform_windows/windows_runtime_shell.h" #include "platform_windows/windows_runtime_state.h" #include "wacom.h" #include "../resource.h" namespace pp::platform::windows { namespace { void register_touch_window(HWND hWnd) { // link: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registertouchwindow if (RegisterTouchWindow(hWnd, 0) == 0) { LOG("RegisterTouchWindow error: %s", GetLastErrorAsString().c_str()); } } void initialize_runtime_threads() { auto* app = bound_app(); auto* runtime = retained_bound_runtime(); assert(runtime); mark_lifecycle_running(); runtime->render_thread_start(*app); runtime->ui_thread_start(*app); } void install_debug_gl_callbacks() { #ifdef _DEBUG glad_set_pre_callback(_pre_call_callback); glad_set_post_callback(_post_call_callback); #endif } void initialize_wintab(HWND hWnd, bool sandboxed) { auto* tablet = bound_wacom_tablet(); if (!sandboxed) { LOG("init WinTab"); tablet->init(hWnd); } else { LOG("SKIP init WinTab"); } } void set_main_window_icon(HWND hWnd) { LOG("change icon"); SendMessage( hWnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON1))); } void restore_window_placement(HWND hWnd, int show_command) { WINDOWPLACEMENT wp; GetWindowPlacement(hWnd, &wp); wp.showCmd = show_command; SetWindowPlacement(hWnd, &wp); } void run_main_message_loop() { MSG msg; auto* app = bound_app(); LOG("start main loop"); while (lifecycle_is_running()) { auto present = app->animate || app->redraw ? PeekMessage(&msg, 0, 0, 0, PM_REMOVE) : GetMessage(&msg, 0, 0, 0); if (msg.message == WM_QUIT) mark_lifecycle_stopped(); if (present) { DispatchMessage(&msg); TranslateMessage(&msg); } drain_main_thread_tasks(); } } void shutdown_main_window_runtime(const MainWindowStartupState& startup, HINSTANCE hInst) { retained_wacom_tablet().terminate(); UnregisterClass(startup.window_class.lpszClassName, hInst); LogRemote::I.stop(); } } void run_main_window_runtime_session(const MainWindowStartupState& startup, bool start_in_vr, HINSTANCE instance, SplashScreen& splash) { auto* app = bound_app(); register_touch_window(retained_main_window_handle_ref()); wglMakeCurrent(NULL, NULL); initialize_runtime_threads(); install_debug_gl_callbacks(); initialize_wintab(retained_main_window_handle_ref(), retained_main_window_sandboxed()); set_main_window_icon(retained_main_window_handle_ref()); app->ui_sync(); restore_window_placement(retained_main_window_handle_ref(), startup.show_command); if (start_in_vr) app->vr_start(); LOG("show main window"); SetForegroundWindow(retained_main_window_handle_ref()); splash.dismiss(); run_main_message_loop(); shutdown_main_window_runtime(startup, instance); } }