10 #include "flutter/shell/platform/embedder/embedder.h"
17 .struct_size =
sizeof(FlutterKeyEvent),
19 .
type = kFlutterKeyEventTypeDown,
54 constexpr uint64_t lower_a = 0x61;
55 constexpr uint64_t upper_a = 0x41;
56 constexpr uint64_t upper_z = 0x5a;
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;
64 if (n >= upper_a && n <= upper_z) {
65 return n - upper_a + lower_a;
69 if (n >= upper_a_grave && n <= upper_thorn && n != division) {
70 return n - upper_a_grave + lower_a_grave;
82 fl_key_embedder_user_data,
84 KEY_EMBEDDER_USER_DATA,
94 G_DEFINE_TYPE(FlKeyEmbedderUserData, fl_key_embedder_user_data, G_TYPE_OBJECT)
99 FlKeyEmbedderUserDataClass* klass) {
108 g_return_if_fail(FL_IS_KEY_EMBEDDER_USER_DATA(
object));
117 FlKeyEmbedderUserData*
self = FL_KEY_EMBEDDER_USER_DATA(
118 g_object_new(fl_key_embedder_user_data_get_type(),
nullptr));
120 self->callback = callback;
128 STATE_LOGIC_INFERRENCE_UNDECIDED,
129 STATE_LOGIC_INFERRENCE_NORMAL,
130 STATE_LOGIC_INFERRENCE_REVERSED,
131 } StateLogicInferrence;
197 G_DEFINE_TYPE(FlKeyEmbedderResponder, fl_key_embedder_responder, G_TYPE_OBJECT)
201 FlKeyEmbedderResponderClass* klass) {
210 FlKeyEmbedderResponder*
self = FL_KEY_EMBEDDER_RESPONDER(
object);
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);
218 G_OBJECT_CLASS(fl_key_embedder_responder_parent_class)->dispose(
object);
230 GHashTable* table =
reinterpret_cast<GHashTable*
>(
user_data);
231 g_hash_table_insert(table,
233 GUINT_TO_POINTER(lock_bit));
239 void* send_key_event_user_data) {
240 FlKeyEmbedderResponder*
self = FL_KEY_EMBEDDER_RESPONDER(
241 g_object_new(fl_key_embedder_responder_get_type(),
nullptr));
244 self->send_key_event_user_data = send_key_event_user_data;
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;
251 self->modifier_bit_to_checked_keys =
252 g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
255 self->lock_bit_to_checked_keys =
256 g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
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);
275 return found->second;
284 return found->second;
304 gchar* result = g_ucs4_to_utf8(&unicodeChar, 1, NULL, &items_written, NULL);
305 if (items_written == 0) {
306 if (result != NULL) {
317 g_autoptr(FlKeyEmbedderUserData) data = FL_KEY_EMBEDDER_USER_DATA(
user_data);
319 g_return_if_fail(data->callback !=
nullptr);
321 data->callback(handled, data->user_data);
326 FlutterKeyEventType
type,
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);
348 FlKeyEmbedderResponder*
self;
350 uint64_t event_logical_key;
353 } SyncStateLoopContext;
358 bool known_modifier_physical_key;
359 uint64_t logical_key;
360 uint64_t physical_key_from_event;
361 uint64_t corrected_physical_key;
362 } ModifierLogicalToPhysicalContext;
372 uint64_t physical_key,
373 uint64_t logical_key) {
374 if (logical_key != 0) {
377 g_hash_table_insert(self->pressing_records,
383 g_hash_table_remove(self->pressing_records,
393 uint64_t logical_key,
398 const guint mode_bit = GPOINTER_TO_UINT(g_hash_table_lookup(
401 self->lock_records ^= mode_bit;
406 uint64_t physical_key,
407 uint64_t logical_key) {
419 SyncStateLoopContext* context =
420 reinterpret_cast<SyncStateLoopContext*
>(
user_data);
424 const guint modifier_bit = GPOINTER_TO_INT(key);
425 FlKeyEmbedderResponder*
self = context->self;
434 const uint64_t logical_keys[] = {
440 const bool any_pressed_by_state = (context->state & modifier_bit) != 0;
442 bool any_pressed_by_record =
false;
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 =
456 const bool this_key_pressed_before_event = pressing_physical_key != 0;
458 any_pressed_by_record =
459 any_pressed_by_record || this_key_pressed_before_event;
461 if (this_key_pressed_before_event && !any_pressed_by_state) {
462 const uint64_t recorded_physical_key =
466 g_return_if_fail(recorded_physical_key != 0);
468 const uint64_t recorded_logical_key =
471 recorded_physical_key, recorded_logical_key,
478 if (any_pressed_by_state && !any_pressed_by_record) {
480 const uint64_t recorded_physical_key =
487 const uint64_t physical_key = recorded_physical_key != 0
488 ? recorded_physical_key
490 if (recorded_physical_key == 0) {
494 logical_key, context->timestamp);
502 constexpr
int stage_by_record_index[] = {
508 return stage_by_record_index[(is_down << 1) + is_enabled];
516 bool reverse_state_logic) {
518 return reverse_state_logic ? 2 : 0;
521 return reverse_state_logic ? 0 : 2;
523 return stage_by_record;
529 g_return_val_if_fail(stage_by_record >= 0 && stage_by_record < 4,
534 if (stage_by_record == 0) {
537 return stage_by_record;
556 FlKeyEmbedderResponder*
self,
558 bool enabled_by_state,
559 int stage_by_record) {
560 if (self->caps_lock_state_logic_inferrence !=
561 STATE_LOGIC_INFERRENCE_UNDECIDED) {
564 if (!is_down_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;
573 self->caps_lock_state_logic_inferrence = STATE_LOGIC_INFERRENCE_NORMAL;
586 SyncStateLoopContext* context =
587 reinterpret_cast<SyncStateLoopContext*
>(
user_data);
591 guint modifier_bit = GPOINTER_TO_INT(key);
592 FlKeyEmbedderResponder*
self = context->self;
595 const uint64_t recorded_physical_key =
604 const uint64_t physical_key = recorded_physical_key != 0
605 ? recorded_physical_key
627 const uint64_t pressed_logical_key =
628 recorded_physical_key == 0
632 g_return_if_fail(pressed_logical_key == 0 ||
633 pressed_logical_key == logical_key);
635 pressed_logical_key != 0, (self->lock_records & modifier_bit) != 0);
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) {
641 enabled_by_state, stage_by_record);
642 g_return_if_fail(self->caps_lock_state_logic_inferrence !=
643 STATE_LOGIC_INFERRENCE_UNDECIDED);
645 const bool reverse_state_logic =
647 self->caps_lock_state_logic_inferrence == STATE_LOGIC_INFERRENCE_REVERSED;
648 const int stage_by_event =
649 this_key_is_event_key
651 enabled_by_state, reverse_state_logic)
656 constexpr
int kNumStages = 4;
657 const int destination_stage = stage_by_event >= stage_by_record
659 : stage_by_event + kNumStages;
661 g_return_if_fail(stage_by_record <= destination_stage);
662 if (stage_by_record == destination_stage) {
665 for (
int current_stage = stage_by_record; current_stage < destination_stage;
666 current_stage += 1) {
667 if (current_stage == 9) {
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) {
677 FlutterKeyEventType
type =
678 is_down_event ? kFlutterKeyEventTypeDown : kFlutterKeyEventTypeUp;
693 ModifierLogicalToPhysicalContext* context =
694 reinterpret_cast<ModifierLogicalToPhysicalContext*
>(
user_data);
699 context->known_modifier_physical_key =
true;
710 ModifierLogicalToPhysicalContext* context =
711 reinterpret_cast<ModifierLogicalToPhysicalContext*
>(
user_data);
722 GHashTable* modifier_bit_to_checked_keys,
723 uint64_t physical_key_from_event,
724 uint64_t logical_key) {
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;
731 logical_to_physical_context.corrected_physical_key = physical_key_from_event;
734 g_hash_table_foreach(modifier_bit_to_checked_keys,
736 &logical_to_physical_context);
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);
746 return logical_to_physical_context.corrected_physical_key;
750 FlKeyEmbedderResponder* responder,
752 uint64_t specified_logical_key,
755 FlKeyEmbedderResponder*
self = FL_KEY_EMBEDDER_RESPONDER(responder);
757 g_return_if_fail(event !=
nullptr);
758 g_return_if_fail(callback !=
nullptr);
760 const uint64_t logical_key = specified_logical_key != 0
761 ? specified_logical_key
765 self->modifier_bit_to_checked_keys, physical_key_from_event, logical_key);
769 SyncStateLoopContext sync_state_context;
770 sync_state_context.self =
self;
772 sync_state_context.timestamp = timestamp;
773 sync_state_context.is_down = is_down_event;
774 sync_state_context.event_logical_key = logical_key;
777 g_hash_table_foreach(self->lock_bit_to_checked_keys,
781 g_hash_table_foreach(self->modifier_bit_to_checked_keys,
783 &sync_state_context);
786 const uint64_t last_logical_record =
789 FlutterKeyEvent out_event;
790 out_event.struct_size =
sizeof(out_event);
791 out_event.timestamp = timestamp;
792 out_event.physical = physical_key;
794 last_logical_record != 0 ? last_logical_record : logical_key;
795 out_event.character =
nullptr;
796 out_event.synthesized =
false;
798 g_autofree
char* character_to_free =
nullptr;
800 if (last_logical_record) {
803 out_event.type = kFlutterKeyEventTypeRepeat;
805 out_event.type = kFlutterKeyEventTypeDown;
808 out_event.character = character_to_free;
810 if (!last_logical_record) {
817 out_event.type = kFlutterKeyEventTypeUp;
821 if (out_event.type != kFlutterKeyEventTypeRepeat) {
828 FlKeyEmbedderUserData* response_data =
830 self->sent_any_events =
true;
832 self->send_key_event_user_data);
836 FlKeyEmbedderResponder*
self,
838 uint64_t specified_logical_key,
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);
851 FlKeyEmbedderResponder* responder,
856 SyncStateLoopContext sync_state_context;
857 sync_state_context.self = responder;
858 sync_state_context.state =
state;
859 sync_state_context.timestamp = timestamp;
862 g_hash_table_foreach(responder->modifier_bit_to_checked_keys,
864 &sync_state_context);
868 FlKeyEmbedderResponder*
self) {
869 return self->pressing_records;