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
 

Macros

#define FL_TYPE_EMBEDDER_USER_DATA   fl_key_embedder_user_data_get_type()
 
#define FL_TYPE_EMBEDDER_RESPONDER_USER_DATA   fl_key_embedder_responder_get_type()
 

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 (FlKeyResponderAsyncCallback callback, gpointer user_data)
 
static void fl_key_embedder_responder_iface_init (FlKeyResponderInterface *iface)
 
static void fl_key_embedder_responder_dispose (GObject *object)
 
 G_DEFINE_TYPE_WITH_CODE (FlKeyEmbedderResponder, fl_key_embedder_responder, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(FL_TYPE_KEY_RESPONDER, fl_key_embedder_responder_iface_init)) static void fl_key_embedder_responder_handle_event(FlKeyResponder *responder
 
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)
 
static uint64_t apply_id_plane (uint64_t logical_id, uint64_t plane)
 
static uint64_t event_to_physical_key (const FlKeyEvent *event)
 
static uint64_t event_to_logical_key (const FlKeyEvent *event)
 
static uint64_t event_to_timestamp (const FlKeyEvent *event)
 
static char * event_to_character (const 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 (FlKeyResponder *responder, FlKeyEvent *event, uint64_t specified_logical_key, FlKeyResponderAsyncCallback callback, gpointer user_data)
 
static void fl_key_embedder_responder_handle_event (FlKeyResponder *responder, FlKeyEvent *event, uint64_t specified_logical_key, FlKeyResponderAsyncCallback 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
 
FlKeyEventevent
 
FlKeyEvent uint64_t specified_logical_key
 
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
 
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
 

Macro Definition Documentation

◆ FL_TYPE_EMBEDDER_RESPONDER_USER_DATA

#define FL_TYPE_EMBEDDER_RESPONDER_USER_DATA   fl_key_embedder_responder_get_type()

Definition at line 203 of file fl_key_embedder_responder.cc.

◆ FL_TYPE_EMBEDDER_USER_DATA

#define FL_TYPE_EMBEDDER_USER_DATA   fl_key_embedder_user_data_get_type()

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

Definition at line 83 of file fl_key_embedder_responder.cc.

Function Documentation

◆ apply_id_plane()

static uint64_t apply_id_plane ( uint64_t  logical_id,
uint64_t  plane 
)
static

Definition at line 293 of file fl_key_embedder_responder.cc.

293  {
294  return (logical_id & kValueMask) | plane;
295 }

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 743 of file fl_key_embedder_responder.cc.

746  {
747  ModifierLogicalToPhysicalContext logical_to_physical_context;
748  logical_to_physical_context.known_modifier_physical_key = false;
749  logical_to_physical_context.physical_key_from_event = physical_key_from_event;
750  logical_to_physical_context.logical_key = logical_key;
751  // If no match is found, defaults to the physical key retrieved from the
752  // event.
753  logical_to_physical_context.corrected_physical_key = physical_key_from_event;
754 
755  // Check if the physical key is one of the known modifier physical key.
756  g_hash_table_foreach(modifier_bit_to_checked_keys,
758  &logical_to_physical_context);
759 
760  // If the physical key matches a known modifier key, find the modifier
761  // physical key from the logical key.
762  if (logical_to_physical_context.known_modifier_physical_key) {
763  g_hash_table_foreach(modifier_bit_to_checked_keys,
765  &logical_to_physical_context);
766  }
767 
768  return logical_to_physical_context.corrected_physical_key;
769 }

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 ( const FlKeyEvent event)
static

Definition at line 325 of file fl_key_embedder_responder.cc.

325  {
326  gunichar unicodeChar = gdk_keyval_to_unicode(event->keyval);
327  glong items_written;
328  gchar* result = g_ucs4_to_utf8(&unicodeChar, 1, NULL, &items_written, NULL);
329  if (items_written == 0) {
330  if (result != NULL) {
331  g_free(result);
332  }
333  return nullptr;
334  }
335  return result;
336 }

References event, _FlKeyEvent::keyval, and result.

Referenced by fl_key_embedder_responder_handle_event_impl().

◆ event_to_logical_key()

static uint64_t event_to_logical_key ( const FlKeyEvent event)
static

Definition at line 305 of file fl_key_embedder_responder.cc.

305  {
306  guint keyval = event->keyval;
307  auto found = gtk_keyval_to_logical_key_map.find(keyval);
308  if (found != gtk_keyval_to_logical_key_map.end()) {
309  return found->second;
310  }
311  // EASCII range
312  if (keyval < 256) {
313  return apply_id_plane(to_lower(keyval), kUnicodePlane);
314  }
315  // Auto-generate key
316  return apply_id_plane(keyval, kGtkPlane);
317 }

References apply_id_plane(), 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 ( const FlKeyEvent event)
static

Definition at line 297 of file fl_key_embedder_responder.cc.

297  {
298  auto found = xkb_to_physical_key_map.find(event->keycode);
299  if (found != xkb_to_physical_key_map.end()) {
300  return found->second;
301  }
303 }

References apply_id_plane(), event, _FlKeyEvent::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 ( const FlKeyEvent event)
static

Definition at line 319 of file fl_key_embedder_responder.cc.

319  {
320  return kMicrosecondsPerMillisecond * static_cast<double>(event->time);
321 }

References 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 729 of file fl_key_embedder_responder.cc.

731  {
732  ModifierLogicalToPhysicalContext* context =
733  reinterpret_cast<ModifierLogicalToPhysicalContext*>(user_data);
734  FlKeyEmbedderCheckedKey* checked_key =
735  reinterpret_cast<FlKeyEmbedderCheckedKey*>(value);
736 
737  if (checked_key->primary_logical_key == context->logical_key ||
738  checked_key->secondary_logical_key == context->logical_key) {
739  context->corrected_physical_key = checked_key->primary_physical_key;
740  }
741 }

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 551 of file fl_key_embedder_responder.cc.

551  {
552  g_return_val_if_fail(stage_by_record >= 0 && stage_by_record < 4,
553  stage_by_record);
554  if (!is_state_on) {
555  return 0;
556  }
557  if (stage_by_record == 0) {
558  return 1;
559  }
560  return stage_by_record;
561 }

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 524 of file fl_key_embedder_responder.cc.

524  {
525  constexpr int stage_by_record_index[] = {
526  0, // is_down: 0, is_enabled: 0
527  2, // 0 1
528  3, // 1 0
529  1 // 1 1
530  };
531  return stage_by_record_index[(is_down << 1) + is_enabled];
532 }

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 536 of file fl_key_embedder_responder.cc.

539  {
540  if (!is_state_on) {
541  return reverse_state_logic ? 2 : 0;
542  }
543  if (is_down_event) {
544  return reverse_state_logic ? 0 : 2;
545  }
546  return stage_by_record;
547 }

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 225 of file fl_key_embedder_responder.cc.

226  {
227  G_OBJECT_CLASS(klass)->dispose = fl_key_embedder_responder_dispose;
228 }

References fl_key_embedder_responder_dispose().

◆ fl_key_embedder_responder_dispose()

static void fl_key_embedder_responder_dispose ( GObject *  object)
static

Definition at line 234 of file fl_key_embedder_responder.cc.

234  {
235  FlKeyEmbedderResponder* self = FL_KEY_EMBEDDER_RESPONDER(object);
236 
237  g_clear_pointer(&self->pressing_records, g_hash_table_unref);
238  g_clear_pointer(&self->mapping_records, g_hash_table_unref);
239  g_clear_pointer(&self->modifier_bit_to_checked_keys, g_hash_table_unref);
240  g_clear_pointer(&self->lock_bit_to_checked_keys, g_hash_table_unref);
241  g_clear_pointer(&self->logical_key_to_lock_bit, g_hash_table_unref);
242 
243  G_OBJECT_CLASS(fl_key_embedder_responder_parent_class)->dispose(object);
244 }

References self.

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 889 of file fl_key_embedder_responder.cc.

890  {
891  return self->pressing_records;
892 }

Referenced by fl_keyboard_manager_get_pressed_state().

◆ fl_key_embedder_responder_handle_event()

static void fl_key_embedder_responder_handle_event ( FlKeyResponder *  responder,
FlKeyEvent event,
uint64_t  specified_logical_key,
FlKeyResponderAsyncCallback  callback,
gpointer  user_data 
)
static

Definition at line 857 of file fl_key_embedder_responder.cc.

862  {
863  FlKeyEmbedderResponder* self = FL_KEY_EMBEDDER_RESPONDER(responder);
864  self->sent_any_events = false;
867  if (!self->sent_any_events) {
868  self->send_key_event(&kEmptyEvent, nullptr, nullptr);
869  }
870 }

References callback, event, fl_key_embedder_responder_handle_event_impl(), kEmptyEvent, self, specified_logical_key, and user_data.

Referenced by fl_key_embedder_responder_iface_init().

◆ fl_key_embedder_responder_handle_event_impl()

static void fl_key_embedder_responder_handle_event_impl ( FlKeyResponder *  responder,
FlKeyEvent event,
uint64_t  specified_logical_key,
FlKeyResponderAsyncCallback  callback,
gpointer  user_data 
)
static

Definition at line 771 of file fl_key_embedder_responder.cc.

776  {
777  FlKeyEmbedderResponder* self = FL_KEY_EMBEDDER_RESPONDER(responder);
778 
779  g_return_if_fail(event != nullptr);
780  g_return_if_fail(callback != nullptr);
781 
782  const uint64_t logical_key = specified_logical_key != 0
785  const uint64_t physical_key_from_event = event_to_physical_key(event);
786  const uint64_t physical_key = corrected_modifier_physical_key(
787  self->modifier_bit_to_checked_keys, physical_key_from_event, logical_key);
788  const double timestamp = event_to_timestamp(event);
789  const bool is_down_event = event->is_press;
790 
791  SyncStateLoopContext sync_state_context;
792  sync_state_context.self = self;
793  sync_state_context.state = event->state;
794  sync_state_context.timestamp = timestamp;
795  sync_state_context.is_down = is_down_event;
796  sync_state_context.event_logical_key = logical_key;
797 
798  // Update lock mode states
799  g_hash_table_foreach(self->lock_bit_to_checked_keys,
800  synchronize_lock_states_loop_body, &sync_state_context);
801 
802  // Update pressing states
803  g_hash_table_foreach(self->modifier_bit_to_checked_keys,
805  &sync_state_context);
806 
807  // Construct the real event
808  const uint64_t last_logical_record =
809  lookup_hash_table(self->pressing_records, physical_key);
810 
811  FlutterKeyEvent out_event;
812  out_event.struct_size = sizeof(out_event);
813  out_event.timestamp = timestamp;
814  out_event.physical = physical_key;
815  out_event.logical =
816  last_logical_record != 0 ? last_logical_record : logical_key;
817  out_event.character = nullptr;
818  out_event.synthesized = false;
819 
820  g_autofree char* character_to_free = nullptr;
821  if (is_down_event) {
822  if (last_logical_record) {
823  // A key has been pressed that has the exact physical key as a currently
824  // pressed one. This can happen during repeated events.
825  out_event.type = kFlutterKeyEventTypeRepeat;
826  } else {
827  out_event.type = kFlutterKeyEventTypeDown;
828  }
829  character_to_free = event_to_character(event); // Might be null
830  out_event.character = character_to_free;
831  } else { // is_down_event false
832  if (!last_logical_record) {
833  // The physical key has been released before. It might indicate a missed
834  // event due to loss of focus, or multiple keyboards pressed keys with the
835  // same physical key. Ignore the up event.
836  callback(true, user_data);
837  return;
838  } else {
839  out_event.type = kFlutterKeyEventTypeUp;
840  }
841  }
842 
843  if (out_event.type != kFlutterKeyEventTypeRepeat) {
844  update_pressing_state(self, physical_key, is_down_event ? logical_key : 0);
845  }
846  possibly_update_lock_bit(self, logical_key, is_down_event);
847  if (is_down_event) {
848  update_mapping_record(self, physical_key, logical_key);
849  }
850  FlKeyEmbedderUserData* response_data =
852  self->sent_any_events = true;
853  self->send_key_event(&out_event, handle_response, response_data);
854 }

References callback, corrected_modifier_physical_key(), event, event_to_character(), event_to_logical_key(), event_to_physical_key(), event_to_timestamp(), fl_key_embedder_user_data_new(), handle_response(), lookup_hash_table(), possibly_update_lock_bit(), self, specified_logical_key, 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_iface_init()

static void fl_key_embedder_responder_iface_init ( FlKeyResponderInterface *  iface)
static

Definition at line 219 of file fl_key_embedder_responder.cc.

220  {
221  iface->handle_event = fl_key_embedder_responder_handle_event;
222 }

References fl_key_embedder_responder_handle_event().

◆ fl_key_embedder_responder_init()

static void fl_key_embedder_responder_init ( FlKeyEmbedderResponder *  self)
static

Definition at line 231 of file fl_key_embedder_responder.cc.

231 {}

◆ fl_key_embedder_responder_new()

FlKeyEmbedderResponder* fl_key_embedder_responder_new ( EmbedderSendKeyEvent  send_key_event)

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.

Returns: a new #FlKeyEmbedderResponder.

Definition at line 262 of file fl_key_embedder_responder.cc.

263  {
264  FlKeyEmbedderResponder* self = FL_KEY_EMBEDDER_RESPONDER(
265  g_object_new(FL_TYPE_EMBEDDER_RESPONDER_USER_DATA, nullptr));
266 
267  self->send_key_event = std::move(send_key_event);
268 
269  self->pressing_records = g_hash_table_new(g_direct_hash, g_direct_equal);
270  self->mapping_records = g_hash_table_new(g_direct_hash, g_direct_equal);
271  self->lock_records = 0;
272  self->caps_lock_state_logic_inferrence = kStateLogicUndecided;
273 
274  self->modifier_bit_to_checked_keys =
275  g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
276  initialize_modifier_bit_to_checked_keys(self->modifier_bit_to_checked_keys);
277 
278  self->lock_bit_to_checked_keys =
279  g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
280  initialize_lock_bit_to_checked_keys(self->lock_bit_to_checked_keys);
281 
282  self->logical_key_to_lock_bit =
283  g_hash_table_new(g_direct_hash, g_direct_equal);
284  g_hash_table_foreach(self->lock_bit_to_checked_keys,
286  self->logical_key_to_lock_bit);
287 
288  return self;
289 }

References FL_TYPE_EMBEDDER_RESPONDER_USER_DATA, initialize_lock_bit_to_checked_keys(), initialize_logical_key_to_lock_bit_loop_body(), initialize_modifier_bit_to_checked_keys(), self, 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 872 of file fl_key_embedder_responder.cc.

875  {
876  const double timestamp = event_time * kMicrosecondsPerMillisecond;
877 
878  SyncStateLoopContext sync_state_context;
879  sync_state_context.self = responder;
880  sync_state_context.state = state;
881  sync_state_context.timestamp = timestamp;
882 
883  // Update pressing states.
884  g_hash_table_foreach(responder->modifier_bit_to_checked_keys,
886  &sync_state_context);
887 }

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 101 of file fl_key_embedder_responder.cc.

102  {
103  G_OBJECT_CLASS(klass)->dispose = fl_key_embedder_user_data_dispose;
104 }

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 108 of file fl_key_embedder_responder.cc.

108  {
109  // The following line suppresses a warning for unused function
110  // FL_IS_KEY_EMBEDDER_USER_DATA.
111  g_return_if_fail(FL_IS_KEY_EMBEDDER_USER_DATA(object));
112 }

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 106 of file fl_key_embedder_responder.cc.

106 {}

◆ fl_key_embedder_user_data_new()

static FlKeyEmbedderUserData* fl_key_embedder_user_data_new ( FlKeyResponderAsyncCallback  callback,
gpointer  user_data 
)
static

Definition at line 117 of file fl_key_embedder_responder.cc.

119  {
120  FlKeyEmbedderUserData* self = FL_KEY_EMBEDDER_USER_DATA(
121  g_object_new(FL_TYPE_EMBEDDER_USER_DATA, nullptr));
122 
123  self->callback = callback;
124  self->user_data = user_data;
125  return self;
126 }

References callback, FL_TYPE_EMBEDDER_USER_DATA, and 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   
)

◆ G_DEFINE_TYPE_WITH_CODE()

G_DEFINE_TYPE_WITH_CODE ( FlKeyEmbedderResponder  ,
fl_key_embedder_responder  ,
G_TYPE_OBJECT  ,
G_IMPLEMENT_INTERFACE(FL_TYPE_KEY_RESPONDER, fl_key_embedder_responder_iface_init  
)

◆ handle_response()

static void handle_response ( bool  handled,
gpointer  user_data 
)
static

Definition at line 340 of file fl_key_embedder_responder.cc.

340  {
341  g_autoptr(FlKeyEmbedderUserData) data = FL_KEY_EMBEDDER_USER_DATA(user_data);
342 
343  g_return_if_fail(data->callback != nullptr);
344 
345  data->callback(handled, data->user_data);
346 }

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 250 of file fl_key_embedder_responder.cc.

252  {
253  FlKeyEmbedderCheckedKey* checked_key =
254  reinterpret_cast<FlKeyEmbedderCheckedKey*>(value);
255  GHashTable* table = reinterpret_cast<GHashTable*>(user_data);
256  g_hash_table_insert(table,
258  GUINT_TO_POINTER(lock_bit));
259 }

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 712 of file fl_key_embedder_responder.cc.

714  {
715  ModifierLogicalToPhysicalContext* context =
716  reinterpret_cast<ModifierLogicalToPhysicalContext*>(user_data);
717  FlKeyEmbedderCheckedKey* checked_key =
718  reinterpret_cast<FlKeyEmbedderCheckedKey*>(value);
719 
720  if (checked_key->primary_physical_key == context->physical_key_from_event) {
721  context->known_modifier_physical_key = true;
722  }
723 }

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 415 of file fl_key_embedder_responder.cc.

417  {
418  if (!is_down) {
419  return;
420  }
421  const guint mode_bit = GPOINTER_TO_UINT(g_hash_table_lookup(
422  self->logical_key_to_lock_bit, uint64_to_gpointer(logical_key)));
423  if (mode_bit != 0) {
424  self->lock_records ^= mode_bit;
425  }
426 }

References self, and 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 605 of file fl_key_embedder_responder.cc.

607  {
608  SyncStateLoopContext* context =
609  reinterpret_cast<SyncStateLoopContext*>(user_data);
610  FlKeyEmbedderCheckedKey* checked_key =
611  reinterpret_cast<FlKeyEmbedderCheckedKey*>(value);
612 
613  guint modifier_bit = GPOINTER_TO_INT(key);
614  FlKeyEmbedderResponder* self = context->self;
615 
616  const uint64_t logical_key = checked_key->primary_logical_key;
617  const uint64_t recorded_physical_key =
618  lookup_hash_table(self->mapping_records, logical_key);
619  // The physical key is derived from past mapping record if possible.
620  //
621  // If the event to be synthesized is a key up event, then there must have
622  // been a key down event before, which has updated the mapping record.
623  // If the event to be synthesized is a key down event, then there might
624  // not have been a mapping record, in which case the hard-coded
625  // #primary_physical_key is used.
626  const uint64_t physical_key = recorded_physical_key != 0
627  ? recorded_physical_key
628  : checked_key->primary_physical_key;
629 
630  // A lock mode key can be at any of a 4-stage cycle, depending on whether it's
631  // pressed and enabled. The following table lists the definition of each
632  // stage (TruePressed and TrueEnabled), the event of the lock key between
633  // every 2 stages (SelfType and SelfState), and the event of other keys at
634  // each stage (OthersState). On certain platforms SelfState uses a reversed
635  // rule for certain keys (SelfState(rvsd), as documented in
636  // #update_caps_lock_state_logic_inferrence).
637  //
638  // # [0] [1] [2] [3]
639  // TruePressed: Released Pressed Released Pressed
640  // TrueEnabled: Disabled Enabled Enabled Disabled
641  // SelfType: Down Up Down Up
642  // SelfState: 0 1 1 1
643  // SelfState(rvsd): 1 1 0 1
644  // OthersState: 0 1 1 1
645  //
646  // When the exact stage can't be derived, choose the stage that requires the
647  // minimal synthesization.
648 
649  const uint64_t pressed_logical_key =
650  recorded_physical_key == 0
651  ? 0
652  : lookup_hash_table(self->pressing_records, recorded_physical_key);
653 
654  g_return_if_fail(pressed_logical_key == 0 ||
655  pressed_logical_key == logical_key);
656  const int stage_by_record = find_stage_by_record(
657  pressed_logical_key != 0, (self->lock_records & modifier_bit) != 0);
658 
659  const bool enabled_by_state = (context->state & modifier_bit) != 0;
660  const bool this_key_is_event_key = logical_key == context->event_logical_key;
661  if (this_key_is_event_key && checked_key->is_caps_lock) {
662  update_caps_lock_state_logic_inferrence(self, context->is_down,
663  enabled_by_state, stage_by_record);
664  g_return_if_fail(self->caps_lock_state_logic_inferrence !=
665  kStateLogicUndecided);
666  }
667  const bool reverse_state_logic =
668  checked_key->is_caps_lock &&
669  self->caps_lock_state_logic_inferrence == kStateLogicReversed;
670  const int stage_by_event =
671  this_key_is_event_key
672  ? find_stage_by_self_event(stage_by_record, context->is_down,
673  enabled_by_state, reverse_state_logic)
674  : find_stage_by_others_event(stage_by_record, enabled_by_state);
675 
676  // The destination stage is equal to stage_by_event but shifted cyclically to
677  // be no less than stage_by_record.
678  constexpr int kNumStages = 4;
679  const int destination_stage = stage_by_event >= stage_by_record
680  ? stage_by_event
681  : stage_by_event + kNumStages;
682 
683  g_return_if_fail(stage_by_record <= destination_stage);
684  if (stage_by_record == destination_stage) {
685  return;
686  }
687  for (int current_stage = stage_by_record; current_stage < destination_stage;
688  current_stage += 1) {
689  if (current_stage == 9) {
690  return;
691  }
692 
693  const int standard_current_stage = current_stage % kNumStages;
694  const bool is_down_event =
695  standard_current_stage == 0 || standard_current_stage == 2;
696  if (is_down_event && recorded_physical_key == 0) {
697  update_mapping_record(self, physical_key, logical_key);
698  }
699  FlutterKeyEventType type =
700  is_down_event ? kFlutterKeyEventTypeDown : kFlutterKeyEventTypeUp;
701  update_pressing_state(self, physical_key, is_down_event ? logical_key : 0);
702  possibly_update_lock_bit(self, logical_key, is_down_event);
703  synthesize_simple_event(self, type, physical_key, logical_key,
704  context->timestamp);
705  }
706 }

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, self, synthesize_simple_event(), 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 439 of file fl_key_embedder_responder.cc.

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

References lookup_hash_table(), FlKeyEmbedderCheckedKey::primary_logical_key, FlKeyEmbedderCheckedKey::primary_physical_key, reverse_lookup_hash_table(), FlKeyEmbedderCheckedKey::secondary_logical_key, self, 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 349 of file fl_key_embedder_responder.cc.

353  {
354  FlutterKeyEvent out_event;
355  out_event.struct_size = sizeof(out_event);
356  out_event.timestamp = timestamp;
357  out_event.type = type;
358  out_event.physical = physical;
359  out_event.logical = logical;
360  out_event.character = nullptr;
361  out_event.synthesized = true;
362  self->sent_any_events = true;
363  self->send_key_event(&out_event, nullptr, nullptr);
364 }

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 578 of file fl_key_embedder_responder.cc.

582  {
583  if (self->caps_lock_state_logic_inferrence != kStateLogicUndecided) {
584  return;
585  }
586  if (!is_down_event) {
587  return;
588  }
589  const int stage_by_event = find_stage_by_self_event(
590  stage_by_record, is_down_event, enabled_by_state, false);
591  if ((stage_by_event == 0 && stage_by_record == 2) ||
592  (stage_by_event == 2 && stage_by_record == 0)) {
593  self->caps_lock_state_logic_inferrence = kStateLogicReversed;
594  } else {
595  self->caps_lock_state_logic_inferrence = kStateLogicNormal;
596  }
597 }

References find_stage_by_self_event(), and self.

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 428 of file fl_key_embedder_responder.cc.

430  {
431  g_hash_table_insert(self->mapping_records, uint64_to_gpointer(logical_key),
432  uint64_to_gpointer(physical_key));
433 }

References self, and 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 394 of file fl_key_embedder_responder.cc.

396  {
397  if (logical_key != 0) {
398  g_return_if_fail(lookup_hash_table(self->pressing_records, physical_key) ==
399  0);
400  g_hash_table_insert(self->pressing_records,
401  uint64_to_gpointer(physical_key),
402  uint64_to_gpointer(logical_key));
403  } else {
404  g_return_if_fail(lookup_hash_table(self->pressing_records, physical_key) !=
405  0);
406  g_hash_table_remove(self->pressing_records,
407  uint64_to_gpointer(physical_key));
408  }
409 }

References lookup_hash_table(), self, 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

◆ callback

◆ event

◆ 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

◆ specified_logical_key

FlKeyEvent uint64_t specified_logical_key

◆ user_data

gtk_keyval_to_logical_key_map
std::map< uint64_t, uint64_t > gtk_keyval_to_logical_key_map
Definition: key_mapping.g.cc:240
fl_key_embedder_user_data_new
static FlKeyEmbedderUserData * fl_key_embedder_user_data_new(FlKeyResponderAsyncCallback callback, gpointer user_data)
Definition: fl_key_embedder_responder.cc:117
apply_id_plane
static uint64_t apply_id_plane(uint64_t logical_id, uint64_t plane)
Definition: fl_key_embedder_responder.cc:293
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:536
event_to_timestamp
static uint64_t event_to_timestamp(const FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:319
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_embedder_responder.cc:217
FlKeyEmbedderCheckedKey::is_caps_lock
bool is_caps_lock
Definition: fl_key_embedder_responder_private.h:43
to_lower
static uint64_t to_lower(uint64_t n)
Definition: fl_key_embedder_responder.cc:53
FL_TYPE_EMBEDDER_RESPONDER_USER_DATA
#define FL_TYPE_EMBEDDER_RESPONDER_USER_DATA
Definition: fl_key_embedder_responder.cc:203
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:349
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:514
FL_TYPE_EMBEDDER_USER_DATA
#define FL_TYPE_EMBEDDER_USER_DATA
Definition: fl_key_embedder_responder.cc:83
event_to_logical_key
static uint64_t event_to_logical_key(const FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:305
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:439
event
FlKeyEvent * event
Definition: fl_key_embedder_responder.cc:214
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:551
state
AtkStateType state
Definition: fl_accessible_node.cc:10
_FlValue::type
FlValueType type
Definition: fl_value.cc:12
update_pressing_state
static void update_pressing_state(FlKeyEmbedderResponder *self, uint64_t physical_key, uint64_t logical_key)
Definition: fl_key_embedder_responder.cc:394
fl_key_embedder_responder_handle_event
static void fl_key_embedder_responder_handle_event(FlKeyResponder *responder, FlKeyEvent *event, uint64_t specified_logical_key, FlKeyResponderAsyncCallback callback, gpointer user_data)
Definition: fl_key_embedder_responder.cc:857
find_stage_by_record
static int find_stage_by_record(bool is_down, bool is_enabled)
Definition: fl_key_embedder_responder.cc:524
fl_key_embedder_responder_handle_event_impl
static void fl_key_embedder_responder_handle_event_impl(FlKeyResponder *responder, FlKeyEvent *event, uint64_t specified_logical_key, FlKeyResponderAsyncCallback callback, gpointer user_data)
Definition: fl_key_embedder_responder.cc:771
event_to_physical_key
static uint64_t event_to_physical_key(const FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:297
specified_logical_key
FlKeyEvent uint64_t specified_logical_key
Definition: fl_key_embedder_responder.cc:215
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:729
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:515
_FlKeyEvent::keycode
guint16 keycode
Definition: fl_key_event.h:37
callback
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Definition: fl_key_embedder_responder.cc:216
event_to_character
static char * event_to_character(const FlKeyEvent *event)
Definition: fl_key_embedder_responder.cc:325
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:513
fl_key_embedder_responder_dispose
static void fl_key_embedder_responder_dispose(GObject *object)
Definition: fl_key_embedder_responder.cc:234
initialize_lock_bit_to_checked_keys
void initialize_lock_bit_to_checked_keys(GHashTable *table)
Definition: key_mapping.g.cc:446
_FlKeyEvent::keyval
guint keyval
Definition: fl_key_event.h:39
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:578
lookup_hash_table
static uint64_t lookup_hash_table(GHashTable *table, uint64_t key)
Definition: fl_key_embedder_responder.cc:31
self
GdkEvent FlView * self
Definition: fl_view.cc:100
result
GAsyncResult * result
Definition: fl_text_input_plugin.cc:106
FlKeyEmbedderCheckedKey::primary_physical_key
uint64_t primary_physical_key
Definition: fl_key_embedder_responder_private.h:36
reverse_lookup_hash_table
static uint64_t reverse_lookup_hash_table(GHashTable *table, uint64_t value)
Definition: fl_key_embedder_responder.cc:48
kMicrosecondsPerMillisecond
constexpr uint64_t kMicrosecondsPerMillisecond
Definition: fl_key_embedder_responder.cc:14
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:605
FlKeyEmbedderCheckedKey::secondary_logical_key
uint64_t secondary_logical_key
Definition: fl_key_embedder_responder_private.h:40
send_key_event
static void send_key_event(FlTextInputPlugin *plugin, gint keyval, gint state=0)
Definition: fl_text_input_plugin_test.cc:181
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:712
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:250
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:743
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:38
handle_response
static void handle_response(bool handled, gpointer user_data)
Definition: fl_key_embedder_responder.cc:340
value
uint8_t value
Definition: fl_standard_message_codec.cc:41
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:415
FlKeyEmbedderCheckedKey
Definition: fl_key_embedder_responder_private.h:34
update_mapping_record
static void update_mapping_record(FlKeyEmbedderResponder *self, uint64_t physical_key, uint64_t logical_key)
Definition: fl_key_embedder_responder.cc:428
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:108