// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "flutter/shell/platform/windows/public/flutter_windows.h" #include #include #include #include #include #include #include #include #include #include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/common/cpp/incoming_message_dispatcher.h" #include "flutter/shell/platform/common/cpp/path_utils.h" #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/windows/flutter_project_bundle.h" #include "flutter/shell/platform/windows/flutter_windows_engine.h" #include "flutter/shell/platform/windows/flutter_windows_view.h" #include "flutter/shell/platform/windows/win32_dpi_utils.h" #include "flutter/shell/platform/windows/win32_flutter_window.h" #include "flutter/shell/platform/windows/win32_task_runner.h" #include "flutter/shell/platform/windows/window_binding_handler.h" #include "flutter/shell/platform/windows/window_state.h" static_assert(FLUTTER_ENGINE_VERSION == 1, ""); // Returns the engine corresponding to the given opaque API handle. static flutter::FlutterWindowsEngine* EngineFromHandle( FlutterDesktopEngineRef ref) { return reinterpret_cast(ref); } // Returns the opaque API handle for the given engine instance. static FlutterDesktopEngineRef HandleForEngine( flutter::FlutterWindowsEngine* engine) { return reinterpret_cast(engine); } // Returns the view corresponding to the given opaque API handle. static flutter::FlutterWindowsView* ViewFromHandle(FlutterDesktopViewRef ref) { return reinterpret_cast(ref); } // Returns the opaque API handle for the given view instance. static FlutterDesktopViewRef HandleForView(flutter::FlutterWindowsView* view) { return reinterpret_cast(view); } FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate( int width, int height, FlutterDesktopEngineRef engine) { std::unique_ptr window_wrapper = std::make_unique(width, height); auto state = std::make_unique(); state->view = std::make_unique(std::move(window_wrapper)); state->view->CreateRenderSurface(); // Take ownership of the engine, starting it if necessary. state->view->SetEngine( std::unique_ptr(EngineFromHandle(engine))); if (!state->view->GetEngine()->running()) { if (!state->view->GetEngine()->RunWithEntrypoint(nullptr)) { return nullptr; } } // Must happen after engine is running. state->view->SendInitialBounds(); return state.release(); } void FlutterDesktopViewControllerDestroy( FlutterDesktopViewControllerRef controller) { delete controller; } FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine( FlutterDesktopViewControllerRef controller) { return HandleForEngine(controller->view->GetEngine()); } FlutterDesktopViewRef FlutterDesktopViewControllerGetView( FlutterDesktopViewControllerRef controller) { return HandleForView(controller->view.get()); } bool FlutterDesktopViewControllerHandleTopLevelWindowProc( FlutterDesktopViewControllerRef controller, HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result) { std::optional delegate_result = controller->view->GetEngine() ->window_proc_delegate_manager() ->OnTopLevelWindowProc(hwnd, message, wparam, lparam); if (delegate_result) { *result = *delegate_result; } return delegate_result.has_value(); } FlutterDesktopEngineRef FlutterDesktopEngineCreate( const FlutterDesktopEngineProperties& engine_properties) { flutter::FlutterProjectBundle project(engine_properties); auto engine = std::make_unique(project); return HandleForEngine(engine.release()); } bool FlutterDesktopEngineDestroy(FlutterDesktopEngineRef engine_ref) { flutter::FlutterWindowsEngine* engine = EngineFromHandle(engine_ref); bool result = true; if (engine->running()) { result = engine->Stop(); } delete engine; return result; } bool FlutterDesktopEngineRun(FlutterDesktopEngineRef engine, const char* entry_point) { return EngineFromHandle(engine)->RunWithEntrypoint(entry_point); } uint64_t FlutterDesktopEngineProcessMessages(FlutterDesktopEngineRef engine) { return EngineFromHandle(engine)->task_runner()->ProcessTasks().count(); } void FlutterDesktopEngineReloadSystemFonts(FlutterDesktopEngineRef engine) { EngineFromHandle(engine)->ReloadSystemFonts(); } FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar( FlutterDesktopEngineRef engine, const char* plugin_name) { // Currently, one registrar acts as the registrar for all plugins, so the // name is ignored. It is part of the API to reduce churn in the future when // aligning more closely with the Flutter registrar system. return EngineFromHandle(engine)->GetRegistrar(); } FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger( FlutterDesktopEngineRef engine) { return EngineFromHandle(engine)->messenger(); } HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view) { return std::get(*ViewFromHandle(view)->GetRenderTarget()); } FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView( FlutterDesktopPluginRegistrarRef registrar) { return HandleForView(registrar->engine->view()); } void FlutterDesktopPluginRegistrarRegisterTopLevelWindowProcDelegate( FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopWindowProcCallback delegate, void* user_data) { registrar->engine->window_proc_delegate_manager() ->RegisterTopLevelWindowProcDelegate(delegate, user_data); } void FlutterDesktopPluginRegistrarUnregisterTopLevelWindowProcDelegate( FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopWindowProcCallback delegate) { registrar->engine->window_proc_delegate_manager() ->UnregisterTopLevelWindowProcDelegate(delegate); } UINT FlutterDesktopGetDpiForHWND(HWND hwnd) { return flutter::GetDpiForHWND(hwnd); } UINT FlutterDesktopGetDpiForMonitor(HMONITOR monitor) { return flutter::GetDpiForMonitor(monitor); } void FlutterDesktopResyncOutputStreams() { FILE* unused; if (freopen_s(&unused, "CONOUT$", "w", stdout)) { _dup2(_fileno(stdout), 1); } if (freopen_s(&unused, "CONOUT$", "w", stderr)) { _dup2(_fileno(stdout), 2); } std::ios::sync_with_stdio(); } // Implementations of common/cpp/ API methods. FlutterDesktopMessengerRef FlutterDesktopPluginRegistrarGetMessenger( FlutterDesktopPluginRegistrarRef registrar) { return registrar->engine->messenger(); } void FlutterDesktopPluginRegistrarSetDestructionHandler( FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopOnPluginRegistrarDestroyed callback) { registrar->engine->SetPluginRegistrarDestructionCallback(callback); } bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger, const char* channel, const uint8_t* message, const size_t message_size, const FlutterDesktopBinaryReply reply, void* user_data) { return messenger->engine->SendPlatformMessage(channel, message, message_size, reply, user_data); } bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, const char* channel, const uint8_t* message, const size_t message_size) { return FlutterDesktopMessengerSendWithReply(messenger, channel, message, message_size, nullptr, nullptr); } void FlutterDesktopMessengerSendResponse( FlutterDesktopMessengerRef messenger, const FlutterDesktopMessageResponseHandle* handle, const uint8_t* data, size_t data_length) { messenger->engine->SendPlatformMessageResponse(handle, data, data_length); } void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, const char* channel, FlutterDesktopMessageCallback callback, void* user_data) { messenger->engine->message_dispatcher()->SetMessageCallback(channel, callback, user_data); }