| Flutter Linux Embedder |

Classes | Functions | Variables
fl_key_embedder_responder.cc File Reference
`#include "flutter/shell/platform/linux/fl_key_embedder_responder.h"`
`#include <gtk/gtk.h>`
`#include <cinttypes>`
`#include "flutter/shell/platform/embedder/embedder.h"`
`#include "flutter/shell/platform/linux/fl_key_embedder_responder_private.h"`
`#include "flutter/shell/platform/linux/key_mapping.h"`

Go to the source code of this file.

## Classes
struct | _FlKeyEmbedderUserData
struct | _FlKeyEmbedderResponder

## Functions
static uint64_t | lookup_hash_table (GHashTable *table, uint64_t key)
static gboolean | hash_table_find_equal_value (gpointer key, gpointer value, gpointer user_data)
static uint64_t | reverse_lookup_hash_table (GHashTable *table, uint64_t value)
static uint64_t | to_lower (uint64_t n)
| G_DECLARE_FINAL_TYPE (FlKeyEmbedderUserData, fl_key_embedder_user_data, FL, KEY_EMBEDDER_USER_DATA, GObject)
static void | fl_key_embedder_user_data_dispose (GObject *object)
static void | fl_key_embedder_user_data_class_init (FlKeyEmbedderUserDataClass *klass)
static void | fl_key_embedder_user_data_init (FlKeyEmbedderUserData *self)
static FlKeyEmbedderUserData * | fl_key_embedder_user_data_new (FlKeyEmbedderResponderAsyncCallback callback, gpointer user_data)
static void | fl_key_embedder_responder_dispose (GObject *object)
static void | fl_key_embedder_responder_class_init (FlKeyEmbedderResponderClass *klass)
static void | fl_key_embedder_responder_init (FlKeyEmbedderResponder *self)
static void | initialize_logical_key_to_lock_bit_loop_body (gpointer lock_bit, gpointer value, gpointer user_data)
FlKeyEmbedderResponder * | fl_key_embedder_responder_new (EmbedderSendKeyEvent send_key_event, void *send_key_event_user_data)
static uint64_t | apply_id_plane (uint64_t logical_id, uint64_t plane)
static uint64_t | event_to_physical_key (FlKeyEvent *event)
static uint64_t | event_to_logical_key (FlKeyEvent *event)
static uint64_t | event_to_timestamp (FlKeyEvent *event)
static char * | event_to_character (FlKeyEvent *event)
static void | handle_response (bool handled, gpointer user_data)
static void | synthesize_simple_event (FlKeyEmbedderResponder *self, FlutterKeyEventType type, uint64_t physical, uint64_t logical, double timestamp)
static void | update_pressing_state (FlKeyEmbedderResponder *self, uint64_t physical_key, uint64_t logical_key)
static void | possibly_update_lock_bit (FlKeyEmbedderResponder *self, uint64_t logical_key, bool is_down)
static void | update_mapping_record (FlKeyEmbedderResponder *self, uint64_t physical_key, uint64_t logical_key)
static void | synchronize_pressed_states_loop_body (gpointer key, gpointer value, gpointer user_data)
static int | find_stage_by_record (bool is_down, bool is_enabled)
static int | find_stage_by_self_event (int stage_by_record, bool is_down_event, bool is_state_on, bool reverse_state_logic)
static int | find_stage_by_others_event (int stage_by_record, bool is_state_on)
static void | update_caps_lock_state_logic_inferrence (FlKeyEmbedderResponder *self, bool is_down_event, bool enabled_by_state, int stage_by_record)
static void | synchronize_lock_states_loop_body (gpointer key, gpointer value, gpointer user_data)
static void | is_known_modifier_physical_key_loop_body (gpointer key, gpointer value, gpointer user_data)
static void | find_physical_from_logical_loop_body (gpointer key, gpointer value, gpointer user_data)
static uint64_t | corrected_modifier_physical_key (GHashTable *modifier_bit_to_checked_keys, uint64_t physical_key_from_event, uint64_t logical_key)
static void | fl_key_embedder_responder_handle_event_impl (FlKeyEmbedderResponder *responder, FlKeyEvent *event, uint64_t specified_logical_key, FlKeyEmbedderResponderAsyncCallback callback, gpointer user_data)
void | fl_key_embedder_responder_handle_event (FlKeyEmbedderResponder *self, FlKeyEvent *event, uint64_t specified_logical_key, FlKeyEmbedderResponderAsyncCallback callback, gpointer user_data)
void | fl_key_embedder_responder_sync_modifiers_if_needed (FlKeyEmbedderResponder *responder, guint state, double event_time)
GHashTable * | fl_key_embedder_responder_get_pressed_state (FlKeyEmbedderResponder *self)

## Variables
constexpr uint64_t | kMicrosecondsPerMillisecond = 1000
static const FlutterKeyEvent | kEmptyEvent

## Function Documentation

## ◆ apply_id_plane()

static uint64_t apply_id_plane | ( | uint64_t | logical_id,
|  | uint64_t | plane
| ) |  |
| static

Definition at line 268 of file fl_key_embedder_responder.cc.

268 {
269 return (logical_id & kValueMask) | plane;
270 }
kValueMask
const uint64_t kValueMask
Definition: key_mapping.g.cc:514

References kValueMask.

Referenced by event_to_logical_key(), and event_to_physical_key().

## ◆ corrected_modifier_physical_key()

static uint64_t corrected_modifier_physical_key | ( | GHashTable * | modifier_bit_to_checked_keys,
|  | uint64_t | physical_key_from_event,
|  | uint64_t | logical_key
| ) |  |
| static

Definition at line 721 of file fl_key_embedder_responder.cc.

724 {
725 ModifierLogicalToPhysicalContext logical_to_physical_context;
726 logical_to_physical_context.known_modifier_physical_key = false;
727 logical_to_physical_context.physical_key_from_event = physical_key_from_event;
728 logical_to_physical_context.logical_key = logical_key;
729 // If no match is found, defaults to the physical key retrieved from the
730 // event.
731 logical_to_physical_context.corrected_physical_key = physical_key_from_event;
732
733 // Check if the physical key is one of the known modifier physical key.
734 g_hash_table_foreach(modifier_bit_to_checked_keys,
735 is_known_modifier_physical_key_loop_body,
736 &logical_to_physical_context);
737
738 // If the physical key matches a known modifier key, find the modifier
739 // physical key from the logical key.
740 if (logical_to_physical_context.known_modifier_physical_key) {
741 g_hash_table_foreach(modifier_bit_to_checked_keys,
742 find_physical_from_logical_loop_body,
743 &logical_to_physical_context);
744 }
745
746 return logical_to_physical_context.corrected_physical_key;
747 }
find_physical_from_logical_loop_body
static void find_physical_from_logical_loop_body(gpointer key, gpointer value, gpointer user_data)
Definition: fl_key_embedder_responder.cc:707
is_known_modifier_physical_key_loop_body
static void is_known_modifier_physical_key_loop_body(gpointer key, gpointer value, gpointer user_data)
Definition: fl_key_embedder_responder.cc:690

