12 #include "flutter/shell/platform/embedder/embedder.h"
105 FlPluginRegistryInterface* iface);
115 G_IMPLEMENT_INTERFACE(fl_plugin_registry_get_type(),
126 gchar* l = g_strdup(locale);
129 gchar* match = strrchr(l,
'@');
130 if (match !=
nullptr) {
131 if (modifier !=
nullptr) {
132 *modifier = g_strdup(match + 1);
135 }
else if (modifier !=
nullptr) {
139 match = strrchr(l,
'.');
140 if (match !=
nullptr) {
141 if (codeset !=
nullptr) {
142 *codeset = g_strdup(match + 1);
145 }
else if (codeset !=
nullptr) {
149 match = strrchr(l,
'_');
150 if (match !=
nullptr) {
151 if (territory !=
nullptr) {
152 *territory = g_strdup(match + 1);
155 }
else if (territory !=
nullptr) {
156 *territory =
nullptr;
159 if (language !=
nullptr) {
165 g_autoptr(GTask) task = G_TASK(result->user_data);
168 g_task_return_boolean(task,
TRUE);
176 g_autoptr(GTask) task = G_TASK(result->user_data);
178 if (result->removed) {
179 g_task_return_boolean(task,
TRUE);
187 free(
const_cast<gchar*
>(locale->language_code));
188 free(
const_cast<gchar*
>(locale->country_code));
194 const gchar*
const* languages = g_get_language_names();
195 g_autoptr(GPtrArray) locales_array = g_ptr_array_new_with_free_func(
197 for (
int i = 0; languages[
i] !=
nullptr;
i++) {
198 g_autofree gchar* locale_string = g_strstrip(g_strdup(languages[
i]));
201 if (strcmp(locale_string,
"") == 0) {
205 g_autofree gchar* language =
nullptr;
206 g_autofree gchar* territory =
nullptr;
207 parse_locale(locale_string, &language, &territory,
nullptr,
nullptr);
211 gboolean has_locale = FALSE;
212 for (guint j = 0; !has_locale && j < locales_array->len; j++) {
213 FlutterLocale* locale =
214 reinterpret_cast<FlutterLocale*
>(g_ptr_array_index(locales_array, j));
215 has_locale = g_strcmp0(locale->language_code, language) == 0 &&
216 g_strcmp0(locale->country_code, territory) == 0;
222 FlutterLocale* locale =
223 static_cast<FlutterLocale*
>(g_malloc0(
sizeof(FlutterLocale)));
224 g_ptr_array_add(locales_array, locale);
225 locale->struct_size =
sizeof(FlutterLocale);
226 locale->language_code =
227 reinterpret_cast<const gchar*
>(g_steal_pointer(&language));
228 locale->country_code =
229 reinterpret_cast<const gchar*
>(g_steal_pointer(&territory));
230 locale->script_code =
nullptr;
231 locale->variant_code =
nullptr;
233 FlutterLocale** locales =
234 reinterpret_cast<FlutterLocale**
>(locales_array->pdata);
235 FlutterEngineResult result =
self->embedder_api.UpdateLocales(
236 self->engine,
const_cast<const FlutterLocale**
>(locales),
238 if (result != kSuccess) {
239 g_warning(
"Failed to set up Flutter locales");
245 const FlutterBackingStoreConfig* config,
246 FlutterBackingStore* backing_store_out,
248 g_return_val_if_fail(FL_IS_RENDERER(
user_data),
false);
255 const FlutterBackingStore* backing_store,
257 g_return_val_if_fail(FL_IS_RENDERER(
user_data),
false);
264 const FlutterPresentViewInfo* info) {
265 g_return_val_if_fail(FL_IS_RENDERER(info->user_data),
false);
267 info->layers, info->layers_count);
273 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
278 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
284 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
290 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
301 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
312 FlutterOpenGLTexture* opengl_texture) {
313 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
314 if (!self->texture_registrar) {
320 if (texture ==
nullptr) {
321 g_warning(
"Unable to find texture %" G_GINT64_FORMAT,
texture_id);
326 g_autoptr(GError)
error =
nullptr;
327 if (FL_IS_TEXTURE_GL(texture)) {
329 opengl_texture, &
error);
330 }
else if (FL_IS_PIXEL_BUFFER_TEXTURE(texture)) {
335 g_warning(
"Unsupported texture type %" G_GINT64_FORMAT,
texture_id);
340 g_warning(
"%s",
error->message);
349 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
350 return self->thread == g_thread_self();
355 uint64_t target_time_nanos,
357 FlEngine*
self =
static_cast<FlEngine*
>(
user_data);
367 gboolean handled = FALSE;
368 if (self->platform_message_handler !=
nullptr) {
369 g_autoptr(GBytes) data =
370 g_bytes_new(message->message, message->message_size);
371 handled =
self->platform_message_handler(
372 self, message->channel, data, message->response_handle,
373 self->platform_message_handler_data);
391 g_clear_object(&self->keyboard_manager);
394 g_clear_object(&self->keyboard_handler);
395 self->keyboard_handler =
399 self->text_input_handler !=
nullptr
402 g_clear_object(&self->text_input_handler);
404 if (widget !=
nullptr) {
427 g_autoptr(GTask) task = G_TASK(
user_data);
428 g_task_return_pointer(task, g_bytes_new(data, data_length),
429 reinterpret_cast<GDestroyNotify
>(g_bytes_unref));
434 FlPluginRegistry* registry,
436 FlEngine*
self = FL_ENGINE(registry);
439 self->texture_registrar);
443 FlPluginRegistryInterface* iface) {
451 FlEngine*
self = FL_ENGINE(
object);
453 case PROP_BINARY_MESSENGER:
454 g_set_object(&self->binary_messenger,
455 FL_BINARY_MESSENGER(g_value_get_object(
value)));
458 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object,
prop_id,
pspec);
464 FlEngine*
self = FL_ENGINE(
object);
466 if (self->engine !=
nullptr) {
467 self->embedder_api.Shutdown(self->engine);
468 self->engine =
nullptr;
471 if (self->aot_data !=
nullptr) {
472 self->embedder_api.CollectAOTData(self->aot_data);
473 self->aot_data =
nullptr;
479 g_clear_object(&self->project);
480 g_clear_object(&self->display_monitor);
481 g_clear_object(&self->renderer);
482 g_clear_object(&self->texture_registrar);
483 g_clear_object(&self->binary_messenger);
484 g_clear_object(&self->settings_handler);
485 g_clear_object(&self->platform_handler);
486 g_clear_object(&self->windowing_handler);
487 g_clear_object(&self->keyboard_manager);
488 g_clear_object(&self->text_input_handler);
489 g_clear_object(&self->keyboard_handler);
490 g_clear_object(&self->mouse_cursor_handler);
491 g_clear_object(&self->task_runner);
493 if (self->platform_message_handler_destroy_notify) {
494 self->platform_message_handler_destroy_notify(
495 self->platform_message_handler_data);
497 self->platform_message_handler_data =
nullptr;
498 self->platform_message_handler_destroy_notify =
nullptr;
500 G_OBJECT_CLASS(fl_engine_parent_class)->dispose(
object);
507 g_object_class_install_property(
508 G_OBJECT_CLASS(klass), PROP_BINARY_MESSENGER,
510 "binary-messenger",
"messenger",
"Binary messenger",
511 fl_binary_messenger_get_type(),
512 static_cast<GParamFlags
>(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
513 G_PARAM_STATIC_STRINGS)));
516 "on-pre-engine-restart", fl_engine_get_type(), G_SIGNAL_RUN_LAST, 0,
517 nullptr,
nullptr,
nullptr, G_TYPE_NONE, 0);
519 "update-semantics", fl_engine_get_type(), G_SIGNAL_RUN_LAST, 0,
nullptr,
520 nullptr,
nullptr, G_TYPE_NONE, 1, G_TYPE_POINTER);
524 self->thread = g_thread_self();
526 self->embedder_api.struct_size =
sizeof(FlutterEngineProcTable);
527 if (FlutterEngineGetProcAddresses(&self->embedder_api) != kSuccess) {
528 g_warning(
"Failed get get engine function pointers");
531 self->display_monitor =
536 self->next_view_id = 1;
542 FlRenderer* renderer,
543 FlBinaryMessenger* binary_messenger) {
544 g_return_val_if_fail(FL_IS_DART_PROJECT(project),
nullptr);
545 g_return_val_if_fail(FL_IS_RENDERER(renderer),
nullptr);
547 FlEngine*
self = FL_ENGINE(g_object_new(fl_engine_get_type(),
nullptr));
549 self->project = FL_DART_PROJECT(g_object_ref(project));
550 self->renderer = FL_RENDERER(g_object_ref(renderer));
551 if (binary_messenger !=
nullptr) {
552 self->binary_messenger =
553 FL_BINARY_MESSENGER(g_object_ref(binary_messenger));
558 self->mouse_cursor_handler =
568 void* engine =
reinterpret_cast<void*
>(
id);
569 g_return_val_if_fail(FL_IS_ENGINE(engine),
nullptr);
570 return FL_ENGINE(engine);
574 FlRenderer* renderer) {
575 g_return_val_if_fail(FL_IS_DART_PROJECT(project),
nullptr);
576 g_return_val_if_fail(FL_IS_RENDERER(renderer),
nullptr);
586 FlBinaryMessenger* binary_messenger) {
598 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
599 return self->renderer;
603 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
604 return self->display_monitor;
608 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
610 FlutterRendererConfig config = {};
611 config.type = kOpenGL;
612 config.open_gl.struct_size =
sizeof(FlutterOpenGLRendererConfig);
619 config.open_gl.gl_external_texture_frame_callback =
622 FlutterTaskRunnerDescription platform_task_runner = {};
623 platform_task_runner.struct_size =
sizeof(FlutterTaskRunnerDescription);
624 platform_task_runner.user_data =
self;
625 platform_task_runner.runs_task_on_current_thread_callback =
630 FlutterCustomTaskRunners custom_task_runners = {};
631 custom_task_runners.struct_size =
sizeof(FlutterCustomTaskRunners);
632 custom_task_runners.platform_task_runner = &platform_task_runner;
633 custom_task_runners.render_task_runner = &platform_task_runner;
635 g_autoptr(GPtrArray) command_line_args =
636 g_ptr_array_new_with_free_func(g_free);
637 g_ptr_array_insert(command_line_args, 0, g_strdup(
"flutter"));
639 g_ptr_array_add(command_line_args, g_strdup(env_switch.c_str()));
642 gchar** dart_entrypoint_args =
645 FlutterProjectArgs
args = {};
646 args.struct_size =
sizeof(FlutterProjectArgs);
649 args.command_line_argc = command_line_args->len;
650 args.command_line_argv =
651 reinterpret_cast<const char* const*
>(command_line_args->pdata);
654 args.custom_task_runners = &custom_task_runners;
655 args.shutdown_dart_vm_when_done =
true;
657 args.dart_entrypoint_argc =
658 dart_entrypoint_args !=
nullptr ? g_strv_length(dart_entrypoint_args) : 0;
659 args.dart_entrypoint_argv =
660 reinterpret_cast<const char* const*
>(dart_entrypoint_args);
661 args.engine_id =
reinterpret_cast<int64_t
>(
self);
663 FlutterCompositor compositor = {};
664 compositor.struct_size =
sizeof(FlutterCompositor);
665 compositor.user_data =
self->renderer;
666 compositor.create_backing_store_callback =
668 compositor.collect_backing_store_callback =
671 args.compositor = &compositor;
673 if (self->embedder_api.RunsAOTCompiledDartCode()) {
674 FlutterEngineAOTDataSource source = {};
675 source.type = kFlutterEngineAOTDataSourceTypeElfPath;
677 if (self->embedder_api.CreateAOTData(&source, &self->aot_data) !=
680 "Failed to create AOT data");
683 args.aot_data =
self->aot_data;
686 FlutterEngineResult result =
self->embedder_api.Initialize(
687 FLUTTER_ENGINE_VERSION, &config, &
args,
self, &self->engine);
688 if (result != kSuccess) {
690 "Failed to initialize Flutter engine");
694 result =
self->embedder_api.RunInitialized(self->engine);
695 if (result != kSuccess) {
697 "Failed to run Flutter engine");
711 result =
self->embedder_api.UpdateSemanticsEnabled(self->engine,
TRUE);
712 if (result != kSuccess) {
713 g_warning(
"Failed to enable accessibility features on Flutter engine");
722 return &(
self->embedder_api);
726 const FlutterEngineDisplay* displays,
727 size_t displays_length) {
728 g_return_if_fail(FL_IS_ENGINE(
self));
730 FlutterEngineResult result =
self->embedder_api.NotifyDisplayUpdate(
731 self->engine, kFlutterEngineDisplaysUpdateTypeStartup, displays,
733 if (result != kSuccess) {
734 g_warning(
"Failed to notify display update to Flutter engine: %d", result);
742 GCancellable* cancellable,
743 GAsyncReadyCallback callback,
745 g_return_val_if_fail(FL_IS_ENGINE(
self), -1);
747 g_autoptr(GTask) task = g_task_new(
self, cancellable, callback,
user_data);
749 FlutterViewId view_id =
self->next_view_id;
750 self->next_view_id++;
754 FlutterEngineDisplayId display_id = 0;
756 FlutterWindowMetricsEvent metrics;
757 metrics.struct_size =
sizeof(FlutterWindowMetricsEvent);
758 metrics.width =
width;
760 metrics.pixel_ratio = pixel_ratio;
761 metrics.display_id = display_id;
762 metrics.view_id = view_id;
763 FlutterAddViewInfo info;
764 info.struct_size =
sizeof(FlutterAddViewInfo);
765 info.view_id = view_id;
766 info.view_metrics = &metrics;
767 info.user_data = g_object_ref(task);
769 FlutterEngineResult result =
self->embedder_api.AddView(self->engine, &info);
770 if (result != kSuccess) {
775 g_object_unref(task);
782 GAsyncResult* result,
784 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
785 return g_task_propagate_boolean(G_TASK(result),
error);
789 FlutterViewId view_id,
790 GCancellable* cancellable,
791 GAsyncReadyCallback callback,
793 g_return_if_fail(FL_IS_ENGINE(
self));
795 g_autoptr(GTask) task = g_task_new(
self, cancellable, callback,
user_data);
797 FlutterRemoveViewInfo info;
798 info.struct_size =
sizeof(FlutterRemoveViewInfo);
799 info.view_id = view_id;
800 info.user_data = g_object_ref(task);
802 FlutterEngineResult result =
803 self->embedder_api.RemoveView(self->engine, &info);
804 if (result != kSuccess) {
809 g_object_unref(task);
814 GAsyncResult* result,
816 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
817 return g_task_propagate_boolean(G_TASK(result),
error);
824 GDestroyNotify destroy_notify) {
825 g_return_if_fail(FL_IS_ENGINE(
self));
826 g_return_if_fail(handler !=
nullptr);
828 if (self->platform_message_handler_destroy_notify) {
829 self->platform_message_handler_destroy_notify(
830 self->platform_message_handler_data);
833 self->platform_message_handler = handler;
834 self->platform_message_handler_data =
user_data;
835 self->platform_message_handler_destroy_notify = destroy_notify;
841 const FlutterPlatformMessageResponseHandle* handle,
844 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
845 g_return_val_if_fail(handle !=
nullptr, FALSE);
847 if (self->engine ==
nullptr) {
849 "No engine to send response to");
853 gsize data_length = 0;
854 const uint8_t* data =
nullptr;
855 if (response !=
nullptr) {
857 static_cast<const uint8_t*
>(g_bytes_get_data(response, &data_length));
859 FlutterEngineResult result =
self->embedder_api.SendPlatformMessageResponse(
860 self->engine, handle, data, data_length);
862 if (result != kSuccess) {
864 "Failed to send platform message response");
872 const gchar* channel,
874 GCancellable* cancellable,
875 GAsyncReadyCallback callback,
877 g_return_if_fail(FL_IS_ENGINE(
self));
879 GTask* task =
nullptr;
880 FlutterPlatformMessageResponseHandle* response_handle =
nullptr;
881 if (callback !=
nullptr) {
882 task = g_task_new(
self, cancellable, callback,
user_data);
884 if (self->engine ==
nullptr) {
890 FlutterEngineResult result =
891 self->embedder_api.PlatformMessageCreateResponseHandle(
894 if (result != kSuccess) {
897 "Failed to create response handle");
898 g_object_unref(task);
901 }
else if (self->engine ==
nullptr) {
905 FlutterPlatformMessage fl_message = {};
906 fl_message.struct_size =
sizeof(fl_message);
907 fl_message.channel = channel;
910 ?
static_cast<const uint8_t*
>(g_bytes_get_data(message,
nullptr))
912 fl_message.message_size = message !=
nullptr ? g_bytes_get_size(message) : 0;
913 fl_message.response_handle = response_handle;
914 FlutterEngineResult result =
915 self->embedder_api.SendPlatformMessage(self->engine, &fl_message);
917 if (result != kSuccess && task !=
nullptr) {
920 "Failed to send platform messages");
921 g_object_unref(task);
924 if (response_handle !=
nullptr) {
925 self->embedder_api.PlatformMessageReleaseResponseHandle(self->engine,
931 GAsyncResult* result,
933 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
934 g_return_val_if_fail(g_task_is_valid(result,
self), FALSE);
936 return static_cast<GBytes*
>(g_task_propagate_pointer(G_TASK(result),
error));
940 FlutterEngineDisplayId display_id,
941 FlutterViewId view_id,
944 double pixel_ratio) {
945 g_return_if_fail(FL_IS_ENGINE(
self));
947 if (self->engine ==
nullptr) {
951 FlutterWindowMetricsEvent
event = {};
952 event.struct_size =
sizeof(FlutterWindowMetricsEvent);
955 event.pixel_ratio = pixel_ratio;
956 event.display_id = display_id;
957 event.view_id = view_id;
958 self->embedder_api.SendWindowMetricsEvent(self->engine, &event);
962 FlutterViewId view_id,
963 FlutterPointerPhase phase,
967 FlutterPointerDeviceKind device_kind,
968 double scroll_delta_x,
969 double scroll_delta_y,
971 g_return_if_fail(FL_IS_ENGINE(
self));
973 if (self->engine ==
nullptr) {
977 FlutterPointerEvent fl_event = {};
978 fl_event.struct_size =
sizeof(fl_event);
979 fl_event.phase = phase;
980 fl_event.timestamp = timestamp;
983 if (scroll_delta_x != 0 || scroll_delta_y != 0) {
984 fl_event.signal_kind = kFlutterPointerSignalKindScroll;
986 fl_event.scroll_delta_x = scroll_delta_x;
987 fl_event.scroll_delta_y = scroll_delta_y;
988 fl_event.device_kind = device_kind;
989 fl_event.buttons = buttons;
991 fl_event.view_id = view_id;
992 self->embedder_api.SendPointerEvent(self->engine, &fl_event, 1);
996 FlutterViewId view_id,
1001 g_return_if_fail(FL_IS_ENGINE(
self));
1003 if (self->engine ==
nullptr) {
1007 FlutterPointerEvent event;
1008 event.timestamp = timestamp;
1011 event.device_kind = kFlutterPointerDeviceKindTouch;
1012 event.device = device;
1014 event.view_id = view_id;
1015 event.phase = FlutterPointerPhase::kUp;
1016 event.struct_size =
sizeof(event);
1018 self->embedder_api.SendPointerEvent(self->engine, &event, 1);
1022 FlutterViewId view_id,
1027 g_return_if_fail(FL_IS_ENGINE(
self));
1029 if (self->engine ==
nullptr) {
1033 FlutterPointerEvent event;
1034 event.timestamp = timestamp;
1037 event.device_kind = kFlutterPointerDeviceKindTouch;
1038 event.device = device;
1039 event.buttons = FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary;
1040 event.view_id = view_id;
1041 event.phase = FlutterPointerPhase::kDown;
1042 event.struct_size =
sizeof(event);
1044 self->embedder_api.SendPointerEvent(self->engine, &event, 1);
1048 FlutterViewId view_id,
1053 g_return_if_fail(FL_IS_ENGINE(
self));
1055 if (self->engine ==
nullptr) {
1059 FlutterPointerEvent event;
1060 event.timestamp = timestamp;
1063 event.device_kind = kFlutterPointerDeviceKindTouch;
1064 event.device = device;
1065 event.buttons = FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary;
1066 event.view_id = view_id;
1067 event.phase = FlutterPointerPhase::kMove;
1068 event.struct_size =
sizeof(event);
1070 self->embedder_api.SendPointerEvent(self->engine, &event, 1);
1074 FlutterViewId view_id,
1079 g_return_if_fail(FL_IS_ENGINE(
self));
1081 if (self->engine ==
nullptr) {
1085 FlutterPointerEvent event;
1086 event.timestamp = timestamp;
1089 event.device_kind = kFlutterPointerDeviceKindTouch;
1090 event.device = device;
1092 event.view_id = view_id;
1093 event.phase = FlutterPointerPhase::kAdd;
1094 event.struct_size =
sizeof(event);
1096 self->embedder_api.SendPointerEvent(self->engine, &event, 1);
1100 FlutterViewId view_id,
1105 g_return_if_fail(FL_IS_ENGINE(
self));
1107 if (self->engine ==
nullptr) {
1111 FlutterPointerEvent event;
1112 event.timestamp = timestamp;
1115 event.device_kind = kFlutterPointerDeviceKindTouch;
1116 event.device = device;
1118 event.view_id = view_id;
1119 event.phase = FlutterPointerPhase::kRemove;
1120 event.struct_size =
sizeof(event);
1122 self->embedder_api.SendPointerEvent(self->engine, &event, 1);
1126 FlutterViewId view_id,
1130 FlutterPointerPhase phase,
1135 g_return_if_fail(FL_IS_ENGINE(
self));
1137 if (self->engine ==
nullptr) {
1141 FlutterPointerEvent fl_event = {};
1142 fl_event.struct_size =
sizeof(fl_event);
1143 fl_event.timestamp = timestamp;
1146 fl_event.phase = phase;
1147 fl_event.pan_x = pan_x;
1148 fl_event.pan_y = pan_y;
1149 fl_event.scale = scale;
1150 fl_event.rotation = rotation;
1152 fl_event.device_kind = kFlutterPointerDeviceKindTrackpad;
1153 fl_event.view_id = view_id;
1154 self->embedder_api.SendPointerEvent(self->engine, &fl_event, 1);
1158 g_autoptr(GTask) task = G_TASK(
user_data);
1159 gboolean* return_value = g_new0(gboolean, 1);
1160 *return_value = handled;
1161 g_task_return_pointer(task, return_value, g_free);
1165 const FlutterKeyEvent* event,
1166 GCancellable* cancellable,
1167 GAsyncReadyCallback callback,
1169 g_return_if_fail(FL_IS_ENGINE(
self));
1171 g_autoptr(GTask) task = g_task_new(
self, cancellable, callback,
user_data);
1173 if (self->engine ==
nullptr) {
1180 g_object_ref(task)) != kSuccess) {
1183 g_object_unref(task);
1188 GAsyncResult* result,
1191 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
1192 g_return_val_if_fail(g_task_is_valid(result,
self), FALSE);
1194 g_autofree gboolean* return_value =
1195 static_cast<gboolean*
>(g_task_propagate_pointer(G_TASK(result),
error));
1196 if (return_value ==
nullptr) {
1200 *handled = *return_value;
1206 FlutterSemanticsAction action,
1208 g_return_if_fail(FL_IS_ENGINE(
self));
1210 if (self->engine ==
nullptr) {
1214 const uint8_t* action_data =
nullptr;
1215 size_t action_data_length = 0;
1216 if (data !=
nullptr) {
1217 action_data =
static_cast<const uint8_t*
>(
1218 g_bytes_get_data(data, &action_data_length));
1221 self->embedder_api.DispatchSemanticsAction(self->engine,
id, action,
1222 action_data, action_data_length);
1227 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
1228 return self->embedder_api.MarkExternalTextureFrameAvailable(
1234 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
1235 return self->embedder_api.RegisterExternalTexture(self->engine,
texture_id) ==
1241 g_return_val_if_fail(FL_IS_ENGINE(
self), FALSE);
1242 return self->embedder_api.UnregisterExternalTexture(self->engine,
1248 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
1249 return self->binary_messenger;
1253 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
1254 return self->task_runner;
1258 g_return_if_fail(FL_IS_ENGINE(
self));
1259 self->embedder_api.RunTask(self->engine, task);
1264 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
1265 return self->texture_registrar;
1269 g_return_if_fail(FL_IS_ENGINE(
self));
1271 if (self->engine ==
nullptr) {
1275 self->embedder_api.UpdateAccessibilityFeatures(
1276 self->engine,
static_cast<FlutterAccessibilityFeature
>(
flags));
1280 g_return_if_fail(FL_IS_ENGINE(
self));
1285 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
1286 return self->windowing_handler;
1290 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
1291 return self->keyboard_manager;
1295 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
1296 return self->text_input_handler;
1300 g_return_val_if_fail(FL_IS_ENGINE(
self),
nullptr);
1301 return self->mouse_cursor_handler;