mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add a Linux Shell that uses GTK for rendering. (flutter/engine#16977)
This commit is contained in:
parent
2f3a5f36fd
commit
71d631160f
@ -1145,6 +1145,11 @@ FILE: ../../../flutter/shell/platform/glfw/platform_handler.h
|
||||
FILE: ../../../flutter/shell/platform/glfw/public/flutter_glfw.h
|
||||
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.cc
|
||||
FILE: ../../../flutter/shell/platform/glfw/text_input_plugin.h
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_dart_project.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/fl_view.cc
|
||||
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_dart_project.h
|
||||
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/fl_view.h
|
||||
FILE: ../../../flutter/shell/platform/linux/public/flutter_linux/flutter_linux.h
|
||||
FILE: ../../../flutter/shell/platform/windows/angle_surface_manager.cc
|
||||
FILE: ../../../flutter/shell/platform/windows/angle_surface_manager.h
|
||||
FILE: ../../../flutter/shell/platform/windows/client_wrapper/dart_project_unittests.cc
|
||||
|
||||
@ -5,15 +5,23 @@
|
||||
assert(is_linux)
|
||||
|
||||
import("//flutter/shell/platform/glfw/config.gni")
|
||||
import("//flutter/shell/platform/linux/config.gni")
|
||||
|
||||
group("linux") {
|
||||
deps = []
|
||||
if (build_glfw_shell) {
|
||||
deps = [
|
||||
deps += [
|
||||
":flutter_linux_glfw",
|
||||
"//flutter/shell/platform/glfw:publish_headers_glfw",
|
||||
"//flutter/shell/platform/glfw/client_wrapper:publish_wrapper_glfw",
|
||||
]
|
||||
}
|
||||
if (build_linux_shell) {
|
||||
deps += [
|
||||
":flutter_linux_gtk",
|
||||
":publish_headers_linux",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# Temporary workaround for the issue describe in
|
||||
@ -37,3 +45,49 @@ if (build_glfw_shell) {
|
||||
public_configs = [ "//flutter:config" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (build_linux_shell) {
|
||||
_public_headers = [
|
||||
"public/flutter_linux/fl_dart_project.h",
|
||||
"public/flutter_linux/fl_view.h",
|
||||
"public/flutter_linux/flutter_linux.h",
|
||||
]
|
||||
|
||||
config("relative_flutter_linux_headers") {
|
||||
include_dirs = [ "public" ]
|
||||
}
|
||||
|
||||
source_set("flutter_linux") {
|
||||
sources = [
|
||||
"fl_dart_project.cc",
|
||||
"fl_view.cc",
|
||||
]
|
||||
|
||||
configs += [
|
||||
"//flutter/shell/platform/linux/config:gtk",
|
||||
"//flutter/shell/platform/linux/config:egl",
|
||||
]
|
||||
|
||||
# Set flag to stop headers being directly included (library users should not do this)
|
||||
defines = [ "FLUTTER_LINUX_COMPILATION" ]
|
||||
|
||||
deps = [
|
||||
"//flutter/shell/platform/embedder:embedder_with_symbol_prefix",
|
||||
]
|
||||
}
|
||||
|
||||
shared_library("flutter_linux_gtk") {
|
||||
deps = [
|
||||
":flutter_linux",
|
||||
]
|
||||
|
||||
public_configs = [ "//flutter:config" ]
|
||||
}
|
||||
|
||||
copy("publish_headers_linux") {
|
||||
sources = _public_headers
|
||||
outputs = [
|
||||
"$root_out_dir/flutter_linux/{{source_file_part}}",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
11
engine/src/flutter/shell/platform/linux/config.gni
Normal file
11
engine/src/flutter/shell/platform/linux/config.gni
Normal file
@ -0,0 +1,11 @@
|
||||
# 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.
|
||||
|
||||
declare_args() {
|
||||
# Whether to build the Linux (GTK) shell for the host platform, if available.
|
||||
#
|
||||
# The Linux shell is not currently built by default as the CI system doesn't
|
||||
# (yet) have GTK as a dependency. When that is ready the flag will be removed.
|
||||
build_linux_shell = false
|
||||
}
|
||||
@ -3,7 +3,17 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//build/config/linux/pkg_config.gni")
|
||||
import("//flutter/shell/platform/linux/config.gni")
|
||||
|
||||
pkg_config("x11") {
|
||||
packages = [ "x11" ]
|
||||
}
|
||||
|
||||
if (build_linux_shell) {
|
||||
pkg_config("gtk") {
|
||||
packages = [ "gtk+-3.0" ]
|
||||
}
|
||||
pkg_config("egl") {
|
||||
packages = [ "egl" ]
|
||||
}
|
||||
}
|
||||
|
||||
140
engine/src/flutter/shell/platform/linux/fl_dart_project.cc
Normal file
140
engine/src/flutter/shell/platform/linux/fl_dart_project.cc
Normal file
@ -0,0 +1,140 @@
|
||||
// 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/linux/public/flutter_linux/fl_dart_project.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
/**
|
||||
* FlDartProject:
|
||||
*
|
||||
* #FlDartProject represents a Dart project. It is used provide information
|
||||
* about the application when creating a #FlView.
|
||||
*/
|
||||
|
||||
struct _FlDartProject {
|
||||
GObject parent_instance;
|
||||
|
||||
gchar* assets_path;
|
||||
gchar* icu_data_path;
|
||||
};
|
||||
|
||||
enum { PROP_ASSETS_PATH = 1, PROP_ICU_DATA_PATH, PROP_LAST };
|
||||
|
||||
G_DEFINE_TYPE(FlDartProject, fl_dart_project, G_TYPE_OBJECT)
|
||||
|
||||
static void fl_dart_project_set_property(GObject* object,
|
||||
guint prop_id,
|
||||
const GValue* value,
|
||||
GParamSpec* pspec) {
|
||||
FlDartProject* self = FL_DART_PROJECT(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_ASSETS_PATH:
|
||||
g_free(self->assets_path);
|
||||
self->assets_path = g_strdup(g_value_get_string(value));
|
||||
break;
|
||||
case PROP_ICU_DATA_PATH:
|
||||
g_free(self->icu_data_path);
|
||||
self->icu_data_path = g_strdup(g_value_get_string(value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void fl_dart_project_get_property(GObject* object,
|
||||
guint prop_id,
|
||||
GValue* value,
|
||||
GParamSpec* pspec) {
|
||||
FlDartProject* self = FL_DART_PROJECT(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_ASSETS_PATH:
|
||||
g_value_set_string(value, self->assets_path);
|
||||
break;
|
||||
case PROP_ICU_DATA_PATH:
|
||||
g_value_set_string(value, self->icu_data_path);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void fl_dart_project_dispose(GObject* object) {
|
||||
FlDartProject* self = FL_DART_PROJECT(object);
|
||||
|
||||
g_clear_pointer(&self->assets_path, g_free);
|
||||
g_clear_pointer(&self->icu_data_path, g_free);
|
||||
|
||||
G_OBJECT_CLASS(fl_dart_project_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void fl_dart_project_class_init(FlDartProjectClass* klass) {
|
||||
G_OBJECT_CLASS(klass)->set_property = fl_dart_project_set_property;
|
||||
G_OBJECT_CLASS(klass)->get_property = fl_dart_project_get_property;
|
||||
G_OBJECT_CLASS(klass)->dispose = fl_dart_project_dispose;
|
||||
|
||||
g_object_class_install_property(
|
||||
G_OBJECT_CLASS(klass), PROP_ASSETS_PATH,
|
||||
g_param_spec_string(
|
||||
"assets-path", "assets-path", "Path to Flutter assets", nullptr,
|
||||
static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS)));
|
||||
g_object_class_install_property(
|
||||
G_OBJECT_CLASS(klass), PROP_ICU_DATA_PATH,
|
||||
g_param_spec_string(
|
||||
"icu-data-path", "icu-data-path", "Path to ICU data", nullptr,
|
||||
static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS)));
|
||||
}
|
||||
|
||||
static void fl_dart_project_init(FlDartProject* self) {}
|
||||
|
||||
/**
|
||||
* fl_dart_project_new:
|
||||
* @assets_path: a file path, e.g. "build/assets"
|
||||
* @icu_data_path: a file path, e.g. "build/icudtl.dat"
|
||||
*
|
||||
* Create a Flutter project.
|
||||
*
|
||||
* Returns: a new #FlDartProject
|
||||
*/
|
||||
G_MODULE_EXPORT FlDartProject* fl_dart_project_new(const gchar* assets_path,
|
||||
const gchar* icu_data_path) {
|
||||
return static_cast<FlDartProject*>(
|
||||
g_object_new(fl_dart_project_get_type(), "assets-path", assets_path,
|
||||
"icu-data-path", icu_data_path, nullptr));
|
||||
}
|
||||
|
||||
/**
|
||||
* fl_dart_project_get_assets_path:
|
||||
* @view: a #FlDartProject
|
||||
*
|
||||
* Get the path to the directory containing the assets used in the Flutter
|
||||
* application.
|
||||
*
|
||||
* Returns: a file path, e.g. "build/assets"
|
||||
*/
|
||||
G_MODULE_EXPORT const gchar* fl_dart_project_get_assets_path(
|
||||
FlDartProject* self) {
|
||||
g_return_val_if_fail(FL_IS_DART_PROJECT(self), nullptr);
|
||||
return self->assets_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* fl_dart_project_get_icu_data_path:
|
||||
* @view: a #FlDartProject
|
||||
*
|
||||
* Get the path to the ICU data file in the Flutter application.
|
||||
*
|
||||
* Returns: a file path, e.g. "build/icudtl.dat"
|
||||
*/
|
||||
G_MODULE_EXPORT const gchar* fl_dart_project_get_icu_data_path(
|
||||
FlDartProject* self) {
|
||||
g_return_val_if_fail(FL_IS_DART_PROJECT(self), nullptr);
|
||||
return self->icu_data_path;
|
||||
}
|
||||
287
engine/src/flutter/shell/platform/linux/fl_view.cc
Normal file
287
engine/src/flutter/shell/platform/linux/fl_view.cc
Normal file
@ -0,0 +1,287 @@
|
||||
// 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/linux/public/flutter_linux/fl_view.h"
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include "flutter/shell/platform/embedder/embedder.h"
|
||||
|
||||
/**
|
||||
* FlView:
|
||||
*
|
||||
* #FlView is a GTK widget that is capable of displaying a Flutter application.
|
||||
*/
|
||||
|
||||
struct _FlView {
|
||||
GtkWidget parent_instance;
|
||||
|
||||
EGLDisplay egl_display;
|
||||
EGLSurface egl_surface;
|
||||
EGLContext egl_context;
|
||||
|
||||
FlDartProject* flutter_project;
|
||||
FLUTTER_API_SYMBOL(FlutterEngine) flutter_engine;
|
||||
};
|
||||
|
||||
enum { PROP_FLUTTER_PROJECT = 1, PROP_LAST };
|
||||
|
||||
G_DEFINE_TYPE(FlView, fl_view, GTK_TYPE_WIDGET)
|
||||
|
||||
static gboolean initialize_egl(FlView* self) {
|
||||
/* Note that we don't provide the XDisplay from GTK, this would make both
|
||||
* GTK and EGL share the same X connection and this would crash when used by
|
||||
* a Flutter thread. So the EGL display and GTK both have separate
|
||||
* connections.
|
||||
*/
|
||||
self->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
|
||||
EGLint egl_major, egl_minor;
|
||||
if (!eglInitialize(self->egl_display, &egl_major, &egl_minor)) {
|
||||
g_warning("Failed to initialze EGL");
|
||||
return FALSE;
|
||||
}
|
||||
// TODO(robert-ancell): It would probably be useful to store the EGL version
|
||||
// for debugging purposes
|
||||
|
||||
EGLint attributes[] = {EGL_RENDERABLE_TYPE,
|
||||
EGL_OPENGL_ES2_BIT,
|
||||
EGL_RED_SIZE,
|
||||
8,
|
||||
EGL_GREEN_SIZE,
|
||||
8,
|
||||
EGL_BLUE_SIZE,
|
||||
8,
|
||||
EGL_ALPHA_SIZE,
|
||||
8,
|
||||
EGL_NONE};
|
||||
EGLConfig egl_config;
|
||||
EGLint n_config;
|
||||
if (!eglChooseConfig(self->egl_display, attributes, &egl_config, 1,
|
||||
&n_config)) {
|
||||
g_warning("Failed to choose EGL config");
|
||||
return FALSE;
|
||||
}
|
||||
if (n_config == 0) {
|
||||
g_warning("Failed to find appropriate EGL config");
|
||||
return FALSE;
|
||||
}
|
||||
if (!eglBindAPI(EGL_OPENGL_ES_API)) {
|
||||
g_warning("Failed to bind EGL OpenGL ES API");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Window xid = gdk_x11_window_get_xid(gtk_widget_get_window(GTK_WIDGET(self)));
|
||||
self->egl_surface =
|
||||
eglCreateWindowSurface(self->egl_display, egl_config, xid, nullptr);
|
||||
EGLint context_attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
|
||||
self->egl_context = eglCreateContext(self->egl_display, egl_config,
|
||||
EGL_NO_CONTEXT, context_attributes);
|
||||
EGLint value;
|
||||
eglQueryContext(self->egl_display, self->egl_context,
|
||||
EGL_CONTEXT_CLIENT_VERSION, &value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void* fl_view_gl_proc_resolver(void* user_data, const char* name) {
|
||||
return reinterpret_cast<void*>(eglGetProcAddress(name));
|
||||
}
|
||||
|
||||
static bool fl_view_gl_make_current(void* user_data) {
|
||||
FlView* self = static_cast<FlView*>(user_data);
|
||||
|
||||
if (!eglMakeCurrent(self->egl_display, self->egl_surface, self->egl_surface,
|
||||
self->egl_context))
|
||||
g_warning("Failed to make EGL context current");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool fl_view_gl_clear_current(void* user_data) {
|
||||
FlView* self = static_cast<FlView*>(user_data);
|
||||
|
||||
if (!eglMakeCurrent(self->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT))
|
||||
g_warning("Failed to make EGL context current");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t fl_view_gl_fbo_callback(void* user_data) {
|
||||
/* There is only one frame buffer object - always return that */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool fl_view_gl_present(void* user_data) {
|
||||
FlView* self = static_cast<FlView*>(user_data);
|
||||
|
||||
if (!eglSwapBuffers(self->egl_display, self->egl_surface))
|
||||
g_warning("Failed to swap EGL buffers");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static gboolean run_flutter_engine(FlView* self) {
|
||||
FlutterRendererConfig config = {};
|
||||
config.type = kOpenGL;
|
||||
config.open_gl.struct_size = sizeof(FlutterOpenGLRendererConfig);
|
||||
config.open_gl.gl_proc_resolver = fl_view_gl_proc_resolver;
|
||||
config.open_gl.make_current = fl_view_gl_make_current;
|
||||
config.open_gl.clear_current = fl_view_gl_clear_current;
|
||||
config.open_gl.fbo_callback = fl_view_gl_fbo_callback;
|
||||
config.open_gl.present = fl_view_gl_present;
|
||||
|
||||
FlutterProjectArgs args = {};
|
||||
args.struct_size = sizeof(FlutterProjectArgs);
|
||||
args.assets_path = fl_dart_project_get_assets_path(self->flutter_project);
|
||||
args.icu_data_path = fl_dart_project_get_icu_data_path(self->flutter_project);
|
||||
|
||||
FlutterEngineResult result = FlutterEngineInitialize(
|
||||
FLUTTER_ENGINE_VERSION, &config, &args, self, &self->flutter_engine);
|
||||
if (result != kSuccess)
|
||||
return FALSE;
|
||||
|
||||
result = FlutterEngineRunInitialized(self->flutter_engine);
|
||||
if (result != kSuccess)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void fl_view_set_property(GObject* object,
|
||||
guint prop_id,
|
||||
const GValue* value,
|
||||
GParamSpec* pspec) {
|
||||
FlView* self = FL_VIEW(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FLUTTER_PROJECT:
|
||||
g_set_object(&self->flutter_project,
|
||||
static_cast<FlDartProject*>(g_value_get_object(value)));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void fl_view_get_property(GObject* object,
|
||||
guint prop_id,
|
||||
GValue* value,
|
||||
GParamSpec* pspec) {
|
||||
FlView* self = FL_VIEW(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_FLUTTER_PROJECT:
|
||||
g_value_set_object(value, self->flutter_project);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void fl_view_dispose(GObject* object) {
|
||||
FlView* self = FL_VIEW(object);
|
||||
|
||||
FlutterEngineDeinitialize(self->flutter_engine);
|
||||
FlutterEngineShutdown(self->flutter_engine);
|
||||
|
||||
if (!eglDestroyContext(self->egl_display, self->egl_context))
|
||||
g_warning("Failed to destroy EGL context");
|
||||
if (!eglDestroySurface(self->egl_display, self->egl_surface))
|
||||
g_warning("Failed to destroy EGL surface");
|
||||
if (!eglTerminate(self->egl_display))
|
||||
g_warning("Failed to terminate EGL display");
|
||||
|
||||
g_clear_object(&self->flutter_project);
|
||||
|
||||
G_OBJECT_CLASS(fl_view_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void fl_view_realize(GtkWidget* widget) {
|
||||
FlView* self = FL_VIEW(widget);
|
||||
|
||||
gtk_widget_set_realized(widget, TRUE);
|
||||
|
||||
GtkAllocation allocation;
|
||||
gtk_widget_get_allocation(widget, &allocation);
|
||||
|
||||
GdkWindowAttr window_attributes;
|
||||
window_attributes.window_type = GDK_WINDOW_CHILD;
|
||||
window_attributes.x = allocation.x;
|
||||
window_attributes.y = allocation.y;
|
||||
window_attributes.width = allocation.width;
|
||||
window_attributes.height = allocation.height;
|
||||
window_attributes.wclass = GDK_INPUT_OUTPUT;
|
||||
window_attributes.visual = gtk_widget_get_visual(widget);
|
||||
window_attributes.event_mask =
|
||||
gtk_widget_get_events(widget) | GDK_EXPOSURE_MASK;
|
||||
|
||||
gint window_attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
|
||||
|
||||
GdkWindow* window =
|
||||
gdk_window_new(gtk_widget_get_parent_window(widget), &window_attributes,
|
||||
window_attributes_mask);
|
||||
gtk_widget_register_window(widget, window);
|
||||
gtk_widget_set_window(widget, window);
|
||||
|
||||
if (initialize_egl(self))
|
||||
run_flutter_engine(self);
|
||||
}
|
||||
|
||||
static void fl_view_size_allocate(GtkWidget* widget,
|
||||
GtkAllocation* allocation) {
|
||||
FlView* self = FL_VIEW(widget);
|
||||
|
||||
gtk_widget_set_allocation(widget, allocation);
|
||||
|
||||
if (gtk_widget_get_realized(widget) && gtk_widget_get_has_window(widget))
|
||||
gdk_window_move_resize(gtk_widget_get_window(widget), allocation->x,
|
||||
allocation->y, allocation->width,
|
||||
allocation->height);
|
||||
|
||||
FlutterWindowMetricsEvent event = {};
|
||||
event.struct_size = sizeof(FlutterWindowMetricsEvent);
|
||||
event.width = allocation->width;
|
||||
event.height = allocation->height;
|
||||
event.pixel_ratio =
|
||||
1; // TODO(robert-ancell): This won't work on hidpi displays
|
||||
FlutterEngineSendWindowMetricsEvent(self->flutter_engine, &event);
|
||||
}
|
||||
|
||||
static void fl_view_class_init(FlViewClass* klass) {
|
||||
G_OBJECT_CLASS(klass)->set_property = fl_view_set_property;
|
||||
G_OBJECT_CLASS(klass)->get_property = fl_view_get_property;
|
||||
G_OBJECT_CLASS(klass)->dispose = fl_view_dispose;
|
||||
GTK_WIDGET_CLASS(klass)->realize = fl_view_realize;
|
||||
GTK_WIDGET_CLASS(klass)->size_allocate = fl_view_size_allocate;
|
||||
|
||||
g_object_class_install_property(
|
||||
G_OBJECT_CLASS(klass), PROP_FLUTTER_PROJECT,
|
||||
g_param_spec_object(
|
||||
"flutter-project", "flutter-project", "Flutter project in use",
|
||||
fl_dart_project_get_type(),
|
||||
static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS)));
|
||||
}
|
||||
|
||||
static void fl_view_init(FlView* self) {}
|
||||
|
||||
/**
|
||||
* fl_view_new:
|
||||
* @project: The project to show.
|
||||
*
|
||||
* Create a widget to show Flutter application.
|
||||
*
|
||||
* Returns: a new #FlView
|
||||
*/
|
||||
G_MODULE_EXPORT FlView* fl_view_new(FlDartProject* project) {
|
||||
return static_cast<FlView*>(
|
||||
g_object_new(fl_view_get_type(), "flutter-project", project, nullptr));
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_DART_PROJECT_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_DART_PROJECT_H_
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#if !defined(__FLUTTER_LINUX_INSIDE__) && !defined(FLUTTER_LINUX_COMPILATION)
|
||||
#error "Only <flutter_linux/flutter_linux.h> can be included directly."
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlDartProject, fl_dart_project, FL, DART_PROJECT, GObject)
|
||||
|
||||
FlDartProject* fl_dart_project_new(const gchar* assets_path,
|
||||
const gchar* icu_data_path);
|
||||
|
||||
const gchar* fl_dart_project_get_assets_path(FlDartProject* project);
|
||||
|
||||
const gchar* fl_dart_project_get_icu_data_path(FlDartProject* project);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_DART_PROJECT_H_
|
||||
@ -0,0 +1,24 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_VIEW_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_VIEW_H_
|
||||
|
||||
#if !defined(__FLUTTER_LINUX_INSIDE__) && !defined(FLUTTER_LINUX_COMPILATION)
|
||||
#error "Only <flutter_linux/flutter_linux.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "fl_dart_project.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlView, fl_view, FL, VIEW, GtkWidget)
|
||||
|
||||
FlView* fl_view_new(FlDartProject* project);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_VIEW_H_
|
||||
@ -0,0 +1,15 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FLUTTER_LINUX_H_
|
||||
#define FLUTTER_SHELL_PLATFORM_LINUX_FLUTTER_LINUX_H_
|
||||
|
||||
#define __FLUTTER_LINUX_INSIDE__
|
||||
|
||||
#include <flutter_linux/fl_dart_project.h>
|
||||
#include <flutter_linux/fl_view.h>
|
||||
|
||||
#undef __FLUTTER_LINUX_INSIDE__
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_LINUX_FLUTTER_LINUX_H_
|
||||
Loading…
x
Reference in New Issue
Block a user