References find_physical_from_logical_loop_body(), and is_known_modifier_physical_key_loop_body().

Referenced by fl_key_embedder_responder_handle_event_impl().

## ◆ event_to_character()

static char* event_to_character | ( | FlKeyEvent * | event | ) |
| static

Definition at line 301 of file fl_key_embedder_responder.cc.

301 {
302 gunichar unicodeChar = gdk_keyval_to_unicode(fl_key_event_get_keyval(event));
303 glong items_written;
304 gchar* result = g_ucs4_to_utf8(&unicodeChar, 1, NULL, &items_written, NULL);
305 if (items_written == 0) {
306 if (result != NULL) {
307 g_free(result);
308 }
309 return nullptr;
310 }
311 return result;
312 }
fl_key_event_get_keyval
guint fl_key_event_get_keyval(FlKeyEvent *self)
Definition: fl_key_event.cc:94

References fl_key_event_get_keyval().

Referenced by fl_key_embedder_responder_handle_event_impl().

## ◆ event_to_logical_key()

static uint64_t event_to_logical_key | ( | FlKeyEvent * | event | ) |
| static

Definition at line 280 of file fl_key_embedder_responder.cc.

280 {
281 guint keyval = fl_key_event_get_keyval(event);
282 auto found = gtk_keyval_to_logical_key_map.find(keyval);
283 if (found != gtk_keyval_to_logical_key_map.end()) {
284 return found->second;
285 }
286 // EASCII range
287 if (keyval < 256) {
288 return apply_id_plane(to_lower(keyval), kUnicodePlane);
289 }
290 // Auto-generate key
291 return apply_id_plane(keyval, kGtkPlane);
292 }
apply_id_plane
static uint64_t apply_id_plane(uint64_t logical_id, uint64_t plane)
Definition: fl_key_embedder_responder.cc:268
to_lower
static uint64_t to_lower(uint64_t n)
Definition: fl_key_embedder_responder.cc:53
kGtkPlane
const uint64_t kGtkPlane
Definition: key_mapping.g.cc:516
kUnicodePlane
const uint64_t kUnicodePlane
Definition: key_mapping.g.cc:515
gtk_keyval_to_logical_key_map
std::map< uint64_t, uint64_t > gtk_keyval_to_logical_key_map
Definition: key_mapping.g.cc:240

References apply_id_plane(), fl_key_event_get_keyval(), gtk_keyval_to_logical_key_map, kGtkPlane, kUnicodePlane, and to_lower().

Referenced by fl_key_embedder_responder_handle_event_impl().

## ◆ event_to_physical_key()

static uint64_t event_to_physical_key | ( | FlKeyEvent * | event | ) |
| static

Definition at line 272 of file fl_key_embedder_responder.cc.

272 {
273 auto found = xkb_to_physical_key_map.find(fl_key_event_get_keycode(event));
274 if (found != xkb_to_physical_key_map.end()) {
275 return found->second;
276 }
277 return apply_id_plane(fl_key_event_get_keycode(event), kGtkPlane);
278 }
fl_key_event_get_keycode
guint16 fl_key_event_get_keycode(FlKeyEvent *self)
Definition: fl_key_event.cc:89
xkb_to_physical_key_map
std::map< uint64_t, uint64_t > xkb_to_physical_key_map
Definition: key_mapping.g.cc:20

References apply_id_plane(), fl_key_event_get_keycode(), kGtkPlane, and xkb_to_physical_key_map.

Referenced by fl_key_embedder_responder_handle_event_impl().

## ◆ event_to_timestamp()

static uint64_t event_to_timestamp | ( | FlKeyEvent * | event | ) |
| static

Definition at line 294 of file fl_key_embedder_responder.cc.

294 {
295 return kMicrosecondsPerMillisecond *
296 static_cast<double>(fl_key_event_get_time(event));
297 }
kMicrosecondsPerMillisecond
constexpr uint64_t kMicrosecondsPerMillisecond
Definition: fl_key_embedder_responder.cc:14
fl_key_event_get_time
guint32 fl_key_event_get_time(FlKeyEvent *self)
Definition: fl_key_event.cc:79

References fl_key_event_get_time(), and kMicrosecondsPerMillisecond.

Referenced by fl_key_embedder_responder_handle_event_impl().

## ◆ find_physical_from_logical_loop_body()

static void find_physical_from_logical_loop_body | ( | gpointer | key,
|  | gpointer | value,
|  | gpointer | user_data
| ) |  |
| static

Definition at line 707 of file fl_key_embedder_responder.cc.

709 {
710 ModifierLogicalToPhysicalContext* context =
711 reinterpret_cast<ModifierLogicalToPhysicalContext*>(user_data);
712 FlKeyEmbedderCheckedKey* checked_key =
713 reinterpret_cast<FlKeyEmbedderCheckedKey*>(value);
714
715 if (checked_key->primary_logical_key == context->logical_key ||
716 checked_key->secondary_logical_key == context->logical_key) {
717 context->corrected_physical_key = checked_key->primary_physical_key;
718 }
719 }
user_data
G_BEGIN_DECLS G_MODULE_EXPORT FlValue gpointer user_data
Definition: fl_event_channel.h:90
value
uint8_t value
Definition: fl_standard_message_codec.cc:36
FlKeyEmbedderCheckedKey
Definition: fl_key_embedder_responder_private.h:33
FlKeyEmbedderCheckedKey::primary_physical_key
uint64_t primary_physical_key
Definition: fl_key_embedder_responder_private.h:35
FlKeyEmbedderCheckedKey::primary_logical_key
uint64_t primary_logical_key
Definition: fl_key_embedder_responder_private.h:37
FlKeyEmbedderCheckedKey::secondary_logical_key
uint64_t secondary_logical_key
Definition: fl_key_embedder_responder_private.h:39

References FlKeyEmbedderCheckedKey::primary_logical_key, FlKeyEmbedderCheckedKey::primary_physical_key, FlKeyEmbedderCheckedKey::secondary_logical_key, user_data, and value.

Referenced by corrected_modifier_physical_key().

## ◆ find_stage_by_others_event()

static int find_stage_by_others_event | ( | int | stage_by_record,
|  | bool | is_state_on
| ) |  |
| static

Definition at line 528 of file fl_key_embedder_responder.cc.

528 {
529 g_return_val_if_fail(stage_by_record >= 0 && stage_by_record < 4,
530 stage_by_record);
531 if (!is_state_on) {
532 return 0;
533 }
534 if (stage_by_record == 0) {
535 return 1;
536 }
537 return stage_by_record;
538 }

