Flutter Engine
flutter_windows.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/shell/platform/windows/public/flutter_windows.h"
6 
7 #include <io.h>
8 
9 #include <algorithm>
10 #include <cassert>
11 #include <chrono>
12 #include <cstdlib>
13 #include <filesystem>
14 #include <iostream>
15 #include <memory>
16 #include <vector>
17 
18 #include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h"
19 #include "flutter/shell/platform/common/cpp/incoming_message_dispatcher.h"
20 #include "flutter/shell/platform/common/cpp/path_utils.h"
21 #include "flutter/shell/platform/embedder/embedder.h"
22 #include "flutter/shell/platform/windows/flutter_project_bundle.h"
23 #include "flutter/shell/platform/windows/flutter_windows_engine.h"
24 #include "flutter/shell/platform/windows/flutter_windows_view.h"
25 #include "flutter/shell/platform/windows/win32_dpi_utils.h"
26 #include "flutter/shell/platform/windows/win32_flutter_window.h"
27 #include "flutter/shell/platform/windows/win32_task_runner.h"
28 #include "flutter/shell/platform/windows/window_binding_handler.h"
29 #include "flutter/shell/platform/windows/window_state.h"
30 
31 static_assert(FLUTTER_ENGINE_VERSION == 1, "");
32 
33 // Returns the engine corresponding to the given opaque API handle.
36  return reinterpret_cast<flutter::FlutterWindowsEngine*>(ref);
37 }
38 
39 // Returns the opaque API handle for the given engine instance.
42  return reinterpret_cast<FlutterDesktopEngineRef>(engine);
43 }
44 
45 // Returns the view corresponding to the given opaque API handle.
47  return reinterpret_cast<flutter::FlutterWindowsView*>(ref);
48 }
49 
50 // Returns the opaque API handle for the given view instance.
52  return reinterpret_cast<FlutterDesktopViewRef>(view);
53 }
54 
56  int width,
57  int height,
59  std::unique_ptr<flutter::WindowBindingHandler> window_wrapper =
60  std::make_unique<flutter::Win32FlutterWindow>(width, height);
61 
62  auto state = std::make_unique<FlutterDesktopViewControllerState>();
63  state->view =
64  std::make_unique<flutter::FlutterWindowsView>(std::move(window_wrapper));
65  state->view->CreateRenderSurface();
66 
67  // Take ownership of the engine, starting it if necessary.
68  state->view->SetEngine(
69  std::unique_ptr<flutter::FlutterWindowsEngine>(EngineFromHandle(engine)));
70  if (!state->view->GetEngine()->running()) {
71  if (!state->view->GetEngine()->RunWithEntrypoint(nullptr)) {
72  return nullptr;
73  }
74  }
75 
76  // Must happen after engine is running.
77  state->view->SendInitialBounds();
78  return state.release();
79 }
80 
83  delete controller;
84 }
85 
88  return HandleForEngine(controller->view->GetEngine());
89 }
90 
93  return HandleForView(controller->view.get());
94 }
95 
98  HWND hwnd,
99  UINT message,
100  WPARAM wparam,
101  LPARAM lparam,
102  LRESULT* result) {
103  std::optional<LRESULT> delegate_result =
104  controller->view->GetEngine()
105  ->window_proc_delegate_manager()
106  ->OnTopLevelWindowProc(hwnd, message, wparam, lparam);
107  if (delegate_result) {
108  *result = *delegate_result;
109  }
110  return delegate_result.has_value();
111 }
112 
114  const FlutterDesktopEngineProperties& engine_properties) {
115  flutter::FlutterProjectBundle project(engine_properties);
116  auto engine = std::make_unique<flutter::FlutterWindowsEngine>(project);
117  return HandleForEngine(engine.release());
118 }
119 
122  bool result = true;
123  if (engine->running()) {
124  result = engine->Stop();
125  }
126  delete engine;
127  return result;
128 }
129 
131  const char* entry_point) {
132  return EngineFromHandle(engine)->RunWithEntrypoint(entry_point);
133 }
134 
136  return EngineFromHandle(engine)->task_runner()->ProcessTasks().count();
137 }
138 
141 }
142 
145  const char* plugin_name) {
146  // Currently, one registrar acts as the registrar for all plugins, so the
147  // name is ignored. It is part of the API to reduce churn in the future when
148  // aligning more closely with the Flutter registrar system.
149 
150  return EngineFromHandle(engine)->GetRegistrar();
151 }
152 
155  return EngineFromHandle(engine)->messenger();
156 }
157 
159  return std::get<HWND>(*ViewFromHandle(view)->GetRenderTarget());
160 }
161 
164  return HandleForView(registrar->engine->view());
165 }
166 
170  void* user_data) {
171  registrar->engine->window_proc_delegate_manager()
172  ->RegisterTopLevelWindowProcDelegate(delegate, user_data);
173 }
174 
178  registrar->engine->window_proc_delegate_manager()
179  ->UnregisterTopLevelWindowProcDelegate(delegate);
180 }
181 
183  return flutter::GetDpiForHWND(hwnd);
184 }
185 
186 UINT FlutterDesktopGetDpiForMonitor(HMONITOR monitor) {
187  return flutter::GetDpiForMonitor(monitor);
188 }
189 
191  FILE* unused;
192  if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
193  _dup2(_fileno(stdout), 1);
194  }
195  if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
196  _dup2(_fileno(stdout), 2);
197  }
198  std::ios::sync_with_stdio();
199 }
200 
201 // Implementations of common/cpp/ API methods.
202 
205  return registrar->engine->messenger();
206 }
207 
211  registrar->engine->SetPluginRegistrarDestructionCallback(callback);
212 }
213 
215  const char* channel,
216  const uint8_t* message,
217  const size_t message_size,
218  const FlutterDesktopBinaryReply reply,
219  void* user_data) {
220  FlutterPlatformMessageResponseHandle* response_handle = nullptr;
221  if (reply != nullptr && user_data != nullptr) {
223  messenger->engine->engine(), reply, user_data, &response_handle);
224  if (result != kSuccess) {
225  std::cout << "Failed to create response handle\n";
226  return false;
227  }
228  }
229 
230  FlutterPlatformMessage platform_message = {
231  sizeof(FlutterPlatformMessage),
232  channel,
233  message,
234  message_size,
235  response_handle,
236  };
237 
239  messenger->engine->engine(), &platform_message);
240 
241  if (response_handle != nullptr) {
243  response_handle);
244  }
245 
246  return message_result == kSuccess;
247 }
248 
250  const char* channel,
251  const uint8_t* message,
252  const size_t message_size) {
253  return FlutterDesktopMessengerSendWithReply(messenger, channel, message,
254  message_size, nullptr, nullptr);
255 }
256 
258  FlutterDesktopMessengerRef messenger,
260  const uint8_t* data,
261  size_t data_length) {
262  FlutterEngineSendPlatformMessageResponse(messenger->engine->engine(), handle,
263  data, data_length);
264 }
265 
267  const char* channel,
269  void* user_data) {
270  messenger->engine->message_dispatcher()->SetMessageCallback(channel, callback,
271  user_data);
272 }
void FlutterDesktopPluginRegistrarUnregisterTopLevelWindowProcDelegate(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopWindowProcCallback delegate)
bool FlutterDesktopViewControllerHandleTopLevelWindowProc(FlutterDesktopViewControllerRef controller, HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, LRESULT *result)
UINT GetDpiForMonitor(HMONITOR monitor)
FlutterEngineResult FlutterPlatformMessageReleaseResponseHandle(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterPlatformMessageResponseHandle *response)
Collects the handle created using FlutterPlatformMessageCreateResponseHandle.
Definition: embedder.cc:1483
UINT GetDpiForHWND(HWND hwnd)
std::unique_ptr< flutter::IncomingMessageDispatcher > message_dispatcher
FlutterEngineResult FlutterEngineSendPlatformMessageResponse(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPlatformMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
Send a response from the native side to a platform message from the Dart Flutter application.
Definition: embedder.cc:1497
std::unique_ptr< flutter::FlutterWindowsView > view
Definition: window_state.h:26
FlutterDesktopEngineRef FlutterDesktopEngineCreate(const FlutterDesktopEngineProperties &engine_properties)
UINT FlutterDesktopGetDpiForMonitor(HMONITOR monitor)
FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(int width, int height, FlutterDesktopEngineRef engine)
std::unique_ptr< FlutterDesktopMessenger > messenger
bool RunWithEntrypoint(const char *entrypoint)
UINT FlutterDesktopGetDpiForHWND(HWND hwnd)
static flutter::FlutterWindowsEngine * EngineFromHandle(FlutterDesktopEngineRef ref)
FlutterDesktopPluginRegistrarRef GetRegistrar()
void FlutterDesktopPluginRegistrarRegisterTopLevelWindowProcDelegate(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopWindowProcCallback delegate, void *user_data)
struct FlutterDesktopView * FlutterDesktopViewRef
FlutterEngineResult FlutterEngineReloadSystemFonts(FLUTTER_API_SYMBOL(FlutterEngine) engine)
Reloads the system fonts in engine.
Definition: embedder.cc:1662
void FlutterDesktopEngineReloadSystemFonts(FlutterDesktopEngineRef engine)
HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view)
FlutterDesktopMessengerRef FlutterDesktopPluginRegistrarGetMessenger(FlutterDesktopPluginRegistrarRef registrar)
#define FLUTTER_ENGINE_VERSION
Definition: embedder.h:63
void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, const char *channel, FlutterDesktopMessageCallback callback, void *user_data)
FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine)
bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, const char *channel, const uint8_t *message, const size_t message_size)
FlutterDesktopEngineState * engine
FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar(FlutterDesktopEngineRef engine, const char *plugin_name)
bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger, const char *channel, const uint8_t *message, const size_t message_size, const FlutterDesktopBinaryReply reply, void *user_data)
int32_t height
FlutterDesktopViewRef FlutterDesktopViewControllerGetView(FlutterDesktopViewControllerRef controller)
int32_t width
void FlutterDesktopResyncOutputStreams()
bool(* FlutterDesktopWindowProcCallback)(HWND, UINT, WPARAM, LPARAM, void *, LRESULT *result)
FlutterDesktopMessengerRef messenger()
G_BEGIN_DECLS FlMethodCall gpointer user_data
void FlutterDesktopPluginRegistrarSetDestructionHandler(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopOnPluginRegistrarDestroyed callback)
FlutterEngineResult
Definition: embedder.h:65
std::chrono::nanoseconds ProcessTasks()
bool FlutterDesktopEngineDestroy(FlutterDesktopEngineRef engine_ref)
FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine(FlutterDesktopViewControllerRef controller)
static FlutterDesktopEngineRef HandleForEngine(flutter::FlutterWindowsEngine *engine)
static FlutterDesktopViewRef HandleForView(flutter::FlutterWindowsView *view)
static flutter::FlutterWindowsView * ViewFromHandle(FlutterDesktopViewRef ref)
void(* FlutterDesktopBinaryReply)(const uint8_t *data, size_t data_size, void *user_data)
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(FlutterDesktopPluginRegistrarRef registrar)
void(* FlutterDesktopOnPluginRegistrarDestroyed)(FlutterDesktopPluginRegistrarRef)
WindowsRenderTarget * GetRenderTarget() const
void FlutterDesktopViewControllerDestroy(FlutterDesktopViewControllerRef controller)
void(* FlutterDesktopMessageCallback)(FlutterDesktopMessengerRef, const FlutterDesktopMessage *, void *)
FlutterDesktopEngineState * engine
void FlutterDesktopMessengerSendResponse(FlutterDesktopMessengerRef messenger, const FlutterDesktopMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
bool FlutterDesktopEngineRun(FlutterDesktopEngineRef engine, const char *entry_point)
uint64_t FlutterDesktopEngineProcessMessages(FlutterDesktopEngineRef engine)
FlutterEngineResult FlutterEngineSendPlatformMessage(FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterPlatformMessage *flutter_message)
Definition: embedder.cc:1396
FlutterEngineResult FlutterPlatformMessageCreateResponseHandle(FLUTTER_API_SYMBOL(FlutterEngine) engine, FlutterDataCallback data_callback, void *user_data, FlutterPlatformMessageResponseHandle **response_out)
Creates a platform message response handle that allows the embedder to set a native callback for a re...
Definition: embedder.cc:1448