| // 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 <io.h> |
| |
| #include <algorithm> |
| #include <cassert> |
| #include <chrono> |
| #include <cstdlib> |
| #include <filesystem> |
| #include <iostream> |
| #include <memory> |
| #include <vector> |
| |
| #include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h" |
| #include "flutter/shell/platform/common/incoming_message_dispatcher.h" |
| #include "flutter/shell/platform/common/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/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<flutter::FlutterWindowsEngine*>(ref); |
| } |
| |
| // Returns the opaque API handle for the given engine instance. |
| static FlutterDesktopEngineRef HandleForEngine( |
| flutter::FlutterWindowsEngine* engine) { |
| return reinterpret_cast<FlutterDesktopEngineRef>(engine); |
| } |
| |
| // Returns the view corresponding to the given opaque API handle. |
| static flutter::FlutterWindowsView* ViewFromHandle(FlutterDesktopViewRef ref) { |
| return reinterpret_cast<flutter::FlutterWindowsView*>(ref); |
| } |
| |
| // Returns the opaque API handle for the given view instance. |
| static FlutterDesktopViewRef HandleForView(flutter::FlutterWindowsView* view) { |
| return reinterpret_cast<FlutterDesktopViewRef>(view); |
| } |
| |
| // Returns the texture registrar corresponding to the given opaque API handle. |
| static flutter::FlutterWindowsTextureRegistrar* TextureRegistrarFromHandle( |
| FlutterDesktopTextureRegistrarRef ref) { |
| return reinterpret_cast<flutter::FlutterWindowsTextureRegistrar*>(ref); |
| } |
| |
| // Returns the opaque API handle for the given texture registrar instance. |
| static FlutterDesktopTextureRegistrarRef HandleForTextureRegistrar( |
| flutter::FlutterWindowsTextureRegistrar* registrar) { |
| return reinterpret_cast<FlutterDesktopTextureRegistrarRef>(registrar); |
| } |
| |
| void FlutterDesktopViewControllerDestroy( |
| FlutterDesktopViewControllerRef controller) { |
| delete controller; |
| } |
| |
| FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine( |
| FlutterDesktopViewControllerRef controller) { |
| return HandleForEngine(controller->view->GetEngine()); |
| } |
| |
| FlutterDesktopViewRef FlutterDesktopViewControllerGetView( |
| FlutterDesktopViewControllerRef controller) { |
| return HandleForView(controller->view.get()); |
| } |
| |
| void FlutterDesktopViewControllerForceRedraw( |
| FlutterDesktopViewControllerRef controller) { |
| controller->view->ForceRedraw(); |
| } |
| |
| FlutterDesktopEngineRef FlutterDesktopEngineCreate( |
| const FlutterDesktopEngineProperties* engine_properties) { |
| flutter::FlutterProjectBundle project(*engine_properties); |
| auto engine = std::make_unique<flutter::FlutterWindowsEngine>(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); |
| } |
| |
| 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(); |
| } |
| |
| FlutterDesktopTextureRegistrarRef FlutterDesktopEngineGetTextureRegistrar( |
| FlutterDesktopEngineRef engine) { |
| return HandleForTextureRegistrar( |
| EngineFromHandle(engine)->texture_registrar()); |
| } |
| |
| HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view) { |
| return ViewFromHandle(view)->GetPlatformWindow(); |
| } |
| |
| FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView( |
| FlutterDesktopPluginRegistrarRef registrar) { |
| return HandleForView(registrar->engine->view()); |
| } |
| |
| 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/ API methods. |
| |
| FlutterDesktopMessengerRef FlutterDesktopPluginRegistrarGetMessenger( |
| FlutterDesktopPluginRegistrarRef registrar) { |
| return registrar->engine->messenger(); |
| } |
| |
| void FlutterDesktopPluginRegistrarSetDestructionHandler( |
| FlutterDesktopPluginRegistrarRef registrar, |
| FlutterDesktopOnPluginRegistrarDestroyed callback) { |
| registrar->engine->AddPluginRegistrarDestructionCallback(callback, registrar); |
| } |
| |
| 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); |
| } |
| |
| FlutterDesktopTextureRegistrarRef FlutterDesktopRegistrarGetTextureRegistrar( |
| FlutterDesktopPluginRegistrarRef registrar) { |
| return HandleForTextureRegistrar(registrar->engine->texture_registrar()); |
| } |
| |
| int64_t FlutterDesktopTextureRegistrarRegisterExternalTexture( |
| FlutterDesktopTextureRegistrarRef texture_registrar, |
| const FlutterDesktopTextureInfo* texture_info) { |
| return TextureRegistrarFromHandle(texture_registrar) |
| ->RegisterTexture(texture_info); |
| } |
| |
| bool FlutterDesktopTextureRegistrarUnregisterExternalTexture( |
| FlutterDesktopTextureRegistrarRef texture_registrar, |
| int64_t texture_id) { |
| return TextureRegistrarFromHandle(texture_registrar) |
| ->UnregisterTexture(texture_id); |
| } |
| |
| bool FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable( |
| FlutterDesktopTextureRegistrarRef texture_registrar, |
| int64_t texture_id) { |
| return TextureRegistrarFromHandle(texture_registrar) |
| ->MarkTextureFrameAvailable(texture_id); |
| } |