Referenced by synchronize_lock_states_loop_body().

## ◆ find_stage_by_record()

static int find_stage_by_record | ( | bool | is_down,
|  | bool | is_enabled
| ) |  |
| static

Definition at line 501 of file fl_key_embedder_responder.cc.

501 {
502 constexpr int stage_by_record_index[] = {
503 0, // is_down: 0, is_enabled: 0
504 2, // 0 1
505 3, // 1 0
506 1 // 1 1
507 };
508 return stage_by_record_index[(is_down << 1) + is_enabled];
509 }

Referenced by synchronize_lock_states_loop_body().

## ◆ find_stage_by_self_event()

static int find_stage_by_self_event | ( | int | stage_by_record,
|  | bool | is_down_event,
|  | bool | is_state_on,
|  | bool | reverse_state_logic
| ) |  |
| static

Definition at line 513 of file fl_key_embedder_responder.cc.

516 {
517 if (!is_state_on) {
518 return reverse_state_logic ? 2 : 0;
519 }
520 if (is_down_event) {
521 return reverse_state_logic ? 0 : 2;
522 }
523 return stage_by_record;
524 }

Referenced by synchronize_lock_states_loop_body(), and update_caps_lock_state_logic_inferrence().

## ◆ fl_key_embedder_responder_class_init()

static void fl_key_embedder_responder_class_init | ( | FlKeyEmbedderResponderClass * | klass | ) |
| static

Definition at line 200 of file fl_key_embedder_responder.cc.

201 {
202 G_OBJECT_CLASS(klass)->dispose = fl_key_embedder_responder_dispose;
203 }
fl_key_embedder_responder_dispose
static void fl_key_embedder_responder_dispose(GObject *object)
Definition: fl_key_embedder_responder.cc:209

References fl_key_embedder_responder_dispose().

## ◆ fl_key_embedder_responder_dispose()

static void fl_key_embedder_responder_dispose | ( | GObject * | object | ) |
| static

Definition at line 209 of file fl_key_embedder_responder.cc.

209 {
210 FlKeyEmbedderResponder* self = FL_KEY_EMBEDDER_RESPONDER(object);
211
212 g_clear_pointer(&self->pressing_records, g_hash_table_unref);
213 g_clear_pointer(&self->mapping_records, g_hash_table_unref);
214 g_clear_pointer(&self->modifier_bit_to_checked_keys, g_hash_table_unref);
215 g_clear_pointer(&self->lock_bit_to_checked_keys, g_hash_table_unref);
216 g_clear_pointer(&self->logical_key_to_lock_bit, g_hash_table_unref);
217
218 G_OBJECT_CLASS(fl_key_embedder_responder_parent_class)->dispose(object);
219 }

Referenced by fl_key_embedder_responder_class_init().

## ◆ fl_key_embedder_responder_get_pressed_state()

GHashTable* fl_key_embedder_responder_get_pressed_state | ( | FlKeyEmbedderResponder * | responder | ) |

fl_key_embedder_responder_get_pressed_state: @responder: the #FlKeyEmbedderResponder self.

Returns the keyboard pressed state. The hash table contains one entry per pressed keys, mapping from the logical key to the physical key.

Definition at line 867 of file fl_key_embedder_responder.cc.

868 {
869 return self->pressing_records;
870 }

Referenced by fl_keyboard_manager_get_pressed_state().

## ◆ fl_key_embedder_responder_handle_event()

void fl_key_embedder_responder_handle_event | ( | FlKeyEmbedderResponder * | responder,
|  | FlKeyEvent * | event,
|  | uint64_t | specified_logical_key,
|  | FlKeyEmbedderResponderAsyncCallback | callback,
|  | gpointer | user_data
| ) |  |

fl_key_embedder_responder_handle_event: @responder: the #FlKeyEmbedderResponder self. @event: the event to be handled. Must not be null. The object is managed by callee and must not be assumed available after this function. @specified_logical_key: @callback: the callback to report the result. It should be called exactly once. Must not be null. @user_data: a value that will be sent back in the callback. Can be null.

Let the responder handle an event, expecting the responder to report whether to handle the event. The result will be reported by invoking `callback` exactly once, which might happen after `fl_key_embedder_responder_handle_event` or during it.

Definition at line 835 of file fl_key_embedder_responder.cc.

840 {
841 self->sent_any_events = false;
842 fl_key_embedder_responder_handle_event_impl(
843 self, event, specified_logical_key, callback, user_data);
844 if (!self->sent_any_events) {
845 self->send_key_event(&kEmptyEvent, nullptr, nullptr,
846 self->send_key_event_user_data);
847 }
848 }
fl_key_embedder_responder_handle_event_impl
static void fl_key_embedder_responder_handle_event_impl(FlKeyEmbedderResponder *responder, FlKeyEvent *event, uint64_t specified_logical_key, FlKeyEmbedderResponderAsyncCallback callback, gpointer user_data)
Definition: fl_key_embedder_responder.cc:749
kEmptyEvent
static const FlutterKeyEvent kEmptyEvent
Definition: fl_key_embedder_responder.cc:16

References fl_key_embedder_responder_handle_event_impl(), kEmptyEvent, and user_data.

Referenced by fl_keyboard_manager_handle_event(), and TEST().

## ◆ fl_key_embedder_responder_handle_event_impl()

static void fl_key_embedder_responder_handle_event_impl | ( | FlKeyEmbedderResponder * | responder,
|  | FlKeyEvent * | event,
|  | uint64_t | specified_logical_key,
|  | FlKeyEmbedderResponderAsyncCallback | callback,
|  | gpointer | user_data
| ) |  |
| static

Definition at line 749 of file fl_key_embedder_responder.cc.

