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;
83 #define FL_TYPE_EMBEDDER_USER_DATA fl_key_embedder_user_data_get_type()
85 fl_key_embedder_user_data,
87 KEY_EMBEDDER_USER_DATA,
97 G_DEFINE_TYPE(FlKeyEmbedderUserData, fl_key_embedder_user_data, G_TYPE_OBJECT)
102 FlKeyEmbedderUserDataClass* klass) {
111 g_return_if_fail(FL_IS_KEY_EMBEDDER_USER_DATA(
object));
120 FlKeyEmbedderUserData*
self = FL_KEY_EMBEDDER_USER_DATA(
133 kStateLogicUndecided,
136 } StateLogicInferrence;
201 FlKeyResponderInterface* iface);
204 #define FL_TYPE_EMBEDDER_RESPONDER_USER_DATA \
205 fl_key_embedder_responder_get_type()
207 FlKeyEmbedderResponder,
208 fl_key_embedder_responder,
214 FlKeyResponder* responder,
221 FlKeyResponderInterface* iface) {
227 FlKeyEmbedderResponderClass* klass) {
236 FlKeyEmbedderResponder*
self = FL_KEY_EMBEDDER_RESPONDER(
object);
238 g_clear_pointer(&self->pressing_records, g_hash_table_unref);
239 g_clear_pointer(&self->mapping_records, g_hash_table_unref);
240 g_clear_pointer(&self->modifier_bit_to_checked_keys, g_hash_table_unref);
241 g_clear_pointer(&self->lock_bit_to_checked_keys, g_hash_table_unref);
242 g_clear_pointer(&self->logical_key_to_lock_bit, g_hash_table_unref);
244 G_OBJECT_CLASS(fl_key_embedder_responder_parent_class)->dispose(
object);
256 GHashTable* table =
reinterpret_cast<GHashTable*
>(
user_data);
257 g_hash_table_insert(table,
259 GUINT_TO_POINTER(lock_bit));
265 void* send_key_event_user_data) {
266 FlKeyEmbedderResponder*
self = FL_KEY_EMBEDDER_RESPONDER(
270 self->send_key_event_user_data = send_key_event_user_data;
272 self->pressing_records = g_hash_table_new(g_direct_hash, g_direct_equal);
273 self->mapping_records = g_hash_table_new(g_direct_hash, g_direct_equal);
274 self->lock_records = 0;
275 self->caps_lock_state_logic_inferrence = kStateLogicUndecided;
277 self->modifier_bit_to_checked_keys =
278 g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
281 self->lock_bit_to_checked_keys =
282 g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
285 self->logical_key_to_lock_bit =
286 g_hash_table_new(g_direct_hash, g_direct_equal);
287 g_hash_table_foreach(self->lock_bit_to_checked_keys,
289 self->logical_key_to_lock_bit);
303 return found->second;
312 return found->second;
332 gchar*
result = g_ucs4_to_utf8(&unicodeChar, 1, NULL, &items_written, NULL);
333 if (items_written == 0) {
345 g_autoptr(FlKeyEmbedderUserData) data = FL_KEY_EMBEDDER_USER_DATA(
user_data);
347 g_return_if_fail(data->callback !=
nullptr);
349 data->callback(handled, data->user_data);
354 FlutterKeyEventType
type,
358 FlutterKeyEvent out_event;
359 out_event.struct_size =
sizeof(out_event);
360 out_event.timestamp = timestamp;
361 out_event.type =
type;
362 out_event.physical = physical;
363 out_event.logical = logical;
364 out_event.character =
nullptr;
365 out_event.synthesized =
true;
366 self->sent_any_events =
true;
367 self->send_key_event(&out_event,
nullptr,
nullptr,
368 self->send_key_event_user_data);
376 FlKeyEmbedderResponder*
self;
378 uint64_t event_logical_key;
381 } SyncStateLoopContext;
386 bool known_modifier_physical_key;
387 uint64_t logical_key;
388 uint64_t physical_key_from_event;
389 uint64_t corrected_physical_key;
390 } ModifierLogicalToPhysicalContext;
400 uint64_t physical_key,
401 uint64_t logical_key) {
402 if (logical_key != 0) {
405 g_hash_table_insert(self->pressing_records,
411 g_hash_table_remove(self->pressing_records,
421 uint64_t logical_key,
426 const guint mode_bit = GPOINTER_TO_UINT(g_hash_table_lookup(
429 self->lock_records ^= mode_bit;
434 uint64_t physical_key,
435 uint64_t logical_key) {
447 SyncStateLoopContext* context =
448 reinterpret_cast<SyncStateLoopContext*
>(
user_data);
452 const guint modifier_bit = GPOINTER_TO_INT(key);
453 FlKeyEmbedderResponder*
self = context->self;
462 const uint64_t logical_keys[] = {
468 const bool any_pressed_by_state = (context->state & modifier_bit) != 0;
470 bool any_pressed_by_record =
false;
479 for (guint logical_key_idx = 0; logical_key_idx <
length; logical_key_idx++) {
480 const uint64_t logical_key = logical_keys[logical_key_idx];
481 g_return_if_fail(logical_key != 0);
482 const uint64_t pressing_physical_key =
484 const bool this_key_pressed_before_event = pressing_physical_key != 0;
486 any_pressed_by_record =
487 any_pressed_by_record || this_key_pressed_before_event;
489 if (this_key_pressed_before_event && !any_pressed_by_state) {
490 const uint64_t recorded_physical_key =
494 g_return_if_fail(recorded_physical_key != 0);
496 const uint64_t recorded_logical_key =
499 recorded_physical_key, recorded_logical_key,
506 if (any_pressed_by_state && !any_pressed_by_record) {
508 const uint64_t recorded_physical_key =
515 const uint64_t physical_key = recorded_physical_key != 0
516 ? recorded_physical_key
518 if (recorded_physical_key == 0) {
522 logical_key, context->timestamp);
530 constexpr
int stage_by_record_index[] = {
536 return stage_by_record_index[(is_down << 1) + is_enabled];
544 bool reverse_state_logic) {
546 return reverse_state_logic ? 2 : 0;
549 return reverse_state_logic ? 0 : 2;
551 return stage_by_record;
557 g_return_val_if_fail(stage_by_record >= 0 && stage_by_record < 4,
562 if (stage_by_record == 0) {
565 return stage_by_record;
584 FlKeyEmbedderResponder*
self,
586 bool enabled_by_state,
587 int stage_by_record) {
588 if (self->caps_lock_state_logic_inferrence != kStateLogicUndecided) {
591 if (!is_down_event) {
595 stage_by_record, is_down_event, enabled_by_state,
false);
596 if ((stage_by_event == 0 && stage_by_record == 2) ||
597 (stage_by_event == 2 && stage_by_record == 0)) {
598 self->caps_lock_state_logic_inferrence = kStateLogicReversed;
600 self->caps_lock_state_logic_inferrence = kStateLogicNormal;
613 SyncStateLoopContext* context =
614 reinterpret_cast<SyncStateLoopContext*
>(
user_data);
618 guint modifier_bit = GPOINTER_TO_INT(key);
619 FlKeyEmbedderResponder*
self = context->self;
622 const uint64_t recorded_physical_key =
631 const uint64_t physical_key = recorded_physical_key != 0
632 ? recorded_physical_key
654 const uint64_t pressed_logical_key =
655 recorded_physical_key == 0
659 g_return_if_fail(pressed_logical_key == 0 ||
660 pressed_logical_key == logical_key);
662 pressed_logical_key != 0, (self->lock_records & modifier_bit) != 0);
664 const bool enabled_by_state = (context->state & modifier_bit) != 0;
665 const bool this_key_is_event_key = logical_key == context->event_logical_key;
666 if (this_key_is_event_key && checked_key->
is_caps_lock) {
668 enabled_by_state, stage_by_record);
669 g_return_if_fail(self->caps_lock_state_logic_inferrence !=
670 kStateLogicUndecided);
672 const bool reverse_state_logic =
674 self->caps_lock_state_logic_inferrence == kStateLogicReversed;
675 const int stage_by_event =
676 this_key_is_event_key
678 enabled_by_state, reverse_state_logic)
683 constexpr
int kNumStages = 4;
684 const int destination_stage = stage_by_event >= stage_by_record
686 : stage_by_event + kNumStages;
688 g_return_if_fail(stage_by_record <= destination_stage);
689 if (stage_by_record == destination_stage) {
692 for (
int current_stage = stage_by_record; current_stage < destination_stage;
693 current_stage += 1) {
694 if (current_stage == 9) {
698 const int standard_current_stage = current_stage % kNumStages;
699 const bool is_down_event =
700 standard_current_stage == 0 || standard_current_stage == 2;
701 if (is_down_event && recorded_physical_key == 0) {
704 FlutterKeyEventType
type =
705 is_down_event ? kFlutterKeyEventTypeDown : kFlutterKeyEventTypeUp;
720 ModifierLogicalToPhysicalContext* context =
721 reinterpret_cast<ModifierLogicalToPhysicalContext*
>(
user_data);
726 context->known_modifier_physical_key =
true;
737 ModifierLogicalToPhysicalContext* context =
738 reinterpret_cast<ModifierLogicalToPhysicalContext*
>(
user_data);
749 GHashTable* modifier_bit_to_checked_keys,
750 uint64_t physical_key_from_event,
751 uint64_t logical_key) {
752 ModifierLogicalToPhysicalContext logical_to_physical_context;
753 logical_to_physical_context.known_modifier_physical_key =
false;
754 logical_to_physical_context.physical_key_from_event = physical_key_from_event;
755 logical_to_physical_context.logical_key = logical_key;
758 logical_to_physical_context.corrected_physical_key = physical_key_from_event;
761 g_hash_table_foreach(modifier_bit_to_checked_keys,
763 &logical_to_physical_context);
767 if (logical_to_physical_context.known_modifier_physical_key) {
768 g_hash_table_foreach(modifier_bit_to_checked_keys,
770 &logical_to_physical_context);
773 return logical_to_physical_context.corrected_physical_key;
777 FlKeyResponder* responder,
782 FlKeyEmbedderResponder*
self = FL_KEY_EMBEDDER_RESPONDER(responder);
784 g_return_if_fail(
event !=
nullptr);
785 g_return_if_fail(
callback !=
nullptr);
792 self->modifier_bit_to_checked_keys, physical_key_from_event, logical_key);
796 SyncStateLoopContext sync_state_context;
797 sync_state_context.self =
self;
799 sync_state_context.timestamp = timestamp;
800 sync_state_context.is_down = is_down_event;
801 sync_state_context.event_logical_key = logical_key;
804 g_hash_table_foreach(self->lock_bit_to_checked_keys,
808 g_hash_table_foreach(self->modifier_bit_to_checked_keys,
810 &sync_state_context);
813 const uint64_t last_logical_record =
816 FlutterKeyEvent out_event;
817 out_event.struct_size =
sizeof(out_event);
818 out_event.timestamp = timestamp;
819 out_event.physical = physical_key;
821 last_logical_record != 0 ? last_logical_record : logical_key;
822 out_event.character =
nullptr;
823 out_event.synthesized =
false;
825 g_autofree
char* character_to_free =
nullptr;
827 if (last_logical_record) {
830 out_event.type = kFlutterKeyEventTypeRepeat;
832 out_event.type = kFlutterKeyEventTypeDown;
835 out_event.character = character_to_free;
837 if (!last_logical_record) {
844 out_event.type = kFlutterKeyEventTypeUp;
848 if (out_event.type != kFlutterKeyEventTypeRepeat) {
855 FlKeyEmbedderUserData* response_data =
857 self->sent_any_events =
true;
859 self->send_key_event_user_data);
864 FlKeyResponder* responder,
869 FlKeyEmbedderResponder*
self = FL_KEY_EMBEDDER_RESPONDER(responder);
870 self->sent_any_events =
false;
873 if (!self->sent_any_events) {
874 self->send_key_event(&
kEmptyEvent,
nullptr,
nullptr,
875 self->send_key_event_user_data);
880 FlKeyEmbedderResponder* responder,
885 SyncStateLoopContext sync_state_context;
886 sync_state_context.self = responder;
887 sync_state_context.state =
state;
888 sync_state_context.timestamp = timestamp;
891 g_hash_table_foreach(responder->modifier_bit_to_checked_keys,
893 &sync_state_context);
897 FlKeyEmbedderResponder*
self) {
898 return self->pressing_records;