Flutter Linux Embedder
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 }

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,
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,
743  &logical_to_physical_context);
744  }
745 
746  return logical_to_physical_context.corrected_physical_key;
747 }

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 }

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 }

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  }
278 }

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  {
296  static_cast<double>(fl_key_event_get_time(event));
297 }

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 }

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 }

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;
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 }

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,
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 =
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 }

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,
263  self->logical_key_to_lock_bit);
264 
265  return self;
266 }

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,
864  &sync_state_context);
865 }

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 }

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  {
40 }

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,
233  GUINT_TO_POINTER(lock_bit));
234 }

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

◆ 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

◆ 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 }

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 }

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
gtk_keyval_to_logical_key_map
std::map< uint64_t, uint64_t > gtk_keyval_to_logical_key_map
Definition: key_mapping.g.cc:240
apply_id_plane
static uint64_t apply_id_plane(uint64_t logical_id, uint64_t plane)
Definition: fl_key_embedder_responder.cc:268
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
FlKeyEmbedderCheckedKey::is_caps_lock
bool is_caps_lock
Definition: fl_key_embedder_responder_private.h:42
to_lower
static uint64_t to_lower(uint64_t n)
Definition: fl_key_embedder_responder.cc:53
type
uint8_t type
Definition: fl_standard_message_codec_test.cc:1115
event_to_timestamp
static uint64_t event_to_timestamp(FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:294
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
uint64_to_gpointer
gpointer uint64_to_gpointer(uint64_t number)
Definition: key_mapping.h:17
kUnicodePlane
const uint64_t kUnicodePlane
Definition: key_mapping.g.cc:515
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
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
state
AtkStateType state
Definition: fl_accessible_node.cc:10
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
find_stage_by_record
static int find_stage_by_record(bool is_down, bool is_enabled)
Definition: fl_key_embedder_responder.cc:501
user_data
G_BEGIN_DECLS G_MODULE_EXPORT FlValue gpointer user_data
Definition: fl_event_channel.h:90
fl_key_event_get_keyval
guint fl_key_event_get_keyval(FlKeyEvent *self)
Definition: fl_key_event.cc:94
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
initialize_modifier_bit_to_checked_keys
void initialize_modifier_bit_to_checked_keys(GHashTable *table)
Definition: key_mapping.g.cc:414
kGtkPlane
const uint64_t kGtkPlane
Definition: key_mapping.g.cc:516
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
kValueMask
const uint64_t kValueMask
Definition: key_mapping.g.cc:514
fl_key_embedder_responder_dispose
static void fl_key_embedder_responder_dispose(GObject *object)
Definition: fl_key_embedder_responder.cc:209
initialize_lock_bit_to_checked_keys
void initialize_lock_bit_to_checked_keys(GHashTable *table)
Definition: key_mapping.g.cc:446
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
event_to_physical_key
static uint64_t event_to_physical_key(FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:272
lookup_hash_table
static uint64_t lookup_hash_table(GHashTable *table, uint64_t key)
Definition: fl_key_embedder_responder.cc:31
fl_key_event_get_time
guint32 fl_key_event_get_time(FlKeyEvent *self)
Definition: fl_key_event.cc:79
event_to_logical_key
static uint64_t event_to_logical_key(FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:280
FlKeyEmbedderCheckedKey::primary_physical_key
uint64_t primary_physical_key
Definition: fl_key_embedder_responder_private.h:35
reverse_lookup_hash_table
static uint64_t reverse_lookup_hash_table(GHashTable *table, uint64_t value)
Definition: fl_key_embedder_responder.cc:48
fl_key_event_get_state
GdkModifierType fl_key_event_get_state(FlKeyEvent *self)
Definition: fl_key_event.cc:99
fl_key_event_get_keycode
guint16 fl_key_event_get_keycode(FlKeyEvent *self)
Definition: fl_key_event.cc:89
kMicrosecondsPerMillisecond
constexpr uint64_t kMicrosecondsPerMillisecond
Definition: fl_key_embedder_responder.cc:14
send_key_event
static void send_key_event(FlTextInputHandler *handler, gint keyval, gint state=0)
Definition: fl_text_input_handler_test.cc:144
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
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
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
FlKeyEmbedderCheckedKey::secondary_logical_key
uint64_t secondary_logical_key
Definition: fl_key_embedder_responder_private.h:39
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
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
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
xkb_to_physical_key_map
std::map< uint64_t, uint64_t > xkb_to_physical_key_map
Definition: key_mapping.g.cc:20
FlKeyEmbedderCheckedKey::primary_logical_key
uint64_t primary_logical_key
Definition: fl_key_embedder_responder_private.h:37
fl_key_event_get_is_press
gboolean fl_key_event_get_is_press(FlKeyEvent *self)
Definition: fl_key_event.cc:84
handle_response
static void handle_response(bool handled, gpointer user_data)
Definition: fl_key_embedder_responder.cc:316
event_to_character
static char * event_to_character(FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:301
value
uint8_t value
Definition: fl_standard_message_codec.cc:36
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
FlKeyEmbedderCheckedKey
Definition: fl_key_embedder_responder_private.h:33
length
size_t length
Definition: fl_standard_message_codec_test.cc:1113
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
gpointer_to_uint64
uint64_t gpointer_to_uint64(gpointer pointer)
Definition: key_mapping.h:13
kEmptyEvent
static const FlutterKeyEvent kEmptyEvent
Definition: fl_key_embedder_responder.cc:16
fl_key_embedder_user_data_dispose
static void fl_key_embedder_user_data_dispose(GObject *object)
Definition: fl_key_embedder_responder.cc:105