754 {
755 FlKeyEmbedderResponder* self = FL_KEY_EMBEDDER_RESPONDER(responder);
756
757 g_return_if_fail(event != nullptr);
758 g_return_if_fail(callback != nullptr);
759
760 const uint64_t logical_key = specified_logical_key != 0
761 ? specified_logical_key
762 : event_to_logical_key(event);
763 const uint64_t physical_key_from_event = event_to_physical_key(event);
764 const uint64_t physical_key = corrected_modifier_physical_key(
765 self->modifier_bit_to_checked_keys, physical_key_from_event, logical_key);
766 const double timestamp = event_to_timestamp(event);
767 const bool is_down_event = fl_key_event_get_is_press(event);
768
769 SyncStateLoopContext sync_state_context;
770 sync_state_context.self = self;
771 sync_state_context.state = fl_key_event_get_state(event);
772 sync_state_context.timestamp = timestamp;
773 sync_state_context.is_down = is_down_event;
774 sync_state_context.event_logical_key = logical_key;
775
776 // Update lock mode states
777 g_hash_table_foreach(self->lock_bit_to_checked_keys,
778 synchronize_lock_states_loop_body, &sync_state_context);
779
780 // Update pressing states
781 g_hash_table_foreach(self->modifier_bit_to_checked_keys,
782 synchronize_pressed_states_loop_body,
783 &sync_state_context);
784
785 // Construct the real event
786 const uint64_t last_logical_record =
787 lookup_hash_table(self->pressing_records, physical_key);
788
789 FlutterKeyEvent out_event;
790 out_event.struct_size = sizeof(out_event);
791 out_event.timestamp = timestamp;
792 out_event.physical = physical_key;
793 out_event.logical =
794 last_logical_record != 0 ? last_logical_record : logical_key;
795 out_event.character = nullptr;
796 out_event.synthesized = false;
797
798 g_autofree char* character_to_free = nullptr;
799 if (is_down_event) {
800 if (last_logical_record) {
801 // A key has been pressed that has the exact physical key as a currently
802 // pressed one. This can happen during repeated events.
803 out_event.type = kFlutterKeyEventTypeRepeat;
804 } else {
805 out_event.type = kFlutterKeyEventTypeDown;
806 }
807 character_to_free = event_to_character(event); // Might be null
808 out_event.character = character_to_free;
809 } else { // is_down_event false
810 if (!last_logical_record) {
811 // The physical key has been released before. It might indicate a missed
812 // event due to loss of focus, or multiple keyboards pressed keys with the
813 // same physical key. Ignore the up event.
814 callback(true, user_data);
815 return;
816 } else {
817 out_event.type = kFlutterKeyEventTypeUp;
818 }
819 }
820
821 if (out_event.type != kFlutterKeyEventTypeRepeat) {
822 update_pressing_state(self, physical_key, is_down_event ? logical_key : 0);
823 }
824 possibly_update_lock_bit(self, logical_key, is_down_event);
825 if (is_down_event) {
826 update_mapping_record(self, physical_key, logical_key);
827 }
828 FlKeyEmbedderUserData* response_data =
829 fl_key_embedder_user_data_new(callback, user_data);
830 self->sent_any_events = true;
831 self->send_key_event(&out_event, handle_response, response_data,
832 self->send_key_event_user_data);
833 }
handle_response
static void handle_response(bool handled, gpointer user_data)
Definition: fl_key_embedder_responder.cc:316
fl_key_embedder_user_data_new
static FlKeyEmbedderUserData * fl_key_embedder_user_data_new(FlKeyEmbedderResponderAsyncCallback callback, gpointer user_data)
Definition: fl_key_embedder_responder.cc:114
event_to_logical_key
static uint64_t event_to_logical_key(FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:280
synchronize_pressed_states_loop_body
static void synchronize_pressed_states_loop_body(gpointer key, gpointer value, gpointer user_data)
Definition: fl_key_embedder_responder.cc:416
event_to_physical_key
static uint64_t event_to_physical_key(FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:272
corrected_modifier_physical_key
static uint64_t corrected_modifier_physical_key(GHashTable *modifier_bit_to_checked_keys, uint64_t physical_key_from_event, uint64_t logical_key)
Definition: fl_key_embedder_responder.cc:721
update_mapping_record
static void update_mapping_record(FlKeyEmbedderResponder *self, uint64_t physical_key, uint64_t logical_key)
Definition: fl_key_embedder_responder.cc:405
lookup_hash_table
static uint64_t lookup_hash_table(GHashTable *table, uint64_t key)
Definition: fl_key_embedder_responder.cc:31
possibly_update_lock_bit
static void possibly_update_lock_bit(FlKeyEmbedderResponder *self, uint64_t logical_key, bool is_down)
Definition: fl_key_embedder_responder.cc:392
event_to_timestamp
static uint64_t event_to_timestamp(FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:294
update_pressing_state
static void update_pressing_state(FlKeyEmbedderResponder *self, uint64_t physical_key, uint64_t logical_key)
Definition: fl_key_embedder_responder.cc:371
synchronize_lock_states_loop_body
static void synchronize_lock_states_loop_body(gpointer key, gpointer value, gpointer user_data)
Definition: fl_key_embedder_responder.cc:583
event_to_character
static char * event_to_character(FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:301
fl_key_event_get_is_press
gboolean fl_key_event_get_is_press(FlKeyEvent *self)
Definition: fl_key_event.cc:84
fl_key_event_get_state
GdkModifierType fl_key_event_get_state(FlKeyEvent *self)
Definition: fl_key_event.cc:99

References corrected_modifier_physical_key(), event_to_character(), event_to_logical_key(), event_to_physical_key(), event_to_timestamp(), fl_key_embedder_user_data_new(), fl_key_event_get_is_press(), fl_key_event_get_state(), handle_response(), lookup_hash_table(), possibly_update_lock_bit(), synchronize_lock_states_loop_body(), synchronize_pressed_states_loop_body(), update_mapping_record(), update_pressing_state(), and user_data.

Referenced by fl_key_embedder_responder_handle_event().

## ◆ fl_key_embedder_responder_init()

static void fl_key_embedder_responder_init | ( | FlKeyEmbedderResponder * | self | ) |
| static

Definition at line 206 of file fl_key_embedder_responder.cc.

206 {}

## ◆ fl_key_embedder_responder_new()

FlKeyEmbedderResponder* fl_key_embedder_responder_new | ( | EmbedderSendKeyEvent | send_key_event,
|  | void * | send_key_event_user_data
| ) |  |

FlKeyEmbedderResponder:

A #FlKeyResponder that handles events by sending the converted events through the embedder API.

This class communicates with the HardwareKeyboard API in the framework. fl_key_embedder_responder_new: @engine: The #FlEngine, whose the embedder API will be used to send the event.

Creates a new #FlKeyEmbedderResponder. @send_key_event: a function that is called on every key event. @send_key_event_user_data: an opaque pointer that will be sent back as the last argument of send_key_event, created and managed by the object that holds FlKeyEmbedderResponder.

Returns: a new #FlKeyEmbedderResponder.

Definition at line 237 of file fl_key_embedder_responder.cc.

239 {
240 FlKeyEmbedderResponder* self = FL_KEY_EMBEDDER_RESPONDER(
241 g_object_new(fl_key_embedder_responder_get_type(), nullptr));
242
243 self->send_key_event = send_key_event;
244 self->send_key_event_user_data = send_key_event_user_data;
245
246 self->pressing_records = g_hash_table_new(g_direct_hash, g_direct_equal);
247 self->mapping_records = g_hash_table_new(g_direct_hash, g_direct_equal);
248 self->lock_records = 0;
249 self->caps_lock_state_logic_inferrence = STATE_LOGIC_INFERRENCE_UNDECIDED;
250
251 self->modifier_bit_to_checked_keys =
252 g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
253 initialize_modifier_bit_to_checked_keys(self->modifier_bit_to_checked_keys);
254
255 self->lock_bit_to_checked_keys =
256 g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
257 initialize_lock_bit_to_checked_keys(self->lock_bit_to_checked_keys);
258
259 self->logical_key_to_lock_bit =
260 g_hash_table_new(g_direct_hash, g_direct_equal);
261 g_hash_table_foreach(self->lock_bit_to_checked_keys,
262 initialize_logical_key_to_lock_bit_loop_body,
263 self->logical_key_to_lock_bit);
264
265 return self;
266 }
initialize_logical_key_to_lock_bit_loop_body
static void initialize_logical_key_to_lock_bit_loop_body(gpointer lock_bit, gpointer value, gpointer user_data)
Definition: fl_key_embedder_responder.cc:225
send_key_event
static void send_key_event(FlTextInputHandler *handler, gint keyval, gint state=0)
Definition: fl_text_input_handler_test.cc:144
initialize_modifier_bit_to_checked_keys
void initialize_modifier_bit_to_checked_keys(GHashTable *table)
Definition: key_mapping.g.cc:414
initialize_lock_bit_to_checked_keys
void initialize_lock_bit_to_checked_keys(GHashTable *table)
Definition: key_mapping.g.cc:446

References initialize_lock_bit_to_checked_keys(), initialize_logical_key_to_lock_bit_loop_body(), initialize_modifier_bit_to_checked_keys(), and send_key_event().

Referenced by fl_keyboard_manager_new(), and TEST().

## ◆ fl_key_embedder_responder_sync_modifiers_if_needed()

void fl_key_embedder_responder_sync_modifiers_if_needed | ( | FlKeyEmbedderResponder * | responder,
|  | guint | state,
|  | double | event_time
| ) |  |

fl_key_embedder_responder_sync_modifiers_if_needed: @responder: the #FlKeyEmbedderResponder self. @state: the state of the modifiers mask. @event_time: the time attribute of the incoming GDK event.

If needed, synthesize modifier keys up and down event by comparing their current pressing states with the given modifiers mask.

Definition at line 850 of file fl_key_embedder_responder.cc.

853 {
854 const double timestamp = event_time * kMicrosecondsPerMillisecond;
855
856 SyncStateLoopContext sync_state_context;
857 sync_state_context.self = responder;
858 sync_state_context.state = state;
859 sync_state_context.timestamp = timestamp;
860
861 // Update pressing states.
862 g_hash_table_foreach(responder->modifier_bit_to_checked_keys,
863 synchronize_pressed_states_loop_body,
864 &sync_state_context);
865 }
state
AtkStateType state
Definition: fl_accessible_node.cc:10

References kMicrosecondsPerMillisecond, state, and synchronize_pressed_states_loop_body().

Referenced by fl_keyboard_manager_sync_modifier_if_needed().

## ◆ fl_key_embedder_user_data_class_init()

static void fl_key_embedder_user_data_class_init | ( | FlKeyEmbedderUserDataClass * | klass | ) |
| static

Definition at line 98 of file fl_key_embedder_responder.cc.

99 {
100 G_OBJECT_CLASS(klass)->dispose = fl_key_embedder_user_data_dispose;
101 }
fl_key_embedder_user_data_dispose
static void fl_key_embedder_user_data_dispose(GObject *object)
Definition: fl_key_embedder_responder.cc:105

References fl_key_embedder_user_data_dispose().

## ◆ fl_key_embedder_user_data_dispose()

static void fl_key_embedder_user_data_dispose | ( | GObject * | object | ) |
| static

Definition at line 105 of file fl_key_embedder_responder.cc.

105 {
106 // The following line suppresses a warning for unused function
107 // FL_IS_KEY_EMBEDDER_USER_DATA.
108 g_return_if_fail(FL_IS_KEY_EMBEDDER_USER_DATA(object));
109 }

Referenced by fl_key_embedder_user_data_class_init().

## ◆ fl_key_embedder_user_data_init()

static void fl_key_embedder_user_data_init | ( | FlKeyEmbedderUserData * | self | ) |
| static

Definition at line 103 of file fl_key_embedder_responder.cc.

103 {}

## ◆ fl_key_embedder_user_data_new()

static FlKeyEmbedderUserData* fl_key_embedder_user_data_new | ( | FlKeyEmbedderResponderAsyncCallback | callback,
|  | gpointer | user_data
| ) |  |
| static

Definition at line 114 of file fl_key_embedder_responder.cc.

116 {
117 FlKeyEmbedderUserData* self = FL_KEY_EMBEDDER_USER_DATA(
118 g_object_new(fl_key_embedder_user_data_get_type(), nullptr));
119
120 self->callback = callback;
121 self->user_data = user_data;
122 return self;
123 }

References user_data.

Referenced by fl_key_embedder_responder_handle_event_impl().

## ◆ G_DECLARE_FINAL_TYPE()

G_DECLARE_FINAL_TYPE | ( | FlKeyEmbedderUserData | ,
|  | fl_key_embedder_user_data | ,
|  | FL | ,
|  | KEY_EMBEDDER_USER_DATA | ,
|  | GObject |
| ) |  |

FlKeyEmbedderUserData: The user_data used when #FlKeyEmbedderResponder sends message through the embedder.SendKeyEvent API.

## ◆ handle_response()

static void handle_response | ( | bool | handled,
|  | gpointer | user_data
| ) |  |
| static

Definition at line 316 of file fl_key_embedder_responder.cc.

316 {
317 g_autoptr(FlKeyEmbedderUserData) data = FL_KEY_EMBEDDER_USER_DATA(user_data);
318
319 g_return_if_fail(data->callback != nullptr);
320
321 data->callback(handled, data->user_data);
322 }

References user_data.

Referenced by fl_key_embedder_responder_handle_event_impl().

## ◆ hash_table_find_equal_value()

static gboolean hash_table_find_equal_value | ( | gpointer | key,
|  | gpointer | value,
|  | gpointer | user_data
| ) |  |
| static

Definition at line 36 of file fl_key_embedder_responder.cc.

38 {
39 return gpointer_to_uint64(value) == gpointer_to_uint64(user_data);
40 }
gpointer_to_uint64
uint64_t gpointer_to_uint64(gpointer pointer)
Definition: key_mapping.h:13

References gpointer_to_uint64(), user_data, and value.

Referenced by reverse_lookup_hash_table().

## ◆ initialize_logical_key_to_lock_bit_loop_body()

static void initialize_logical_key_to_lock_bit_loop_body | ( | gpointer | lock_bit,
|  | gpointer | value,
|  | gpointer | user_data
| ) |  |
| static

Definition at line 225 of file fl_key_embedder_responder.cc.

227 {
228 FlKeyEmbedderCheckedKey* checked_key =
229 reinterpret_cast<FlKeyEmbedderCheckedKey*>(value);
230 GHashTable* table = reinterpret_cast<GHashTable*>(user_data);
231 g_hash_table_insert(table,
232 uint64_to_gpointer(checked_key->primary_logical_key),
233 GUINT_TO_POINTER(lock_bit));
234 }
uint64_to_gpointer
gpointer uint64_to_gpointer(uint64_t number)
Definition: key_mapping.h:17

References FlKeyEmbedderCheckedKey::primary_logical_key, uint64_to_gpointer(), user_data, and value.

Referenced by fl_key_embedder_responder_new().

## ◆ is_known_modifier_physical_key_loop_body()

static void is_known_modifier_physical_key_loop_body | ( | gpointer | key,
|  | gpointer | value,
|  | gpointer | user_data
| ) |  |
| static

Definition at line 690 of file fl_key_embedder_responder.cc.

692 {
693 ModifierLogicalToPhysicalContext* context =
694 reinterpret_cast<ModifierLogicalToPhysicalContext*>(user_data);
695 FlKeyEmbedderCheckedKey* checked_key =
696 reinterpret_cast<FlKeyEmbedderCheckedKey*>(value);
697
698 if (checked_key->primary_physical_key == context->physical_key_from_event) {
699 context->known_modifier_physical_key = true;
700 }
701 }

References FlKeyEmbedderCheckedKey::primary_physical_key, user_data, and value.

Referenced by corrected_modifier_physical_key().

## ◆ lookup_hash_table()

static uint64_t lookup_hash_table | ( | GHashTable * | table,
|  | uint64_t | key
| ) |  |
| static

Definition at line 31 of file fl_key_embedder_responder.cc.

31 {
32 return gpointer_to_uint64(
33 g_hash_table_lookup(table, uint64_to_gpointer(key)));
34 }

References gpointer_to_uint64(), and uint64_to_gpointer().

Referenced by fl_key_embedder_responder_handle_event_impl(), synchronize_lock_states_loop_body(), synchronize_pressed_states_loop_body(), and update_pressing_state().

## ◆ possibly_update_lock_bit()

static void possibly_update_lock_bit | ( | FlKeyEmbedderResponder * | self,
|  | uint64_t | logical_key,
|  | bool | is_down
| ) |  |
| static

Definition at line 392 of file fl_key_embedder_responder.cc.

394 {
395 if (!is_down) {
396 return;
397 }
398 const guint mode_bit = GPOINTER_TO_UINT(g_hash_table_lookup(
399 self->logical_key_to_lock_bit, uint64_to_gpointer(logical_key)));
400 if (mode_bit != 0) {
401 self->lock_records ^= mode_bit;
402 }
403 }

References uint64_to_gpointer().

Referenced by fl_key_embedder_responder_handle_event_impl(), and synchronize_lock_states_loop_body().

## ◆ reverse_lookup_hash_table()

static uint64_t reverse_lookup_hash_table | ( | GHashTable * | table,
|  | uint64_t | value
| ) |  |
| static

Definition at line 48 of file fl_key_embedder_responder.cc.

48 {
49 return gpointer_to_uint64(g_hash_table_find(
50 table, hash_table_find_equal_value, uint64_to_gpointer(value)));
51 }
hash_table_find_equal_value
static gboolean hash_table_find_equal_value(gpointer key, gpointer value, gpointer user_data)
Definition: fl_key_embedder_responder.cc:36

References gpointer_to_uint64(), hash_table_find_equal_value(), uint64_to_gpointer(), and value.

Referenced by synchronize_pressed_states_loop_body().

## ◆ synchronize_lock_states_loop_body()

static void synchronize_lock_states_loop_body | ( | gpointer | key,
|  | gpointer | value,
|  | gpointer | user_data
| ) |  |
| static

Definition at line 583 of file fl_key_embedder_responder.cc.

585 {
586 SyncStateLoopContext* context =
587 reinterpret_cast<SyncStateLoopContext*>(user_data);
588 FlKeyEmbedderCheckedKey* checked_key =
589 reinterpret_cast<FlKeyEmbedderCheckedKey*>(value);
590
591 guint modifier_bit = GPOINTER_TO_INT(key);
592 FlKeyEmbedderResponder* self = context->self;
593
594 const uint64_t logical_key = checked_key->primary_logical_key;
595 const uint64_t recorded_physical_key =
596 lookup_hash_table(self->mapping_records, logical_key);
597 // The physical key is derived from past mapping record if possible.
598 //
599 // If the event to be synthesized is a key up event, then there must have
600 // been a key down event before, which has updated the mapping record.
601 // If the event to be synthesized is a key down event, then there might
602 // not have been a mapping record, in which case the hard-coded
603 // #primary_physical_key is used.
604 const uint64_t physical_key = recorded_physical_key != 0
605 ? recorded_physical_key
606 : checked_key->primary_physical_key;
607
608 // A lock mode key can be at any of a 4-stage cycle, depending on whether it's
609 // pressed and enabled. The following table lists the definition of each
610 // stage (TruePressed and TrueEnabled), the event of the lock key between
611 // every 2 stages (SelfType and SelfState), and the event of other keys at
612 // each stage (OthersState). On certain platforms SelfState uses a reversed
613 // rule for certain keys (SelfState(rvsd), as documented in
614 // #update_caps_lock_state_logic_inferrence).
615 //
616 // # [0] [1] [2] [3]
617 // TruePressed: Released Pressed Released Pressed
618 // TrueEnabled: Disabled Enabled Enabled Disabled
619 // SelfType: Down Up Down Up
620 // SelfState: 0 1 1 1
621 // SelfState(rvsd): 1 1 0 1
622 // OthersState: 0 1 1 1
623 //
624 // When the exact stage can't be derived, choose the stage that requires the
625 // minimal synthesization.
626
627 const uint64_t pressed_logical_key =
628 recorded_physical_key == 0
629 ? 0
630 : lookup_hash_table(self->pressing_records, recorded_physical_key);
631
632 g_return_if_fail(pressed_logical_key == 0 ||
633 pressed_logical_key == logical_key);
634 const int stage_by_record = find_stage_by_record(
635 pressed_logical_key != 0, (self->lock_records & modifier_bit) != 0);
636
637 const bool enabled_by_state = (context->state & modifier_bit) != 0;
638 const bool this_key_is_event_key = logical_key == context->event_logical_key;
639 if (this_key_is_event_key && checked_key->is_caps_lock) {
640 update_caps_lock_state_logic_inferrence(self, context->is_down,
641 enabled_by_state, stage_by_record);
642 g_return_if_fail(self->caps_lock_state_logic_inferrence !=
643 STATE_LOGIC_INFERRENCE_UNDECIDED);
644 }
645 const bool reverse_state_logic =
646 checked_key->is_caps_lock &&
647 self->caps_lock_state_logic_inferrence == STATE_LOGIC_INFERRENCE_REVERSED;
648 const int stage_by_event =
649 this_key_is_event_key
650 ? find_stage_by_self_event(stage_by_record, context->is_down,
651 enabled_by_state, reverse_state_logic)
652 : find_stage_by_others_event(stage_by_record, enabled_by_state);
653
654 // The destination stage is equal to stage_by_event but shifted cyclically to
655 // be no less than stage_by_record.
656 constexpr int kNumStages = 4;
657 const int destination_stage = stage_by_event >= stage_by_record
658 ? stage_by_event
659 : stage_by_event + kNumStages;
660
661 g_return_if_fail(stage_by_record <= destination_stage);
662 if (stage_by_record == destination_stage) {
663 return;
664 }
665 for (int current_stage = stage_by_record; current_stage < destination_stage;
666 current_stage += 1) {
667 if (current_stage == 9) {
668 return;
669 }
670
671 const int standard_current_stage = current_stage % kNumStages;
672 const bool is_down_event =
673 standard_current_stage == 0 || standard_current_stage == 2;
674 if (is_down_event && recorded_physical_key == 0) {
675 update_mapping_record(self, physical_key, logical_key);
676 }
677 FlutterKeyEventType type =
678 is_down_event ? kFlutterKeyEventTypeDown : kFlutterKeyEventTypeUp;
679 update_pressing_state(self, physical_key, is_down_event ? logical_key : 0);
680 possibly_update_lock_bit(self, logical_key, is_down_event);
681 synthesize_simple_event(self, type, physical_key, logical_key,
682 context->timestamp);
683 }
684 }
update_caps_lock_state_logic_inferrence
static void update_caps_lock_state_logic_inferrence(FlKeyEmbedderResponder *self, bool is_down_event, bool enabled_by_state, int stage_by_record)
Definition: fl_key_embedder_responder.cc:555
synthesize_simple_event
static void synthesize_simple_event(FlKeyEmbedderResponder *self, FlutterKeyEventType type, uint64_t physical, uint64_t logical, double timestamp)
Definition: fl_key_embedder_responder.cc:325
find_stage_by_others_event
static int find_stage_by_others_event(int stage_by_record, bool is_state_on)
Definition: fl_key_embedder_responder.cc:528
find_stage_by_self_event
static int find_stage_by_self_event(int stage_by_record, bool is_down_event, bool is_state_on, bool reverse_state_logic)
Definition: fl_key_embedder_responder.cc:513
find_stage_by_record
static int find_stage_by_record(bool is_down, bool is_enabled)
Definition: fl_key_embedder_responder.cc:501
type
uint8_t type
Definition: fl_standard_message_codec_test.cc:1115
FlKeyEmbedderCheckedKey::is_caps_lock
bool is_caps_lock
Definition: fl_key_embedder_responder_private.h:42

References find_stage_by_others_event(), find_stage_by_record(), find_stage_by_self_event(), FlKeyEmbedderCheckedKey::is_caps_lock, lookup_hash_table(), possibly_update_lock_bit(), FlKeyEmbedderCheckedKey::primary_logical_key, FlKeyEmbedderCheckedKey::primary_physical_key, synthesize_simple_event(), type, update_caps_lock_state_logic_inferrence(), update_mapping_record(), update_pressing_state(), user_data, and value.

Referenced by fl_key_embedder_responder_handle_event_impl().

## ◆ synchronize_pressed_states_loop_body()

static void synchronize_pressed_states_loop_body | ( | gpointer | key,
|  | gpointer | value,
|  | gpointer | user_data
| ) |  |
| static

Definition at line 416 of file fl_key_embedder_responder.cc.

418 {
419 SyncStateLoopContext* context =
420 reinterpret_cast<SyncStateLoopContext*>(user_data);
421 FlKeyEmbedderCheckedKey* checked_key =
422 reinterpret_cast<FlKeyEmbedderCheckedKey*>(value);
423
424 const guint modifier_bit = GPOINTER_TO_INT(key);
425 FlKeyEmbedderResponder* self = context->self;
426 // Each TestKey contains up to two logical keys, typically the left modifier
427 // and the right modifier, that correspond to the same modifier_bit. We'd
428 // like to infer whether to synthesize a down or up event for each key.
429 //
430 // The hard part is that, if we want to synthesize a down event, we don't know
431 // which physical key to use. Here we assume the keyboard layout do not change
432 // frequently and use the last physical-logical relationship, recorded in
433 // #mapping_records.
434 const uint64_t logical_keys[] = {
435 checked_key->primary_logical_key,
436 checked_key->secondary_logical_key,
437 };
438 const guint length = checked_key->secondary_logical_key == 0 ? 1 : 2;
439
440 const bool any_pressed_by_state = (context->state & modifier_bit) != 0;
441
442 bool any_pressed_by_record = false;
443
444 // Traverse each logical key of this modifier bit for 2 purposes:
445 //
446 // 1. Perform the synthesization of release events: If the modifier bit is 0
447 // and the key is pressed, synthesize a release event.
448 // 2. Prepare for the synthesization of press events: If the modifier bit is
449 // 1, and no keys are pressed (discovered here), synthesize a press event
450 // later.
451 for (guint logical_key_idx = 0; logical_key_idx < length; logical_key_idx++) {
452 const uint64_t logical_key = logical_keys[logical_key_idx];
453 g_return_if_fail(logical_key != 0);
454 const uint64_t pressing_physical_key =
455 reverse_lookup_hash_table(self->pressing_records, logical_key);
456 const bool this_key_pressed_before_event = pressing_physical_key != 0;
457
458 any_pressed_by_record =
459 any_pressed_by_record || this_key_pressed_before_event;
460
461 if (this_key_pressed_before_event && !any_pressed_by_state) {
462 const uint64_t recorded_physical_key =
463 lookup_hash_table(self->mapping_records, logical_key);
464 // Since this key has been pressed before, there must have been a recorded
465 // physical key.
466 g_return_if_fail(recorded_physical_key != 0);
467 // In rare cases #recorded_logical_key is different from #logical_key.
468 const uint64_t recorded_logical_key =
469 lookup_hash_table(self->pressing_records, recorded_physical_key);
470 synthesize_simple_event(self, kFlutterKeyEventTypeUp,
471 recorded_physical_key, recorded_logical_key,
472 context->timestamp);
473 update_pressing_state(self, recorded_physical_key, 0);
474 }
475 }
476 // If the modifier should be pressed, synthesize a down event for its primary
477 // key.
478 if (any_pressed_by_state && !any_pressed_by_record) {
479 const uint64_t logical_key = checked_key->primary_logical_key;
480 const uint64_t recorded_physical_key =
481 lookup_hash_table(self->mapping_records, logical_key);
482 // The physical key is derived from past mapping record if possible.
483 //
484 // The event to be synthesized is a key down event. There might not have
485 // been a mapping record, in which case the hard-coded #primary_physical_key
486 // is used.
487 const uint64_t physical_key = recorded_physical_key != 0
488 ? recorded_physical_key
489 : checked_key->primary_physical_key;
490 if (recorded_physical_key == 0) {
491 update_mapping_record(self, physical_key, logical_key);
492 }
493 synthesize_simple_event(self, kFlutterKeyEventTypeDown, physical_key,
494 logical_key, context->timestamp);
495 update_pressing_state(self, physical_key, logical_key);
496 }
497 }
reverse_lookup_hash_table
static uint64_t reverse_lookup_hash_table(GHashTable *table, uint64_t value)
Definition: fl_key_embedder_responder.cc:48
length
size_t length
Definition: fl_standard_message_codec_test.cc:1113

References length, lookup_hash_table(), FlKeyEmbedderCheckedKey::primary_logical_key, FlKeyEmbedderCheckedKey::primary_physical_key, reverse_lookup_hash_table(), FlKeyEmbedderCheckedKey::secondary_logical_key, synthesize_simple_event(), update_mapping_record(), update_pressing_state(), user_data, and value.

Referenced by fl_key_embedder_responder_handle_event_impl(), and fl_key_embedder_responder_sync_modifiers_if_needed().

## ◆ synthesize_simple_event()

static void synthesize_simple_event | ( | FlKeyEmbedderResponder * | self,
|  | FlutterKeyEventType | type,
|  | uint64_t | physical,
|  | uint64_t | logical,
|  | double | timestamp
| ) |  |
| static

Definition at line 325 of file fl_key_embedder_responder.cc.

329 {
330 FlutterKeyEvent out_event;
331 out_event.struct_size = sizeof(out_event);
332 out_event.timestamp = timestamp;
333 out_event.type = type;
334 out_event.physical = physical;
335 out_event.logical = logical;
336 out_event.character = nullptr;
337 out_event.synthesized = true;
338 self->sent_any_events = true;
339 self->send_key_event(&out_event, nullptr, nullptr,
340 self->send_key_event_user_data);
341 }

References type.

Referenced by synchronize_lock_states_loop_body(), and synchronize_pressed_states_loop_body().

## ◆ to_lower()

static uint64_t to_lower | ( | uint64_t | n | ) |
| static

Definition at line 53 of file fl_key_embedder_responder.cc.

53 {
54 constexpr uint64_t lower_a = 0x61;
55 constexpr uint64_t upper_a = 0x41;
56 constexpr uint64_t upper_z = 0x5a;
57
58 constexpr uint64_t lower_a_grave = 0xe0;
59 constexpr uint64_t upper_a_grave = 0xc0;
60 constexpr uint64_t upper_thorn = 0xde;
61 constexpr uint64_t division = 0xf7;
62
63 // ASCII range.
64 if (n >= upper_a && n <= upper_z) {
65 return n - upper_a + lower_a;
66 }
67
68 // EASCII range.
69 if (n >= upper_a_grave && n <= upper_thorn && n != division) {
70 return n - upper_a_grave + lower_a_grave;
71 }
72
73 return n;
74 }

Referenced by event_to_logical_key().

## ◆ update_caps_lock_state_logic_inferrence()

static void update_caps_lock_state_logic_inferrence | ( | FlKeyEmbedderResponder * | self,
|  | bool | is_down_event,
|  | bool | enabled_by_state,
|  | int | stage_by_record
| ) |  |
| static

Definition at line 555 of file fl_key_embedder_responder.cc.

559 {
560 if (self->caps_lock_state_logic_inferrence !=
561 STATE_LOGIC_INFERRENCE_UNDECIDED) {
562 return;
563 }
564 if (!is_down_event) {
565 return;
566 }
567 const int stage_by_event = find_stage_by_self_event(
568 stage_by_record, is_down_event, enabled_by_state, false);
569 if ((stage_by_event == 0 && stage_by_record == 2) ||
570 (stage_by_event == 2 && stage_by_record == 0)) {
571 self->caps_lock_state_logic_inferrence = STATE_LOGIC_INFERRENCE_REVERSED;
572 } else {
573 self->caps_lock_state_logic_inferrence = STATE_LOGIC_INFERRENCE_NORMAL;
574 }
575 }

References find_stage_by_self_event().

Referenced by synchronize_lock_states_loop_body().

## ◆ update_mapping_record()

static void update_mapping_record | ( | FlKeyEmbedderResponder * | self,
|  | uint64_t | physical_key,
|  | uint64_t | logical_key
| ) |  |
| static

Definition at line 405 of file fl_key_embedder_responder.cc.

407 {
408 g_hash_table_insert(self->mapping_records, uint64_to_gpointer(logical_key),
409 uint64_to_gpointer(physical_key));
410 }

References uint64_to_gpointer().

Referenced by fl_key_embedder_responder_handle_event_impl(), synchronize_lock_states_loop_body(), and synchronize_pressed_states_loop_body().

## ◆ update_pressing_state()

static void update_pressing_state | ( | FlKeyEmbedderResponder * | self,
|  | uint64_t | physical_key,
|  | uint64_t | logical_key
| ) |  |
| static

Definition at line 371 of file fl_key_embedder_responder.cc.

373 {
374 if (logical_key != 0) {
375 g_return_if_fail(lookup_hash_table(self->pressing_records, physical_key) ==
376 0);
377 g_hash_table_insert(self->pressing_records,
378 uint64_to_gpointer(physical_key),
379 uint64_to_gpointer(logical_key));
380 } else {
381 g_return_if_fail(lookup_hash_table(self->pressing_records, physical_key) !=
382 0);
383 g_hash_table_remove(self->pressing_records,
384 uint64_to_gpointer(physical_key));
385 }
386 }

References lookup_hash_table(), and uint64_to_gpointer().

Referenced by fl_key_embedder_responder_handle_event_impl(), synchronize_lock_states_loop_body(), and synchronize_pressed_states_loop_body().

## Variable Documentation

## ◆ kEmptyEvent

const FlutterKeyEvent kEmptyEvent
| static

Initial value:
{
.struct_size = sizeof(FlutterKeyEvent),
.timestamp = 0,
.type = kFlutterKeyEventTypeDown,
.physical = 0,
.logical = 0,
.character = nullptr,
.synthesized = false,
}

Definition at line 16 of file fl_key_embedder_responder.cc.

Referenced by fl_key_embedder_responder_handle_event().

## ◆ kMicrosecondsPerMillisecond

constexpr uint64_t kMicrosecondsPerMillisecond = 1000
| constexpr

Definition at line 14 of file fl_key_embedder_responder.cc.

Referenced by event_to_timestamp(), and fl_key_embedder_responder_sync_modifiers_if_needed().