summaryrefslogtreecommitdiff
path: root/src/bin/keyin.c
diff options
context:
space:
mode:
authorBoris Faure <billiob@gmail.com>2014-08-23 17:01:20 +0200
committerBoris Faure <billiob@gmail.com>2014-09-02 20:42:45 +0200
commit2f9532d28c1526c0dd96cb8544a4f9ea836c77e4 (patch)
tree2a192ede92979f348753cb283f361538606ea41c /src/bin/keyin.c
parenteab93284b7b08a085c95b39f828a8329e1ecc43b (diff)
store keybindings in a hash map
Diffstat (limited to 'src/bin/keyin.c')
-rw-r--r--src/bin/keyin.c140
1 files changed, 132 insertions, 8 deletions
diff --git a/src/bin/keyin.c b/src/bin/keyin.c
index 230c6e1..aa823b9 100644
--- a/src/bin/keyin.c
+++ b/src/bin/keyin.c
@@ -18,6 +18,8 @@ struct _Keyout
18 int outlen; 18 int outlen;
19}; 19};
20 20
21static Eina_Hash *_key_bindings = NULL;
22
21 23
22 24
23#define KEY(in, out) {in, out, sizeof(in) - 1, sizeof(out) - 1} 25#define KEY(in, out) {in, out, sizeof(in) - 1, sizeof(out) - 1}
@@ -622,19 +624,43 @@ _handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
622 } 624 }
623} 625}
624 626
627static Key_Binding *
628key_binding_lookup(const Evas_Event_Key_Down *ev,
629 Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift)
630{
631 Key_Binding *kb;
632 size_t len = strlen(ev->keyname);
633
634 if (len > UINT16_MAX) return NULL;
635
636 kb = alloca(sizeof(Key_Binding) + len + 1);
637 if (!kb) return NULL;
638 kb->ctrl = ctrl;
639 kb->alt = alt;
640 kb->shift = shift;
641 kb->len = len;
642 strncpy(kb->keyname, ev->keyname, kb->len + 1);
643
644 return eina_hash_find(_key_bindings, kb);
645}
646
625Eina_Bool 647Eina_Bool
626keyin_handle(Keys_Handler *khdl, Termpty *ty, const Evas_Event_Key_Down *ev, 648keyin_handle(Keys_Handler *khdl, Termpty *ty, const Evas_Event_Key_Down *ev,
627 int alt, int shift, int ctrl) 649 Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift)
628{ 650{
651 Key_Binding *kb;
652
653 kb = key_binding_lookup(ev, ctrl, alt, shift);
654 if (kb)
655 {
656 if (kb->cb(ty->obj))
657 goto end;
658 }
659
660
629 if ((!alt) && (ctrl) && (!shift)) 661 if ((!alt) && (ctrl) && (!shift))
630 { 662 {
631 if (!strcmp(ev->key, "Prior")) 663 if (!strcmp(ev->key, "Next"))
632 {
633 keyin_compose_seq_reset(khdl);
634 evas_object_smart_callback_call(ty->obj, "prev", NULL);
635 return EINA_TRUE;
636 }
637 else if (!strcmp(ev->key, "Next"))
638 { 664 {
639 keyin_compose_seq_reset(khdl); 665 keyin_compose_seq_reset(khdl);
640 evas_object_smart_callback_call(ty->obj, "next", NULL); 666 evas_object_smart_callback_call(ty->obj, "next", NULL);
@@ -877,3 +903,101 @@ keyin_handle_up(Keys_Handler *khdl, Evas_Event_Key_Up *ev)
877 return; 903 return;
878 } 904 }
879} 905}
906
907static Eina_Bool
908cb_term_prev(Evas_Object *term)
909{
910 evas_object_smart_callback_call(term, "prev", NULL);
911 return EINA_TRUE;
912}
913
914static unsigned int
915key_binding_key_length(EINA_UNUSED const void *key)
916{
917 return 0;
918}
919
920static int
921key_binding_key_cmp(const void *key1, int key1_length,
922 const void *key2, int key2_length)
923{
924 const Key_Binding *kb1 = key1,
925 *kb2 = key2;
926
927 if (key1_length < key2_length)
928 return -1;
929 else if (key1_length > key2_length)
930 return 1;
931 else
932 {
933 unsigned int m1 = (kb1->ctrl << 2) | (kb1->alt << 1) | kb1->shift,
934 m2 = (kb2->ctrl << 2) | (kb2->alt << 1) | kb2->shift;
935 if (m1 < m2)
936 return -1;
937 else if (m1 > m2)
938 return 1;
939 else
940 return strncmp(kb1->keyname, kb2->keyname, kb1->len);
941 }
942}
943
944static int
945key_binding_key_hash(const void *key, int key_length)
946{
947 const Key_Binding *kb = key;
948 int hash;
949
950 hash = eina_hash_djb2(key, key_length);
951 hash &= 0x1fffffff;
952 hash |= (kb->ctrl << 31) | (kb->alt << 30) | (kb->shift << 29);
953 return hash;
954}
955
956
957Key_Binding *
958key_binding_new(const char *keyname,
959 Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift,
960 Key_Binding_Cb cb)
961{
962 Key_Binding *kb;
963 size_t len = strlen(keyname);
964
965 if (len > UINT16_MAX) return NULL;
966
967 kb = malloc(sizeof(Key_Binding) + len + 1);
968 if (!kb) return NULL;
969 kb->ctrl = ctrl;
970 kb->alt = alt;
971 kb->shift = shift;
972 kb->len = len;
973 strncpy(kb->keyname, keyname, kb->len + 1);
974 kb->cb = cb;
975
976 return kb;
977}
978
979int key_bindings_init(void)
980{
981 Key_Binding *kb;
982
983 _key_bindings = eina_hash_new(key_binding_key_length,
984 key_binding_key_cmp,
985 key_binding_key_hash,
986 free,
987 5);
988 if (!_key_bindings) return -1;
989
990 kb = key_binding_new("Prior", 1, 0, 0, cb_term_prev);
991 if (!kb) return -1;
992 if (!eina_hash_direct_add(_key_bindings, kb, kb)) return -1;
993
994
995 return 0;
996}
997
998void key_bindings_shutdown(void)
999{
1000 if (_key_bindings)
1001 eina_hash_free(_key_bindings);
1002 _key_bindings = NULL;
1003}