| Flutter Linux Embedder |

fl_mouse_cursor_handler.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/linux/fl_mouse_cursor_handler.h"
6
7 #include <cstring>
8
9 #include "flutter/shell/platform/linux/fl_mouse_cursor_channel.h"
10
11 static constexpr char kFallbackCursor[] = "default";
12
13 struct _FlMouseCursorHandler {
14 GObject parent_instance;
15
16 FlMouseCursorChannel* channel;
17
18 GHashTable* system_cursor_table;
19
20 // The current cursor.
21 gchar* cursor_name;
22 };
23
24 enum { SIGNAL_CURSOR_CHANGED, LAST_SIGNAL };
25
26 static guint fl_mouse_cursor_handler_signals[LAST_SIGNAL];
27
28 G_DEFINE_TYPE(FlMouseCursorHandler, fl_mouse_cursor_handler, G_TYPE_OBJECT)
29
30 // Insert a new entry into a hashtable from strings to strings.
31 //
32 // Returns whether the newly added value was already in the hash table or not.
33 static bool define_system_cursor(GHashTable* table,
34 const gchar* key,
35 const gchar* value) {
36 return g_hash_table_insert(
37 table, reinterpret_cast<gpointer>(const_cast<gchar*>(key)),
38 reinterpret_cast<gpointer>(const_cast<gchar*>(value)));
39 }
40
41 // Populate the hash table so that it maps from Flutter's cursor kinds to GTK's
42 // cursor values.
43 //
44 // The table must have been created as a hashtable from strings to strings.
45 static void populate_system_cursor_table(GHashTable* table) {
46 // The following mapping must be kept in sync with Flutter framework's
47 // mouse_cursor.dart.
48 define_system_cursor(table, "alias", "alias");
49 define_system_cursor(table, "allScroll", "all-scroll");
50 define_system_cursor(table, "basic", "default");
51 define_system_cursor(table, "cell", "cell");
52 define_system_cursor(table, "click", "pointer");
53 define_system_cursor(table, "contextMenu", "context-menu");
54 define_system_cursor(table, "copy", "copy");
55 define_system_cursor(table, "forbidden", "not-allowed");
56 define_system_cursor(table, "grab", "grab");
57 define_system_cursor(table, "grabbing", "grabbing");
58 define_system_cursor(table, "help", "help");
59 define_system_cursor(table, "move", "move");
60 define_system_cursor(table, "none", "none");
61 define_system_cursor(table, "noDrop", "no-drop");
62 define_system_cursor(table, "precise", "crosshair");
63 define_system_cursor(table, "progress", "progress");
64 define_system_cursor(table, "text", "text");
65 define_system_cursor(table, "resizeColumn", "col-resize");
66 define_system_cursor(table, "resizeDown", "s-resize");
67 define_system_cursor(table, "resizeDownLeft", "sw-resize");
68 define_system_cursor(table, "resizeDownRight", "se-resize");
69 define_system_cursor(table, "resizeLeft", "w-resize");
70 define_system_cursor(table, "resizeLeftRight", "ew-resize");
71 define_system_cursor(table, "resizeRight", "e-resize");
72 define_system_cursor(table, "resizeRow", "row-resize");
73 define_system_cursor(table, "resizeUp", "n-resize");
74 define_system_cursor(table, "resizeUpDown", "ns-resize");
75 define_system_cursor(table, "resizeUpLeft", "nw-resize");
76 define_system_cursor(table, "resizeUpRight", "ne-resize");
77 define_system_cursor(table, "resizeUpLeftDownRight", "nwse-resize");
78 define_system_cursor(table, "resizeUpRightDownLeft", "nesw-resize");
79 define_system_cursor(table, "verticalText", "vertical-text");
80 define_system_cursor(table, "wait", "wait");
81 define_system_cursor(table, "zoomIn", "zoom-in");
82 define_system_cursor(table, "zoomOut", "zoom-out");
83 }
84
85 // Sets the mouse cursor.
86 static void activate_system_cursor(const gchar* kind, gpointer user_data) {
87 FlMouseCursorHandler* self = FL_MOUSE_CURSOR_HANDLER(user_data);
88
89 if (self->system_cursor_table == nullptr) {
90 self->system_cursor_table = g_hash_table_new(g_str_hash, g_str_equal);
91 populate_system_cursor_table(self->system_cursor_table);
92 }
93
94 const gchar* cursor_name = reinterpret_cast<const gchar*>(
95 g_hash_table_lookup(self->system_cursor_table, kind));
96 if (cursor_name == nullptr) {
97 cursor_name = kFallbackCursor;
98 }
99
100 g_free(self->cursor_name);
101 self->cursor_name = g_strdup(cursor_name);
102
103 g_signal_emit(self, fl_mouse_cursor_handler_signals[SIGNAL_CURSOR_CHANGED],
104 0);
105 }
106
107 static void fl_mouse_cursor_handler_dispose(GObject* object) {
108 FlMouseCursorHandler* self = FL_MOUSE_CURSOR_HANDLER(object);
109
110 g_clear_object(&self->channel);
111 g_clear_pointer(&self->system_cursor_table, g_hash_table_unref);
112 g_clear_pointer(&self->cursor_name, g_free);
113
114 G_OBJECT_CLASS(fl_mouse_cursor_handler_parent_class)->dispose(object);
115 }
116
117 static void fl_mouse_cursor_handler_class_init(
118 FlMouseCursorHandlerClass* klass) {
119 G_OBJECT_CLASS(klass)->dispose = fl_mouse_cursor_handler_dispose;
120
121 fl_mouse_cursor_handler_signals[SIGNAL_CURSOR_CHANGED] =
122 g_signal_new("cursor-changed", fl_mouse_cursor_handler_get_type(),
123 G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
124 }
125
126 static void fl_mouse_cursor_handler_init(FlMouseCursorHandler* self) {
127 self->cursor_name = g_strdup("");
128 }
129
130 static FlMouseCursorChannelVTable mouse_cursor_vtable = {
131 .activate_system_cursor = activate_system_cursor,
132 };
133
134 FlMouseCursorHandler* fl_mouse_cursor_handler_new(
135 FlBinaryMessenger* messenger) {
136 g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
137
138 FlMouseCursorHandler* self = FL_MOUSE_CURSOR_HANDLER(
139 g_object_new(fl_mouse_cursor_handler_get_type(), nullptr));
140
141 self->channel =
142 fl_mouse_cursor_channel_new(messenger, &mouse_cursor_vtable, self);
143
144 return self;
145 }
146
147 const gchar* fl_mouse_cursor_handler_get_cursor_name(
148 FlMouseCursorHandler* self) {
149 g_return_val_if_fail(FL_IS_MOUSE_CURSOR_HANDLER(self), nullptr);
150 return self->cursor_name;
151 }
user_data
const char FlTextDirection FlAssertiveness gpointer user_data
Definition: fl_accessibility_handler.cc:24
G_DEFINE_TYPE
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle, fl_basic_message_channel_response_handle, G_TYPE_OBJECT) static void fl_basic_message_channel_response_handle_dispose(GObject *object)
Definition: fl_basic_message_channel.cc:37
fl_mouse_cursor_channel_new
FlMouseCursorChannel * fl_mouse_cursor_channel_new(FlBinaryMessenger *messenger, FlMouseCursorChannelVTable *vtable, gpointer user_data)
Definition: fl_mouse_cursor_channel.cc:85
fl_mouse_cursor_channel.h
populate_system_cursor_table
static void populate_system_cursor_table(GHashTable *table)
Definition: fl_mouse_cursor_handler.cc:45
fl_mouse_cursor_handler_get_cursor_name
const gchar * fl_mouse_cursor_handler_get_cursor_name(FlMouseCursorHandler *self)
Definition: fl_mouse_cursor_handler.cc:147
fl_mouse_cursor_handler_new
FlMouseCursorHandler * fl_mouse_cursor_handler_new(FlBinaryMessenger *messenger)
Definition: fl_mouse_cursor_handler.cc:134
activate_system_cursor
static void activate_system_cursor(const gchar *kind, gpointer user_data)
Definition: fl_mouse_cursor_handler.cc:86
fl_mouse_cursor_handler_init
static void fl_mouse_cursor_handler_init(FlMouseCursorHandler *self)
Definition: fl_mouse_cursor_handler.cc:126
kFallbackCursor
static constexpr char kFallbackCursor[]
Definition: fl_mouse_cursor_handler.cc:11
fl_mouse_cursor_handler_class_init
static void fl_mouse_cursor_handler_class_init(FlMouseCursorHandlerClass *klass)
Definition: fl_mouse_cursor_handler.cc:117
fl_mouse_cursor_handler_signals
static guint fl_mouse_cursor_handler_signals[LAST_SIGNAL]
Definition: fl_mouse_cursor_handler.cc:26
define_system_cursor
static bool define_system_cursor(GHashTable *table, const gchar *key, const gchar *value)
Definition: fl_mouse_cursor_handler.cc:33
mouse_cursor_vtable
static FlMouseCursorChannelVTable mouse_cursor_vtable
Definition: fl_mouse_cursor_handler.cc:130
LAST_SIGNAL
@ LAST_SIGNAL
Definition: fl_mouse_cursor_handler.cc:24
SIGNAL_CURSOR_CHANGED
@ SIGNAL_CURSOR_CHANGED
Definition: fl_mouse_cursor_handler.cc:24
fl_mouse_cursor_handler_dispose
static void fl_mouse_cursor_handler_dispose(GObject *object)
Definition: fl_mouse_cursor_handler.cc:107
fl_mouse_cursor_handler.h
value
uint8_t value
Definition: fl_standard_message_codec.cc:36
_FlMouseCursorHandler
Definition: fl_mouse_cursor_handler.cc:13
_FlMouseCursorHandler::system_cursor_table
GHashTable * system_cursor_table
Definition: fl_mouse_cursor_handler.cc:18
_FlMouseCursorHandler::channel
FlMouseCursorChannel * channel
Definition: fl_mouse_cursor_handler.cc:16
_FlMouseCursorHandler::parent_instance
GObject parent_instance
Definition: fl_mouse_cursor_handler.cc:14
_FlMouseCursorHandler::cursor_name
gchar * cursor_name
Definition: fl_mouse_cursor_handler.cc:21
FlMouseCursorChannelVTable
Definition: fl_mouse_cursor_channel.h:25
FlMouseCursorChannelVTable::activate_system_cursor
void(* activate_system_cursor)(const gchar *kind, gpointer user_data)
Definition: fl_mouse_cursor_channel.h:26