Bind Win32 app shell and move more legacy platform state
This commit is contained in:
@@ -92,6 +92,17 @@ Current hotspot files:
|
|||||||
|
|
||||||
Latest slice:
|
Latest slice:
|
||||||
|
|
||||||
|
- The retained Web fallback service object and the Apple storage-path
|
||||||
|
preparation helper now also live in
|
||||||
|
`src/platform_legacy/legacy_platform_state.*` instead of being built inline
|
||||||
|
inside `src/platform_legacy/legacy_platform_services.cpp`, which trims
|
||||||
|
another process-global fallback/service pocket out of the legacy platform
|
||||||
|
shell.
|
||||||
|
- The Win32 window procedure, stylus state updates, lifecycle shutdown path,
|
||||||
|
and VR shell callback wiring no longer reach `App::I` directly; the live
|
||||||
|
Windows shell now binds the active `App*` explicitly through
|
||||||
|
`src/platform_windows/windows_runtime_shell.*`, leaving `App::I` only at
|
||||||
|
the entry/shutdown composition edge in the touched Win32 path.
|
||||||
- The full retained Apple document bridge construction no longer lives inline
|
- The full retained Apple document bridge construction no longer lives inline
|
||||||
in `src/platform_legacy/legacy_platform_services.cpp`; it now lives behind
|
in `src/platform_legacy/legacy_platform_services.cpp`; it now lives behind
|
||||||
`active_legacy_apple_document_platform_services()` in
|
`active_legacy_apple_document_platform_services()` in
|
||||||
|
|||||||
@@ -1202,6 +1202,15 @@ Why now:
|
|||||||
platform-handle state on `App`, which blocks a real `pp_platform_*` shell split.
|
platform-handle state on `App`, which blocks a real `pp_platform_*` shell split.
|
||||||
|
|
||||||
Current slice:
|
Current slice:
|
||||||
|
- The retained Web fallback service object and the Apple storage-path
|
||||||
|
preparation helper now also live in
|
||||||
|
`src/platform_legacy/legacy_platform_state.*` instead of being built inline
|
||||||
|
in `src/platform_legacy/legacy_platform_services.cpp`, which trims another
|
||||||
|
retained fallback/state pocket out of the legacy platform shell.
|
||||||
|
- The touched Win32 shell path no longer reaches `App::I` directly for
|
||||||
|
window-procedure dispatch, stylus state updates, lifecycle shutdown, or VR
|
||||||
|
callback/thread setup; `src/platform_windows/windows_runtime_shell.*` now
|
||||||
|
binds the active `App*` explicitly and clears that binding on shutdown.
|
||||||
- Windows VR session snapshot ownership no longer lives on `App`.
|
- Windows VR session snapshot ownership no longer lives on `App`.
|
||||||
- `VrSessionSnapshot` now lives behind
|
- `VrSessionSnapshot` now lives behind
|
||||||
`src/platform_windows/windows_vr_shell.h` and
|
`src/platform_windows/windows_vr_shell.h` and
|
||||||
|
|||||||
@@ -43,70 +43,15 @@ void webgl_sync();
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
#ifdef __WEB__
|
|
||||||
class RetainedWebPlatformServices final : public pp::platform::WebPlatformServices {
|
|
||||||
public:
|
|
||||||
void publish_exported_image(std::string_view path) override
|
|
||||||
{
|
|
||||||
(void)path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush_persistent_storage() override
|
|
||||||
{
|
|
||||||
webgl_sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] int default_canvas_resolution() override
|
|
||||||
{
|
|
||||||
return pp::platform::platform_default_canvas_resolution(pp::platform::PlatformFamily::webgl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void save_prepared_file(
|
|
||||||
std::string_view path,
|
|
||||||
std::string_view suggested_name,
|
|
||||||
pp::platform::PreparedFileCallback callback) override
|
|
||||||
{
|
|
||||||
const std::string value(path);
|
|
||||||
const std::string name(suggested_name);
|
|
||||||
webgl_pick_file_save(value, name, [callback = std::move(callback), value](bool success) {
|
|
||||||
callback(value, success);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
[[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services()
|
|
||||||
{
|
|
||||||
#ifdef __WEB__
|
|
||||||
static RetainedWebPlatformServices services;
|
|
||||||
return pp::platform::resolve_web_platform_services(services);
|
|
||||||
#else
|
|
||||||
return pp::platform::active_web_platform_services();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__IOS__) || defined(__OSX__)
|
|
||||||
[[nodiscard]] pp::platform::PlatformStoragePaths prepare_legacy_apple_storage_paths()
|
|
||||||
{
|
|
||||||
const auto& apple_state = pp::platform::legacy::active_legacy_apple_state();
|
|
||||||
#ifdef __IOS__
|
|
||||||
[apple_state.ios_view init_dirs];
|
|
||||||
#elif defined(__OSX__)
|
|
||||||
[apple_state.osx_app init_dirs];
|
|
||||||
#endif
|
|
||||||
return pp::platform::legacy::active_legacy_storage_paths();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// DEBT-0017: fallback for platforms that do not inject PlatformServices yet.
|
// DEBT-0017: fallback for platforms that do not inject PlatformServices yet.
|
||||||
class LegacyPlatformServices final : public pp::platform::PlatformServices {
|
class LegacyPlatformServices final : public pp::platform::PlatformServices {
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] pp::platform::PlatformStoragePaths prepare_storage_paths() override
|
[[nodiscard]] pp::platform::PlatformStoragePaths prepare_storage_paths() override
|
||||||
{
|
{
|
||||||
#if defined(__IOS__)
|
#if defined(__IOS__)
|
||||||
return prepare_legacy_apple_storage_paths();
|
return pp::platform::legacy::prepare_legacy_apple_storage_paths();
|
||||||
#elif defined(__OSX__)
|
#elif defined(__OSX__)
|
||||||
return prepare_legacy_apple_storage_paths();
|
return pp::platform::legacy::prepare_legacy_apple_storage_paths();
|
||||||
#elif __LINUX__
|
#elif __LINUX__
|
||||||
const std::string data_path = linux_home_path() + "/PanoPainter";
|
const std::string data_path = linux_home_path() + "/PanoPainter";
|
||||||
mkpath(data_path + "/brushes");
|
mkpath(data_path + "/brushes");
|
||||||
@@ -316,7 +261,7 @@ public:
|
|||||||
const auto family = pp::platform::current_platform_family();
|
const auto family = pp::platform::current_platform_family();
|
||||||
if (family == pp::platform::PlatformFamily::webgl)
|
if (family == pp::platform::PlatformFamily::webgl)
|
||||||
{
|
{
|
||||||
active_legacy_web_platform_services().publish_exported_image(path);
|
pp::platform::legacy::active_legacy_web_platform_services().publish_exported_image(path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!pp::platform::platform_publishes_exported_images(family))
|
if (!pp::platform::platform_publishes_exported_images(family))
|
||||||
@@ -336,7 +281,7 @@ public:
|
|||||||
const auto family = pp::platform::current_platform_family();
|
const auto family = pp::platform::current_platform_family();
|
||||||
if (family == pp::platform::PlatformFamily::webgl)
|
if (family == pp::platform::PlatformFamily::webgl)
|
||||||
{
|
{
|
||||||
active_legacy_web_platform_services().flush_persistent_storage();
|
pp::platform::legacy::active_legacy_web_platform_services().flush_persistent_storage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!pp::platform::platform_flushes_persistent_storage(family))
|
if (!pp::platform::platform_flushes_persistent_storage(family))
|
||||||
@@ -505,7 +450,7 @@ public:
|
|||||||
{
|
{
|
||||||
const auto family = pp::platform::current_platform_family();
|
const auto family = pp::platform::current_platform_family();
|
||||||
if (family == pp::platform::PlatformFamily::webgl)
|
if (family == pp::platform::PlatformFamily::webgl)
|
||||||
return active_legacy_web_platform_services().default_canvas_resolution();
|
return pp::platform::legacy::active_legacy_web_platform_services().default_canvas_resolution();
|
||||||
return pp::platform::platform_default_canvas_resolution(family);
|
return pp::platform::platform_default_canvas_resolution(family);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +529,7 @@ public:
|
|||||||
const auto family = pp::platform::current_platform_family();
|
const auto family = pp::platform::current_platform_family();
|
||||||
if (family == pp::platform::PlatformFamily::webgl)
|
if (family == pp::platform::PlatformFamily::webgl)
|
||||||
{
|
{
|
||||||
active_legacy_web_platform_services().save_prepared_file(
|
pp::platform::legacy::active_legacy_web_platform_services().save_prepared_file(
|
||||||
path,
|
path,
|
||||||
suggested_name,
|
suggested_name,
|
||||||
std::move(callback));
|
std::move(callback));
|
||||||
|
|||||||
@@ -10,6 +10,12 @@
|
|||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void webgl_pick_file_save(
|
||||||
|
const std::string& path,
|
||||||
|
const std::string& name,
|
||||||
|
std::function<void(bool)> callback);
|
||||||
|
void webgl_sync();
|
||||||
|
|
||||||
namespace pp::platform::legacy {
|
namespace pp::platform::legacy {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -204,6 +210,43 @@ struct RetainedLegacyAppleDocumentPlatformState final {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class RetainedWebPlatformServices final : public pp::platform::WebPlatformServices {
|
||||||
|
public:
|
||||||
|
void publish_exported_image(std::string_view path) override
|
||||||
|
{
|
||||||
|
(void)path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_persistent_storage() override
|
||||||
|
{
|
||||||
|
#ifdef __WEB__
|
||||||
|
webgl_sync();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] int default_canvas_resolution() override
|
||||||
|
{
|
||||||
|
return pp::platform::platform_default_canvas_resolution(pp::platform::PlatformFamily::webgl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void save_prepared_file(
|
||||||
|
std::string_view path,
|
||||||
|
std::string_view suggested_name,
|
||||||
|
pp::platform::PreparedFileCallback callback) override
|
||||||
|
{
|
||||||
|
const std::string value(path);
|
||||||
|
const std::string name(suggested_name);
|
||||||
|
#ifdef __WEB__
|
||||||
|
webgl_pick_file_save(value, name, [callback = std::move(callback), value](bool success) {
|
||||||
|
callback(value, success);
|
||||||
|
});
|
||||||
|
#else
|
||||||
|
(void)name;
|
||||||
|
callback(value, false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__LINUX__) || defined(__WEB__)
|
#if defined(__LINUX__) || defined(__WEB__)
|
||||||
@@ -254,6 +297,17 @@ active_legacy_apple_document_platform_services()
|
|||||||
return *retained.services;
|
return *retained.services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] pp::platform::PlatformStoragePaths prepare_legacy_apple_storage_paths()
|
||||||
|
{
|
||||||
|
const auto& apple_state = active_legacy_apple_state();
|
||||||
|
#ifdef __IOS__
|
||||||
|
[apple_state.ios_view init_dirs];
|
||||||
|
#elif defined(__OSX__)
|
||||||
|
[apple_state.osx_app init_dirs];
|
||||||
|
#endif
|
||||||
|
return active_legacy_storage_paths();
|
||||||
|
}
|
||||||
|
|
||||||
void set_legacy_apple_state(
|
void set_legacy_apple_state(
|
||||||
#ifdef __IOS__
|
#ifdef __IOS__
|
||||||
GameViewController* ios_view,
|
GameViewController* ios_view,
|
||||||
@@ -294,6 +348,12 @@ void set_legacy_apple_state(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
[[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services()
|
||||||
|
{
|
||||||
|
static RetainedWebPlatformServices services;
|
||||||
|
return pp::platform::resolve_web_platform_services(services);
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] const pp::platform::PlatformStoragePaths& active_legacy_storage_paths()
|
[[nodiscard]] const pp::platform::PlatformStoragePaths& active_legacy_storage_paths()
|
||||||
{
|
{
|
||||||
return retained_legacy_storage_paths().storage_paths;
|
return retained_legacy_storage_paths().storage_paths;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ struct RetainedLegacyAppleState final {
|
|||||||
[[nodiscard]] RetainedLegacyAppleState& active_legacy_apple_state();
|
[[nodiscard]] RetainedLegacyAppleState& active_legacy_apple_state();
|
||||||
[[nodiscard]] pp::platform::apple::AppleDocumentPlatformServices&
|
[[nodiscard]] pp::platform::apple::AppleDocumentPlatformServices&
|
||||||
active_legacy_apple_document_platform_services();
|
active_legacy_apple_document_platform_services();
|
||||||
|
[[nodiscard]] pp::platform::PlatformStoragePaths prepare_legacy_apple_storage_paths();
|
||||||
void set_legacy_apple_state(
|
void set_legacy_apple_state(
|
||||||
#ifdef __IOS__
|
#ifdef __IOS__
|
||||||
GameViewController* ios_view,
|
GameViewController* ios_view,
|
||||||
@@ -61,6 +62,8 @@ void set_legacy_apple_state(
|
|||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
[[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services();
|
||||||
|
|
||||||
[[nodiscard]] const pp::platform::PlatformStoragePaths& active_legacy_storage_paths();
|
[[nodiscard]] const pp::platform::PlatformStoragePaths& active_legacy_storage_paths();
|
||||||
void set_legacy_storage_paths(pp::platform::PlatformStoragePaths paths);
|
void set_legacy_storage_paths(pp::platform::PlatformStoragePaths paths);
|
||||||
|
|
||||||
|
|||||||
@@ -46,13 +46,17 @@ void request_window_close(HWND hWnd)
|
|||||||
|
|
||||||
void handle_window_close_message(VrShellState& vr)
|
void handle_window_close_message(VrShellState& vr)
|
||||||
{
|
{
|
||||||
|
auto* app = bound_app();
|
||||||
|
auto* runtime = bound_runtime();
|
||||||
mark_lifecycle_stopped();
|
mark_lifecycle_stopped();
|
||||||
request_stop_and_join_vr_thread(vr);
|
request_stop_and_join_vr_thread(vr);
|
||||||
App::I->runtime().ui_thread_stop();
|
runtime->ui_thread_stop();
|
||||||
App::I->runtime().render_thread_stop();
|
runtime->render_thread_stop();
|
||||||
App::I->terminate();
|
app->terminate();
|
||||||
|
App::I = nullptr;
|
||||||
|
bind_app(nullptr);
|
||||||
bind_runtime(nullptr);
|
bind_runtime(nullptr);
|
||||||
delete App::I;
|
delete app;
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace pp::platform::windows {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct RetainedWindowsRuntimeState final {
|
struct RetainedWindowsRuntimeState final {
|
||||||
|
App* app = nullptr;
|
||||||
AppRuntime* runtime = nullptr;
|
AppRuntime* runtime = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,9 +39,11 @@ void register_touch_window(HWND hWnd)
|
|||||||
|
|
||||||
void initialize_runtime_threads()
|
void initialize_runtime_threads()
|
||||||
{
|
{
|
||||||
|
auto* app = bound_app();
|
||||||
|
auto* runtime = bound_runtime();
|
||||||
mark_lifecycle_running();
|
mark_lifecycle_running();
|
||||||
App::I->runtime().render_thread_start(*App::I);
|
runtime->render_thread_start(*app);
|
||||||
App::I->runtime().ui_thread_start(*App::I);
|
runtime->ui_thread_start(*app);
|
||||||
}
|
}
|
||||||
|
|
||||||
void install_debug_gl_callbacks()
|
void install_debug_gl_callbacks()
|
||||||
@@ -85,10 +88,11 @@ void restore_window_placement(HWND hWnd, int show_command)
|
|||||||
void run_main_message_loop()
|
void run_main_message_loop()
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
auto* app = bound_app();
|
||||||
LOG("start main loop");
|
LOG("start main loop");
|
||||||
while (lifecycle_is_running())
|
while (lifecycle_is_running())
|
||||||
{
|
{
|
||||||
auto present = App::I->animate || App::I->redraw ?
|
auto present = app->animate || app->redraw ?
|
||||||
PeekMessage(&msg, 0, 0, 0, PM_REMOVE) : GetMessage(&msg, 0, 0, 0);
|
PeekMessage(&msg, 0, 0, 0, PM_REMOVE) : GetMessage(&msg, 0, 0, 0);
|
||||||
|
|
||||||
if (msg.message == WM_QUIT)
|
if (msg.message == WM_QUIT)
|
||||||
@@ -113,6 +117,16 @@ void shutdown_main_window_runtime(const MainWindowStartupState& startup, HINSTAN
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bind_app(App* app) noexcept
|
||||||
|
{
|
||||||
|
retained_runtime_state().app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
App* bound_app() noexcept
|
||||||
|
{
|
||||||
|
return retained_runtime_state().app;
|
||||||
|
}
|
||||||
|
|
||||||
void bind_runtime(AppRuntime* runtime) noexcept
|
void bind_runtime(AppRuntime* runtime) noexcept
|
||||||
{
|
{
|
||||||
retained_runtime_state().runtime = runtime;
|
retained_runtime_state().runtime = runtime;
|
||||||
@@ -128,10 +142,12 @@ int run_main_application(int argc, char** argv)
|
|||||||
auto& state = retained_state();
|
auto& state = retained_state();
|
||||||
state.hInst = GetModuleHandle(NULL);
|
state.hInst = GetModuleHandle(NULL);
|
||||||
|
|
||||||
App::I = new App();
|
auto* app = new App();
|
||||||
bind_runtime(&App::I->runtime());
|
App::I = app;
|
||||||
App::I->set_platform_services(&pp::platform::windows::platform_services());
|
bind_app(app);
|
||||||
App::I->initLog();
|
bind_runtime(&app->runtime());
|
||||||
|
app->set_platform_services(&pp::platform::windows::platform_services());
|
||||||
|
app->initLog();
|
||||||
|
|
||||||
pp::platform::windows::init_shcore_API();
|
pp::platform::windows::init_shcore_API();
|
||||||
pp::platform::windows::initialize_stylus_input();
|
pp::platform::windows::initialize_stylus_input();
|
||||||
@@ -149,7 +165,7 @@ int run_main_application(int argc, char** argv)
|
|||||||
|
|
||||||
pp::platform::windows::read_WMI_info();
|
pp::platform::windows::read_WMI_info();
|
||||||
|
|
||||||
App::I->create();
|
app->create();
|
||||||
|
|
||||||
auto startup = pp::platform::windows::initialize_main_window_startup_state();
|
auto startup = pp::platform::windows::initialize_main_window_startup_state();
|
||||||
auto context = pp::platform::windows::OpenGlWindowContext {};
|
auto context = pp::platform::windows::OpenGlWindowContext {};
|
||||||
@@ -158,9 +174,11 @@ int run_main_application(int argc, char** argv)
|
|||||||
case pp::platform::windows::MainStartupResult::Ok:
|
case pp::platform::windows::MainStartupResult::Ok:
|
||||||
break;
|
break;
|
||||||
case pp::platform::windows::MainStartupResult::GladLoadFailure:
|
case pp::platform::windows::MainStartupResult::GladLoadFailure:
|
||||||
|
bind_app(nullptr);
|
||||||
bind_runtime(nullptr);
|
bind_runtime(nullptr);
|
||||||
return 0;
|
return 0;
|
||||||
case pp::platform::windows::MainStartupResult::MissingCoreContextSupport:
|
case pp::platform::windows::MainStartupResult::MissingCoreContextSupport:
|
||||||
|
bind_app(nullptr);
|
||||||
bind_runtime(nullptr);
|
bind_runtime(nullptr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -173,8 +191,9 @@ int run_main_application(int argc, char** argv)
|
|||||||
switch (const_hash(argv[1]))
|
switch (const_hash(argv[1]))
|
||||||
{
|
{
|
||||||
case const_hash("convert"):
|
case const_hash("convert"):
|
||||||
App::I->initShaders();
|
app->initShaders();
|
||||||
App::I->cmd_convert(argv[2], argv[3]);
|
app->cmd_convert(argv[2], argv[3]);
|
||||||
|
bind_app(nullptr);
|
||||||
bind_runtime(nullptr);
|
bind_runtime(nullptr);
|
||||||
return 0;
|
return 0;
|
||||||
case const_hash("-vrmode"):
|
case const_hash("-vrmode"):
|
||||||
@@ -192,6 +211,7 @@ int run_main_application(int argc, char** argv)
|
|||||||
void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, SplashScreen& splash)
|
void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, SplashScreen& splash)
|
||||||
{
|
{
|
||||||
auto& state = retained_state();
|
auto& state = retained_state();
|
||||||
|
auto* app = bound_app();
|
||||||
register_touch_window(state.hWnd);
|
register_touch_window(state.hWnd);
|
||||||
|
|
||||||
wglMakeCurrent(NULL, NULL);
|
wglMakeCurrent(NULL, NULL);
|
||||||
@@ -201,11 +221,11 @@ void run_main_window_runtime(const MainWindowStartupState& startup, bool start_i
|
|||||||
initialize_wintab(state.hWnd, state.sandboxed);
|
initialize_wintab(state.hWnd, state.sandboxed);
|
||||||
set_main_window_icon(state.hWnd);
|
set_main_window_icon(state.hWnd);
|
||||||
|
|
||||||
App::I->ui_sync();
|
app->ui_sync();
|
||||||
restore_window_placement(state.hWnd, startup.show_command);
|
restore_window_placement(state.hWnd, startup.show_command);
|
||||||
|
|
||||||
if (start_in_vr)
|
if (start_in_vr)
|
||||||
App::I->vr_start();
|
app->vr_start();
|
||||||
|
|
||||||
LOG("show main window");
|
LOG("show main window");
|
||||||
SetForegroundWindow(state.hWnd);
|
SetForegroundWindow(state.hWnd);
|
||||||
|
|||||||
@@ -3,12 +3,15 @@
|
|||||||
#include "platform_windows/windows_bootstrap_helpers.h"
|
#include "platform_windows/windows_bootstrap_helpers.h"
|
||||||
#include "platform_windows/windows_splash.h"
|
#include "platform_windows/windows_splash.h"
|
||||||
|
|
||||||
|
class App;
|
||||||
class AppRuntime;
|
class AppRuntime;
|
||||||
|
|
||||||
namespace pp::platform::windows {
|
namespace pp::platform::windows {
|
||||||
|
|
||||||
int run_main_application(int argc, char** argv);
|
int run_main_application(int argc, char** argv);
|
||||||
void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, SplashScreen& splash);
|
void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, SplashScreen& splash);
|
||||||
|
void bind_app(App* app) noexcept;
|
||||||
|
[[nodiscard]] App* bound_app() noexcept;
|
||||||
void bind_runtime(AppRuntime* runtime) noexcept;
|
void bind_runtime(AppRuntime* runtime) noexcept;
|
||||||
[[nodiscard]] AppRuntime* bound_runtime() noexcept;
|
[[nodiscard]] AppRuntime* bound_runtime() noexcept;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "platform_windows/windows_runtime_shell.h"
|
||||||
#include "wacom.h"
|
#include "wacom.h"
|
||||||
|
|
||||||
namespace pp::platform::windows {
|
namespace pp::platform::windows {
|
||||||
@@ -53,6 +54,7 @@ void initialize_stylus_input()
|
|||||||
void update_stylus_state(float dt)
|
void update_stylus_state(float dt)
|
||||||
{
|
{
|
||||||
auto& state = stylus_input_state();
|
auto& state = stylus_input_state();
|
||||||
|
auto* app = bound_app();
|
||||||
state.timer_stylus += dt;
|
state.timer_stylus += dt;
|
||||||
state.timer_ink_touch += dt;
|
state.timer_ink_touch += dt;
|
||||||
state.timer_ink_pen += dt;
|
state.timer_ink_pen += dt;
|
||||||
@@ -61,24 +63,24 @@ void update_stylus_state(float dt)
|
|||||||
{
|
{
|
||||||
WacomTablet::I.m_stylus = false;
|
WacomTablet::I.m_stylus = false;
|
||||||
WacomTablet::I.m_eraser = false;
|
WacomTablet::I.m_eraser = false;
|
||||||
App::I->redraw = true;
|
app->redraw = true;
|
||||||
}
|
}
|
||||||
if (state.timer_ink_pen > 0.1f && WacomTablet::I.m_ink_pen)
|
if (state.timer_ink_pen > 0.1f && WacomTablet::I.m_ink_pen)
|
||||||
{
|
{
|
||||||
WacomTablet::I.m_ink_pen = false;
|
WacomTablet::I.m_ink_pen = false;
|
||||||
App::I->redraw = true;
|
app->redraw = true;
|
||||||
}
|
}
|
||||||
if (state.timer_ink_touch > 0.1f && WacomTablet::I.m_ink_touch)
|
if (state.timer_ink_touch > 0.1f && WacomTablet::I.m_ink_touch)
|
||||||
{
|
{
|
||||||
WacomTablet::I.m_ink_touch = false;
|
WacomTablet::I.m_ink_touch = false;
|
||||||
App::I->redraw = true;
|
app->redraw = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void note_wintab_packet()
|
void note_wintab_packet()
|
||||||
{
|
{
|
||||||
auto& state = stylus_input_state();
|
auto& state = stylus_input_state();
|
||||||
App::I->set_stylus();
|
bound_app()->set_stylus();
|
||||||
state.timer_stylus = 0.0f;
|
state.timer_stylus = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +120,7 @@ void handle_pointer_update_message(WPARAM wp)
|
|||||||
state.timer_ink_pen = 0.0f;
|
state.timer_ink_pen = 0.0f;
|
||||||
WacomTablet::I.m_ink_pen = true;
|
WacomTablet::I.m_ink_pen = true;
|
||||||
WacomTablet::I.m_pen_pres = static_cast<float>(pen_info.pressure) / 1024.0f;
|
WacomTablet::I.m_pen_pres = static_cast<float>(pen_info.pressure) / 1024.0f;
|
||||||
App::I->set_stylus();
|
bound_app()->set_stylus();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
namespace pp::platform::windows {
|
namespace pp::platform::windows {
|
||||||
|
|
||||||
|
[[nodiscard]] App* bound_app() noexcept;
|
||||||
|
|
||||||
struct VrShellState final {
|
struct VrShellState final {
|
||||||
std::mutex snapshot_mutex;
|
std::mutex snapshot_mutex;
|
||||||
VrSessionSnapshot session;
|
VrSessionSnapshot session;
|
||||||
@@ -72,9 +74,10 @@ inline bool start_vr_shell(VrShellState& state, bool sandboxed, std::atomic<int>
|
|||||||
if (sandboxed)
|
if (sandboxed)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
auto* app = bound_app();
|
||||||
state.vive = std::make_unique<Vive>();
|
state.vive = std::make_unique<Vive>();
|
||||||
state.vive->on_draw = [](const glm::mat4& proj, const glm::mat4& view, const glm::mat4& pose) {
|
state.vive->on_draw = [app](const glm::mat4& proj, const glm::mat4& view, const glm::mat4& pose) {
|
||||||
App::I->vr_draw(proj, view, pose);
|
app->vr_draw(proj, view, pose);
|
||||||
};
|
};
|
||||||
if (!state.vive->Initialize())
|
if (!state.vive->Initialize())
|
||||||
{
|
{
|
||||||
@@ -89,7 +92,7 @@ inline bool start_vr_shell(VrShellState& state, bool sandboxed, std::atomic<int>
|
|||||||
state.hmd_renderer.join();
|
state.hmd_renderer.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
state.hmd_renderer = std::jthread([&state, &running](std::stop_token stop_token) {
|
state.hmd_renderer = std::jthread([app, &state, &running](std::stop_token stop_token) {
|
||||||
if (!state.vive)
|
if (!state.vive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -98,13 +101,13 @@ inline bool start_vr_shell(VrShellState& state, bool sandboxed, std::atomic<int>
|
|||||||
clear_vr_session_snapshot(state, true);
|
clear_vr_session_snapshot(state, true);
|
||||||
state.vr_running.store(true, std::memory_order_relaxed);
|
state.vr_running.store(true, std::memory_order_relaxed);
|
||||||
|
|
||||||
state.vive->on_analog_button = std::bind(&App::vr_analog, App::I, std::placeholders::_1,
|
state.vive->on_analog_button = std::bind(&App::vr_analog, app, std::placeholders::_1,
|
||||||
std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
|
std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
|
||||||
state.vive->on_button = std::bind(&App::vr_digital, App::I, std::placeholders::_1,
|
state.vive->on_button = std::bind(&App::vr_digital, app, std::placeholders::_1,
|
||||||
std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
|
std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
|
||||||
|
|
||||||
App::I->render_task([] {
|
app->render_task([app] {
|
||||||
App::I->vr_draw_ui();
|
app->vr_draw_ui();
|
||||||
});
|
});
|
||||||
|
|
||||||
const float target_tick_rate = 90;
|
const float target_tick_rate = 90;
|
||||||
@@ -136,11 +139,11 @@ inline bool start_vr_shell(VrShellState& state, bool sandboxed, std::atomic<int>
|
|||||||
state.vive->m_active,
|
state.vive->m_active,
|
||||||
state.vive->m_controllers[0],
|
state.vive->m_controllers[0],
|
||||||
state.vive->m_pose);
|
state.vive->m_pose);
|
||||||
App::I->vr_update(dt);
|
app->vr_update(dt);
|
||||||
|
|
||||||
if (state.vr_running.load(std::memory_order_relaxed) && state.vive->m_active)
|
if (state.vr_running.load(std::memory_order_relaxed) && state.vive->m_active)
|
||||||
{
|
{
|
||||||
App::I->render_task([&state] {
|
app->render_task([&state] {
|
||||||
state.vive->Draw();
|
state.vive->Draw();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "platform_windows/windows_lifecycle_shell.h"
|
#include "platform_windows/windows_lifecycle_shell.h"
|
||||||
#include "platform_windows/windows_platform_services.h"
|
#include "platform_windows/windows_platform_services.h"
|
||||||
|
#include "platform_windows/windows_runtime_shell.h"
|
||||||
#include "platform_windows/windows_stylus_input.h"
|
#include "platform_windows/windows_stylus_input.h"
|
||||||
#include "keymap.h"
|
#include "keymap.h"
|
||||||
#include "wacom.h"
|
#include "wacom.h"
|
||||||
@@ -47,6 +48,7 @@ RetainedState& retained_state()
|
|||||||
LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||||
{
|
{
|
||||||
auto& state = retained_state();
|
auto& state = retained_state();
|
||||||
|
auto* app = bound_app();
|
||||||
static glm::vec2 lastPoint;
|
static glm::vec2 lastPoint;
|
||||||
|
|
||||||
auto extra = GetMessageExtraInfo();
|
auto extra = GetMessageExtraInfo();
|
||||||
@@ -57,15 +59,15 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
handle_window_close_message(state.vr);
|
handle_window_close_message(state.vr);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
App::I->redraw = true;
|
app->redraw = true;
|
||||||
break;
|
break;
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
BT_SetTerminate();
|
BT_SetTerminate();
|
||||||
break;
|
break;
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
{
|
{
|
||||||
App::I->ui_task_async([] {
|
app->ui_task_async([app] {
|
||||||
if (App::I->request_close())
|
if (app->request_close())
|
||||||
{
|
{
|
||||||
destroy_window();
|
destroy_window();
|
||||||
}
|
}
|
||||||
@@ -79,10 +81,10 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
auto h = (float)HIWORD(lp);
|
auto h = (float)HIWORD(lp);
|
||||||
if (h != 0 && lifecycle_is_running())
|
if (h != 0 && lifecycle_is_running())
|
||||||
{
|
{
|
||||||
App::I->ui_task_async([=]
|
app->ui_task_async([app, w, h]
|
||||||
{
|
{
|
||||||
App::I->resize(w, h);
|
app->resize(w, h);
|
||||||
App::I->redraw = true;
|
app->redraw = true;
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -90,7 +92,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
case WM_ACTIVATE:
|
case WM_ACTIVATE:
|
||||||
{
|
{
|
||||||
platform_services().set_cursor_visible(true);
|
platform_services().set_cursor_visible(true);
|
||||||
App::I->ui_task_async([&state, wp, lp] {
|
app->ui_task_async([app, &state, wp, lp] {
|
||||||
int active = GET_WM_ACTIVATE_STATE(wp, lp);
|
int active = GET_WM_ACTIVATE_STATE(wp, lp);
|
||||||
WacomTablet::I.set_focus(active);
|
WacomTablet::I.set_focus(active);
|
||||||
static BYTE keys[256];
|
static BYTE keys[256];
|
||||||
@@ -102,10 +104,10 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
if (alt && k.first == kKey::KeyTab)
|
if (alt && k.first == kKey::KeyTab)
|
||||||
continue;
|
continue;
|
||||||
bool down = keys[k.second] & 0x80;
|
bool down = keys[k.second] & 0x80;
|
||||||
if (App::I->keys[(int)k.first] && !down)
|
if (app->keys[(int)k.first] && !down)
|
||||||
App::I->key_up(k.first);
|
app->key_up(k.first);
|
||||||
else if (!App::I->keys[(int)k.first] && down)
|
else if (!app->keys[(int)k.first] && down)
|
||||||
App::I->key_down(k.first);
|
app->key_down(k.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -114,7 +116,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
case WT_PACKET:
|
case WT_PACKET:
|
||||||
{
|
{
|
||||||
note_wintab_packet();
|
note_wintab_packet();
|
||||||
App::I->ui_task_async([=] {
|
app->ui_task_async([=] {
|
||||||
WacomTablet::I.handle_message(hWnd, msg, wp, lp);
|
WacomTablet::I.handle_message(hWnd, msg, wp, lp);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -122,32 +124,32 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
case WM_SYSKEYDOWN:
|
case WM_SYSKEYDOWN:
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
if ((lp >> 30 & 1) == 0 &&
|
if ((lp >> 30 & 1) == 0 &&
|
||||||
!(wp == VK_TAB && App::I->keys[(int)kKey::KeyAlt]))
|
!(wp == VK_TAB && app->keys[(int)kKey::KeyAlt]))
|
||||||
{
|
{
|
||||||
App::I->ui_task_async([wp] {
|
app->ui_task_async([app, wp] {
|
||||||
App::I->key_down(convert_key((int)wp));
|
app->key_down(convert_key((int)wp));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WM_SYSKEYUP:
|
case WM_SYSKEYUP:
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
if (!(wp == VK_TAB && App::I->keys[(int)kKey::KeyAlt]))
|
if (!(wp == VK_TAB && app->keys[(int)kKey::KeyAlt]))
|
||||||
{
|
{
|
||||||
App::I->ui_task_async([wp] {
|
app->ui_task_async([app, wp] {
|
||||||
App::I->key_up(convert_key((int)wp));
|
app->key_up(convert_key((int)wp));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
App::I->ui_task_async([wp] {
|
app->ui_task_async([app, wp] {
|
||||||
App::I->key_char((int)wp);
|
app->key_char((int)wp);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
lastPoint = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
|
lastPoint = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
|
||||||
{
|
{
|
||||||
auto pt = lastPoint;
|
auto pt = lastPoint;
|
||||||
App::I->ui_task_async([pt, extra, p = WacomTablet::I.get_pressure()] {
|
app->ui_task_async([app, pt, extra, p = WacomTablet::I.get_pressure()] {
|
||||||
kEventSource pointer_source;
|
kEventSource pointer_source;
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
{
|
{
|
||||||
@@ -159,7 +161,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
||||||
pointer_source = kEventSource::Touch;
|
pointer_source = kEventSource::Touch;
|
||||||
}
|
}
|
||||||
App::I->mouse_move((float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser);
|
app->mouse_move((float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -167,7 +169,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
{
|
{
|
||||||
SetCapture(hWnd);
|
SetCapture(hWnd);
|
||||||
auto pt = lastPoint;
|
auto pt = lastPoint;
|
||||||
App::I->ui_task_async([pt, extra, hWnd, p = WacomTablet::I.get_pressure()] {
|
app->ui_task_async([app, pt, extra, p = WacomTablet::I.get_pressure()] {
|
||||||
kEventSource pointer_source;
|
kEventSource pointer_source;
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
{
|
{
|
||||||
@@ -179,7 +181,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
||||||
pointer_source = kEventSource::Touch;
|
pointer_source = kEventSource::Touch;
|
||||||
}
|
}
|
||||||
App::I->mouse_down(0, (float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser);
|
app->mouse_down(0, (float)pt.x, (float)pt.y, p, pointer_source, WacomTablet::I.m_eraser);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -187,7 +189,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
{
|
{
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
auto pt = lastPoint;
|
auto pt = lastPoint;
|
||||||
App::I->ui_task_async([pt, extra] {
|
app->ui_task_async([app, pt, extra] {
|
||||||
WacomTablet::I.reset_pressure();
|
WacomTablet::I.reset_pressure();
|
||||||
kEventSource pointer_source;
|
kEventSource pointer_source;
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
@@ -200,7 +202,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
||||||
pointer_source = kEventSource::Touch;
|
pointer_source = kEventSource::Touch;
|
||||||
}
|
}
|
||||||
App::I->mouse_up(0, (float)pt.x, (float)pt.y, pointer_source, WacomTablet::I.m_eraser);
|
app->mouse_up(0, (float)pt.x, (float)pt.y, pointer_source, WacomTablet::I.m_eraser);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -208,7 +210,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
{
|
{
|
||||||
SetCapture(hWnd);
|
SetCapture(hWnd);
|
||||||
auto pt = lastPoint;
|
auto pt = lastPoint;
|
||||||
App::I->ui_task_async([pt, extra, hWnd] {
|
app->ui_task_async([app, pt, extra] {
|
||||||
kEventSource pointer_source;
|
kEventSource pointer_source;
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
{
|
{
|
||||||
@@ -220,7 +222,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
||||||
pointer_source = kEventSource::Touch;
|
pointer_source = kEventSource::Touch;
|
||||||
}
|
}
|
||||||
App::I->mouse_down(1, (float)pt.x, (float)pt.y, 1.f, pointer_source, 0);
|
app->mouse_down(1, (float)pt.x, (float)pt.y, 1.f, pointer_source, 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -228,7 +230,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
{
|
{
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
auto pt = lastPoint;
|
auto pt = lastPoint;
|
||||||
App::I->ui_task_async([pt, extra] {
|
app->ui_task_async([app, pt, extra] {
|
||||||
kEventSource pointer_source;
|
kEventSource pointer_source;
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
{
|
{
|
||||||
@@ -240,7 +242,7 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
if ((extra & 0xFFFFFF00) == 0xFF515700)
|
||||||
pointer_source = kEventSource::Touch;
|
pointer_source = kEventSource::Touch;
|
||||||
}
|
}
|
||||||
App::I->mouse_up(1, (float)pt.x, (float)pt.y, pointer_source, 0);
|
app->mouse_up(1, (float)pt.x, (float)pt.y, pointer_source, 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -250,8 +252,8 @@ LRESULT CALLBACK main_window_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
pt.x = GET_X_LPARAM(lp);
|
pt.x = GET_X_LPARAM(lp);
|
||||||
pt.y = GET_Y_LPARAM(lp);
|
pt.y = GET_Y_LPARAM(lp);
|
||||||
ScreenToClient(hWnd, &pt);
|
ScreenToClient(hWnd, &pt);
|
||||||
App::I->ui_task_async([pt, wp] {
|
app->ui_task_async([app, pt, wp] {
|
||||||
App::I->mouse_scroll((float)pt.x, (float)pt.y,
|
app->mouse_scroll((float)pt.x, (float)pt.y,
|
||||||
(float)GET_WHEEL_DELTA_WPARAM(wp) / (float)WHEEL_DELTA);
|
(float)GET_WHEEL_DELTA_WPARAM(wp) / (float)WHEEL_DELTA);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user