Flutter Engine
 
Loading...
Searching...
No Matches
fl_windowing_channel.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
6
9
10static constexpr char kChannelName[] = "flutter/windowing";
11static constexpr char kBadArgumentsError[] = "Bad Arguments";
12
13static constexpr char kCreateRegularMethod[] = "createRegular";
14static constexpr char kModifyRegularMethod[] = "modifyRegular";
15static constexpr char kDestroyWindowMethod[] = "destroyWindow";
16
17static constexpr char kSizeKey[] = "size";
18static constexpr char kMinSizeKey[] = "minSize";
19static constexpr char kMaxSizeKey[] = "maxSize";
20static constexpr char kTitleKey[] = "title";
21static constexpr char kStateKey[] = "state";
22static constexpr char kViewIdKey[] = "viewId";
23
26
27 FlMethodChannel* channel;
28
29 // Handlers for incoming method calls.
31
32 // User data to pass to method call handlers.
33 gpointer user_data;
34};
35
36G_DEFINE_TYPE(FlWindowingChannel, fl_windowing_channel, G_TYPE_OBJECT)
37
38// Returns TRUE if [args] is a valid size argument.
47
48G_DEFINE_AUTOPTR_CLEANUP_FUNC(FlWindowingSize, g_free)
49
51 FlWindowingSize* size = g_new0(FlWindowingSize, 1);
54 return size;
55}
56
57static gboolean parse_window_state_value(FlValue* value, FlWindowState* state) {
59 return FALSE;
60 }
61
62 const gchar* text = fl_value_get_string(value);
63 if (strcmp(text, "WindowState.restored") == 0) {
65 return TRUE;
66 } else if (strcmp(text, "WindowState.maximized") == 0) {
68 return TRUE;
69 } else if (strcmp(text, "WindowState.minimized") == 0) {
71 return TRUE;
72 }
73
74 return FALSE;
75}
76
77static const gchar* window_state_to_string(FlWindowState state) {
78 switch (state) {
80 return nullptr;
82 return "WindowState.restored";
84 return "WindowState.maximized";
86 return "WindowState.minimized";
87 }
88
89 return nullptr;
90}
91
92// Called when a regular window should be created.
93static FlMethodResponse* create_regular(FlWindowingChannel* self,
94 FlValue* args) {
96 return FL_METHOD_RESPONSE(fl_method_error_response_new(
97 kBadArgumentsError, "Argument map missing or malformed", nullptr));
98 }
99
101 if (size_value == nullptr || !is_valid_size_argument(size_value)) {
102 return FL_METHOD_RESPONSE(fl_method_error_response_new(
103 kBadArgumentsError, "Missing/invalid size argument", nullptr));
104 }
105 g_autoptr(FlWindowingSize) size = parse_size_value(size_value);
106
108 g_autoptr(FlWindowingSize) min_size = nullptr;
109 if (min_size_value != nullptr) {
110 if (!is_valid_size_argument(min_size_value)) {
111 return FL_METHOD_RESPONSE(fl_method_error_response_new(
112 kBadArgumentsError, "Invalid minSize argument", nullptr));
113 }
114 min_size = parse_size_value(min_size_value);
115 }
116
118 g_autoptr(FlWindowingSize) max_size = nullptr;
119 if (max_size_value != nullptr) {
120 if (!is_valid_size_argument(max_size_value)) {
121 return FL_METHOD_RESPONSE(fl_method_error_response_new(
122 kBadArgumentsError, "Invalid maxSize argument", nullptr));
123 }
124 max_size = parse_size_value(max_size_value);
125 }
126
128 const gchar* title = nullptr;
129 if (title_value != nullptr) {
130 if (fl_value_get_type(title_value) != FL_VALUE_TYPE_STRING) {
131 return FL_METHOD_RESPONSE(fl_method_error_response_new(
132 kBadArgumentsError, "Invalid title argument", nullptr));
133 }
134 title = fl_value_get_string(title_value);
135 }
138 if (state_value != nullptr) {
139 if (!parse_window_state_value(state_value, &state)) {
140 return FL_METHOD_RESPONSE(fl_method_error_response_new(
141 kBadArgumentsError, "Invalid state argument", nullptr));
142 }
143 }
144
145 return self->vtable->create_regular(size, min_size, max_size, title, state,
146 self->user_data);
147}
148
149// Called when a regular window should be created.
150static FlMethodResponse* modify_regular(FlWindowingChannel* self,
151 FlValue* args) {
153 return FL_METHOD_RESPONSE(fl_method_error_response_new(
154 kBadArgumentsError, "Argument map missing or malformed", nullptr));
155 }
156
158 if (view_id_value == nullptr ||
159 fl_value_get_type(view_id_value) != FL_VALUE_TYPE_INT) {
160 return FL_METHOD_RESPONSE(fl_method_error_response_new(
161 kBadArgumentsError, "Missing/invalid viewId argument", nullptr));
162 }
163 int64_t view_id = fl_value_get_int(view_id_value);
164
165 g_autoptr(FlWindowingSize) size = nullptr;
167 if (size_value != nullptr) {
168 if (!is_valid_size_argument(size_value)) {
169 return FL_METHOD_RESPONSE(fl_method_error_response_new(
170 kBadArgumentsError, "Invalid size argument", nullptr));
171 }
172 size = parse_size_value(size_value);
173 }
175 const gchar* title = nullptr;
176 if (title_value != nullptr) {
177 if (fl_value_get_type(title_value) != FL_VALUE_TYPE_STRING) {
178 return FL_METHOD_RESPONSE(fl_method_error_response_new(
179 kBadArgumentsError, "Invalid title argument", nullptr));
180 }
181 title = fl_value_get_string(title_value);
182 }
185 if (state_value != nullptr) {
186 if (!parse_window_state_value(state_value, &state)) {
187 return FL_METHOD_RESPONSE(fl_method_error_response_new(
188 kBadArgumentsError, "Invalid state argument", nullptr));
189 }
190 }
191
192 return self->vtable->modify_regular(view_id, size, title, state,
193 self->user_data);
194}
195
196// Called when a window should be destroyed.
197static FlMethodResponse* destroy_window(FlWindowingChannel* self,
198 FlValue* args) {
200 return FL_METHOD_RESPONSE(fl_method_error_response_new(
201 kBadArgumentsError, "Argument map missing or malformed", nullptr));
202 }
203
205 if (view_id_value == nullptr ||
206 fl_value_get_type(view_id_value) != FL_VALUE_TYPE_INT) {
207 return FL_METHOD_RESPONSE(fl_method_error_response_new(
208 kBadArgumentsError, "Missing/invalid viewId argument", nullptr));
209 }
210 int64_t view_id = fl_value_get_int(view_id_value);
211
212 return self->vtable->destroy_window(view_id, self->user_data);
213}
214
215// Called when a method call is received from Flutter.
216static void method_call_cb(FlMethodChannel* channel,
217 FlMethodCall* method_call,
218 gpointer user_data) {
219 FlWindowingChannel* self = FL_WINDOWING_CHANNEL(user_data);
220
221 const gchar* method = fl_method_call_get_name(method_call);
223 g_autoptr(FlMethodResponse) response = nullptr;
224
225 if (strcmp(method, kCreateRegularMethod) == 0) {
226 response = create_regular(self, args);
227 } else if (strcmp(method, kModifyRegularMethod) == 0) {
228 response = modify_regular(self, args);
229 } else if (strcmp(method, kDestroyWindowMethod) == 0) {
230 response = destroy_window(self, args);
231 } else {
232 response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
233 }
234
235 if (response != nullptr) {
236 g_autoptr(GError) error = nullptr;
237 if (!fl_method_call_respond(method_call, response, &error)) {
238 g_warning("Failed to send method call response: %s", error->message);
239 }
240 }
241}
242
243static void fl_windowing_channel_dispose(GObject* object) {
244 FlWindowingChannel* self = FL_WINDOWING_CHANNEL(object);
245
246 g_clear_object(&self->channel);
247
248 G_OBJECT_CLASS(fl_windowing_channel_parent_class)->dispose(object);
249}
250
251static void fl_windowing_channel_class_init(FlWindowingChannelClass* klass) {
252 G_OBJECT_CLASS(klass)->dispose = fl_windowing_channel_dispose;
253}
254
255static void fl_windowing_channel_init(FlWindowingChannel* self) {}
256
257FlWindowingChannel* fl_windowing_channel_new(FlBinaryMessenger* messenger,
259 gpointer user_data) {
260 FlWindowingChannel* self = FL_WINDOWING_CHANNEL(
261 g_object_new(fl_windowing_channel_get_type(), nullptr));
262
263 self->vtable = vtable;
264 self->user_data = user_data;
265
266 g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
267 self->channel =
268 fl_method_channel_new(messenger, kChannelName, FL_METHOD_CODEC(codec));
270 nullptr);
271
272 return self;
273}
274
276 int64_t view_id,
277 FlWindowingSize* size,
278 FlWindowState state) {
281 g_autoptr(FlValue) size_value = fl_value_new_list();
282 fl_value_append_take(size_value, fl_value_new_float(size->width));
283 fl_value_append_take(size_value, fl_value_new_float(size->height));
284 fl_value_set_string(result, kSizeKey, size_value);
287 return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
288}
289
291 return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
292}
293
295 return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
296}
int32_t value
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle, fl_basic_message_channel_response_handle, G_TYPE_OBJECT) static void fl_basic_message_channel_response_handle_dispose(GObject *object)
g_autoptr(GMutexLocker) locker
return TRUE
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_MODULE_EXPORT const gchar * fl_method_call_get_name(FlMethodCall *self)
G_MODULE_EXPORT gboolean fl_method_call_respond(FlMethodCall *self, FlMethodResponse *response, GError **error)
G_MODULE_EXPORT FlValue * fl_method_call_get_args(FlMethodCall *self)
G_MODULE_EXPORT FlMethodChannel * fl_method_channel_new(FlBinaryMessenger *messenger, const gchar *name, FlMethodCodec *codec)
G_MODULE_EXPORT void fl_method_channel_set_method_call_handler(FlMethodChannel *self, FlMethodChannelMethodCallHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
G_BEGIN_DECLS G_MODULE_EXPORT FlMethodCall * method_call
G_MODULE_EXPORT FlMethodErrorResponse * fl_method_error_response_new(const gchar *code, const gchar *message, FlValue *details)
G_MODULE_EXPORT FlMethodSuccessResponse * fl_method_success_response_new(FlValue *result)
G_MODULE_EXPORT FlMethodNotImplementedResponse * fl_method_not_implemented_response_new()
const gchar * channel
const uint8_t uint32_t uint32_t GError ** error
G_MODULE_EXPORT FlStandardMethodCodec * fl_standard_method_codec_new()
G_MODULE_EXPORT void fl_value_set_string(FlValue *self, const gchar *key, FlValue *value)
Definition fl_value.cc:639
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition fl_value.cc:366
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
Definition fl_value.cc:650
G_MODULE_EXPORT FlValue * fl_value_lookup_string(FlValue *self, const gchar *key)
Definition fl_value.cc:811
G_MODULE_EXPORT int64_t fl_value_get_int(FlValue *self)
Definition fl_value.cc:668
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition fl_value.cc:466
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition fl_value.cc:276
G_MODULE_EXPORT const gchar * fl_value_get_string(FlValue *self)
Definition fl_value.cc:682
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition fl_value.cc:262
G_MODULE_EXPORT FlValue * fl_value_new_float(double value)
Definition fl_value.cc:269
G_MODULE_EXPORT void fl_value_append_take(FlValue *self, FlValue *value)
Definition fl_value.cc:600
G_MODULE_EXPORT FlValue * fl_value_get_list_value(FlValue *self, size_t index)
Definition fl_value.cc:776
G_MODULE_EXPORT FlValue * fl_value_new_list()
Definition fl_value.cc:349
G_MODULE_EXPORT double fl_value_get_float(FlValue *self)
Definition fl_value.cc:675
G_MODULE_EXPORT size_t fl_value_get_length(FlValue *self)
Definition fl_value.cc:724
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition fl_value.h:42
@ FL_VALUE_TYPE_STRING
Definition fl_value.h:68
@ FL_VALUE_TYPE_INT
Definition fl_value.h:66
@ FL_VALUE_TYPE_LIST
Definition fl_value.h:73
@ FL_VALUE_TYPE_MAP
Definition fl_value.h:74
@ FL_VALUE_TYPE_FLOAT
Definition fl_value.h:67
G_BEGIN_DECLS FlutterViewId view_id
static void method_call_cb(FlMethodChannel *channel, FlMethodCall *method_call, gpointer user_data)
FlWindowingChannel * fl_windowing_channel_new(FlBinaryMessenger *messenger, FlWindowingChannelVTable *vtable, gpointer user_data)
static FlMethodResponse * destroy_window(FlWindowingChannel *self, FlValue *args)
static void fl_windowing_channel_class_init(FlWindowingChannelClass *klass)
static constexpr char kStateKey[]
static FlMethodResponse * modify_regular(FlWindowingChannel *self, FlValue *args)
static FlWindowingSize * parse_size_value(FlValue *value)
static constexpr char kCreateRegularMethod[]
static constexpr char kMaxSizeKey[]
static const gchar * window_state_to_string(FlWindowState state)
static constexpr char kViewIdKey[]
static void fl_windowing_channel_init(FlWindowingChannel *self)
static constexpr char kSizeKey[]
FlMethodResponse * fl_windowing_channel_make_create_regular_response(int64_t view_id, FlWindowingSize *size, FlWindowState state)
static constexpr char kDestroyWindowMethod[]
static constexpr char kMinSizeKey[]
static FlMethodResponse * create_regular(FlWindowingChannel *self, FlValue *args)
static constexpr char kChannelName[]
static gboolean is_valid_size_argument(FlValue *value)
static gboolean parse_window_state_value(FlValue *value, FlWindowState *state)
FlMethodResponse * fl_windowing_channel_make_modify_regular_response()
static constexpr char kTitleKey[]
static constexpr char kModifyRegularMethod[]
static constexpr char kBadArgumentsError[]
static void fl_windowing_channel_dispose(GObject *object)
FlMethodResponse * fl_windowing_channel_make_destroy_window_response()
@ FL_WINDOW_STATE_UNDEFINED
@ FL_WINDOW_STATE_MINIMIZED
@ FL_WINDOW_STATE_MAXIMIZED
@ FL_WINDOW_STATE_RESTORED
std::u16string text
FlWindowingChannelVTable * vtable
FlMethodChannel * channel