Skip to content

Commit 1c0207f

Browse files
authored
Convert embedder.h to a C API (#267)
Remove remaining C++ from embedder.h, and add extern C. Since the namespace is removed, use a standard prefix for all function names. Part of #230
1 parent a166d93 commit 1c0207f

File tree

4 files changed

+63
-52
lines changed

4 files changed

+63
-52
lines changed

library/common/glfw/embedder.cc

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ static FlutterEmbedderState *GetSavedEmbedderState(GLFWwindow *window) {
8989
}
9090

9191
// Converts a FlutterPlatformMessage to an equivalent FlutterEmbedderMessage.
92-
static flutter_desktop_embedding::FlutterEmbedderMessage
93-
ConvertToEmbedderMessage(const FlutterPlatformMessage &engine_message) {
94-
flutter_desktop_embedding::FlutterEmbedderMessage embedder_message = {};
92+
static FlutterEmbedderMessage ConvertToEmbedderMessage(
93+
const FlutterPlatformMessage &engine_message) {
94+
FlutterEmbedderMessage embedder_message = {};
9595
embedder_message.struct_size = sizeof(embedder_message);
9696
embedder_message.channel = engine_message.channel;
9797
embedder_message.message = engine_message.message;
@@ -284,17 +284,18 @@ static void GLFWErrorCallback(int error_code, const char *description) {
284284
// the necessary callbacks for rendering within a GLFWwindow.
285285
//
286286
// Returns a caller-owned pointer to the engine.
287-
static FlutterEngine RunFlutterEngine(
288-
GLFWwindow *window, const std::string &assets_path,
289-
const std::string &icu_data_path,
290-
const std::vector<std::string> &arguments) {
287+
static FlutterEngine RunFlutterEngine(GLFWwindow *window,
288+
const char *assets_path,
289+
const char *icu_data_path,
290+
const char **arguments,
291+
size_t arguments_count) {
291292
// FlutterProjectArgs is expecting a full argv, so when processing it for
292293
// flags the first item is treated as the executable and ignored. Add a dummy
293294
// value so that all provided arguments are used.
294295
std::vector<const char *> argv = {"placeholder"};
295-
std::transform(
296-
arguments.begin(), arguments.end(), std::back_inserter(argv),
297-
[](const std::string &arg) -> const char * { return arg.c_str(); });
296+
if (arguments_count > 0) {
297+
argv.insert(argv.end(), &arguments[0], &arguments[arguments_count]);
298+
}
298299

299300
FlutterRendererConfig config = {};
300301
config.type = kOpenGL;
@@ -306,8 +307,8 @@ static FlutterEngine RunFlutterEngine(
306307
config.open_gl.gl_proc_resolver = GLFWProcResolver;
307308
FlutterProjectArgs args = {};
308309
args.struct_size = sizeof(FlutterProjectArgs);
309-
args.assets_path = assets_path.c_str();
310-
args.icu_data_path = icu_data_path.c_str();
310+
args.assets_path = assets_path;
311+
args.icu_data_path = icu_data_path;
311312
args.command_line_argc = argv.size();
312313
args.command_line_argv = &argv[0];
313314
args.platform_message_callback = GLFWOnFlutterPlatformMessage;
@@ -322,20 +323,17 @@ static FlutterEngine RunFlutterEngine(
322323
return engine;
323324
}
324325

325-
namespace flutter_desktop_embedding {
326-
327-
bool FlutterInit() {
326+
bool FlutterEmbedderInit() {
328327
// Before making any GLFW calls, set up a logging error handler.
329328
glfwSetErrorCallback(GLFWErrorCallback);
330329
return glfwInit();
331330
}
332331

333-
void FlutterTerminate() { glfwTerminate(); }
332+
void FlutterEmbedderTerminate() { glfwTerminate(); }
334333

335-
FlutterWindowRef CreateFlutterWindow(
336-
size_t initial_width, size_t initial_height, const std::string &assets_path,
337-
const std::string &icu_data_path,
338-
const std::vector<std::string> &arguments) {
334+
FlutterWindowRef FlutterEmbedderCreateWindow(
335+
size_t initial_width, size_t initial_height, const char *assets_path,
336+
const char *icu_data_path, const char **arguments, size_t argument_count) {
339337
#ifdef __linux__
340338
gtk_init(0, nullptr);
341339
#endif
@@ -348,7 +346,8 @@ FlutterWindowRef CreateFlutterWindow(
348346
GLFWClearCanvas(window);
349347

350348
// Start the engine.
351-
auto engine = RunFlutterEngine(window, assets_path, icu_data_path, arguments);
349+
auto engine = RunFlutterEngine(window, assets_path, icu_data_path, arguments,
350+
argument_count);
352351
if (engine == nullptr) {
353352
glfwDestroyWindow(window);
354353
return nullptr;
@@ -360,14 +359,18 @@ FlutterWindowRef CreateFlutterWindow(
360359
glfwSetWindowUserPointer(window, state);
361360
state->engine = engine;
362361
state->message_dispatcher =
363-
std::make_unique<IncomingMessageDispatcher>(state);
364-
state->plugin_handler = std::make_unique<PluginHandler>(state);
362+
std::make_unique<flutter_desktop_embedding::IncomingMessageDispatcher>(
363+
state);
364+
state->plugin_handler =
365+
std::make_unique<flutter_desktop_embedding::PluginHandler>(state);
365366

366367
// Set up the keyboard handlers.
367368
state->keyboard_hook_handlers.push_back(
368-
std::make_unique<KeyEventHandler>(state->plugin_handler.get()));
369+
std::make_unique<flutter_desktop_embedding::KeyEventHandler>(
370+
state->plugin_handler.get()));
369371
state->keyboard_hook_handlers.push_back(
370-
std::make_unique<TextInputPlugin>(state->plugin_handler.get()));
372+
std::make_unique<flutter_desktop_embedding::TextInputPlugin>(
373+
state->plugin_handler.get()));
371374

372375
// Trigger an initial size callback to send size information to Flutter.
373376
state->monitor_screen_coordinates_per_inch = GetScreenCoordinatesPerInch();
@@ -382,7 +385,7 @@ FlutterWindowRef CreateFlutterWindow(
382385
return state;
383386
}
384387

385-
void FlutterWindowLoop(FlutterWindowRef flutter_window) {
388+
void FlutterEmbedderRunWindowLoop(FlutterWindowRef flutter_window) {
386389
GLFWwindow *window = flutter_window->window;
387390
#ifdef __linux__
388391
// Necessary for GTK thread safety.
@@ -438,5 +441,3 @@ void FlutterEmbedderEnableInputBlocking(FlutterWindowRef flutter_window,
438441
const char *channel) {
439442
flutter_window->message_dispatcher->EnableInputBlockingForChannel(channel);
440443
}
441-
442-
} // namespace flutter_desktop_embedding

library/common/glfw/flutter_window_controller.cc

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h"
1616

17+
#include <algorithm>
1718
#include <iostream>
1819

1920
#include "library/common/internal/plugin_handler.h"
@@ -22,20 +23,21 @@ namespace flutter_desktop_embedding {
2223

2324
FlutterWindowController::FlutterWindowController(std::string &icu_data_path)
2425
: icu_data_path_(icu_data_path) {
25-
init_succeeded_ = FlutterInit();
26+
init_succeeded_ = FlutterEmbedderInit();
2627
}
2728

2829
FlutterWindowController::~FlutterWindowController() {
2930
if (init_succeeded_) {
30-
FlutterTerminate();
31+
FlutterEmbedderTerminate();
3132
}
3233
}
3334

3435
bool FlutterWindowController::CreateWindow(
3536
size_t width, size_t height, const std::string &assets_path,
3637
const std::vector<std::string> &arguments) {
3738
if (!init_succeeded_) {
38-
std::cerr << "Could not create window; FlutterInit failed." << std::endl;
39+
std::cerr << "Could not create window; FlutterEmbedderInit failed."
40+
<< std::endl;
3941
return false;
4042
}
4143

@@ -44,8 +46,14 @@ bool FlutterWindowController::CreateWindow(
4446
return false;
4547
}
4648

47-
window_ = CreateFlutterWindow(width, height, assets_path, icu_data_path_,
48-
arguments);
49+
std::vector<const char *> engine_arguments;
50+
std::transform(
51+
arguments.begin(), arguments.end(), std::back_inserter(engine_arguments),
52+
[](const std::string &arg) -> const char * { return arg.c_str(); });
53+
54+
window_ = FlutterEmbedderCreateWindow(
55+
width, height, assets_path.c_str(), icu_data_path_.c_str(),
56+
&engine_arguments[0], engine_arguments.size());
4957
if (!window_) {
5058
std::cerr << "Failed to create window." << std::endl;
5159
return false;
@@ -69,7 +77,7 @@ PluginRegistrar *FlutterWindowController::GetRegistrarForPlugin(
6977

7078
void FlutterWindowController::RunEventLoop() {
7179
if (window_) {
72-
FlutterWindowLoop(window_);
80+
FlutterEmbedderRunWindowLoop(window_);
7381
}
7482
}
7583

library/include/flutter_desktop_embedding/glfw/embedder.h

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@
1515
#ifndef LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_EMBEDDER_H_
1616
#define LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_EMBEDDER_H_
1717

18-
#include <memory>
19-
#include <string>
20-
#include <vector>
18+
#include <stddef.h>
19+
#include <stdint.h>
2120

2221
// On Linux, the header output is always flattened; on Windows the GN build
2322
// is still optional. Once GN is required on Windows, eliminate this and just
@@ -34,29 +33,31 @@
3433
#include "../fde_export.h"
3534
#endif
3635

36+
#if defined(__cplusplus)
37+
extern "C" {
38+
#endif
39+
3740
// Opaque reference to a Flutter window.
3841
typedef struct FlutterEmbedderState *FlutterWindowRef;
3942

4043
// Opaque handle for tracking responses to messages.
4144
typedef struct _FlutterPlatformMessageResponseHandle
4245
FlutterEmbedderMessageResponseHandle;
4346

44-
namespace flutter_desktop_embedding {
45-
4647
// Sets up the embedder's graphic context. Must be called before any other
4748
// methods.
4849
//
4950
// Note: Internally, this library uses GLFW, which does not support multiple
5051
// copies within the same process. Internally this calls glfwInit, which will
5152
// fail if you have called glfwInit elsewhere in the process.
52-
FDE_EXPORT bool FlutterInit();
53+
FDE_EXPORT bool FlutterEmbedderInit();
5354

5455
// Tears down embedder state. Must be called before the process terminates.
55-
FDE_EXPORT void FlutterTerminate();
56+
FDE_EXPORT void FlutterEmbedderTerminate();
5657

5758
// Creates a Window running a Flutter Application.
5859
//
59-
// FlutterInit() must be called prior to this function.
60+
// FlutterEmbedderInit() must be called prior to this function.
6061
//
6162
// The |assets_path| is the path to the flutter_assets folder for the Flutter
6263
// application to be run. |icu_data_path| is the path to the icudtl.dat file
@@ -67,19 +68,18 @@ FDE_EXPORT void FlutterTerminate();
6768
// for details. Not all arguments will apply to embedding mode.
6869
//
6970
// Returns a null pointer in the event of an error. Otherwise, the pointer is
70-
// valid until FlutterWindowLoop has been called and returned. Note that calling
71-
// CreateFlutterWindow without later calling FlutterWindowLoop on that pointer
72-
// is a memory leak.
73-
FDE_EXPORT FlutterWindowRef CreateFlutterWindow(
74-
size_t initial_width, size_t initial_height, const std::string &assets_path,
75-
const std::string &icu_data_path,
76-
const std::vector<std::string> &arguments);
71+
// valid until FlutterEmbedderRunWindowLoop has been called and returned.
72+
// Note that calling FlutterEmbedderCreateWindow without later calling
73+
// FlutterEmbedderRunWindowLoop on the returned reference is a memory leak.
74+
FDE_EXPORT FlutterWindowRef FlutterEmbedderCreateWindow(
75+
size_t initial_width, size_t initial_height, const char *assets_path,
76+
const char *icu_data_path, const char **arguments, size_t argument_count);
7777

7878
// Loops on Flutter window events until the window is closed.
7979
//
8080
// Once this function returns, FlutterWindowRef is no longer valid, and must
8181
// not be used again.
82-
FDE_EXPORT void FlutterWindowLoop(FlutterWindowRef flutter_window);
82+
FDE_EXPORT void FlutterEmbedderRunWindowLoop(FlutterWindowRef flutter_window);
8383

8484
// A received from Flutter.
8585
typedef struct {
@@ -141,6 +141,8 @@ FDE_EXPORT void FlutterEmbedderSetMessageCallback(
141141
FDE_EXPORT void FlutterEmbedderEnableInputBlocking(
142142
FlutterWindowRef flutter_window, const char *channel);
143143

144-
} // namespace flutter_desktop_embedding
144+
#if defined(__cplusplus)
145+
} // extern "C"
146+
#endif
145147

146148
#endif // LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_EMBEDDER_H_

library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class FDE_EXPORT FlutterWindowController {
7979
// for any window created.
8080
std::string icu_data_path_;
8181

82-
// Whether or not FlutterInit succeeded at creation time.
82+
// Whether or not FlutterEmbedderInit succeeded at creation time.
8383
bool init_succeeded_ = false;
8484

8585
// The curent Flutter window, if any.

0 commit comments

Comments
 (0)