billiob pushed a commit to branch master.

http://git.enlightenment.org/apps/terminology.git/commit/?id=2f9532d28c1526c0dd96cb8544a4f9ea836c77e4

commit 2f9532d28c1526c0dd96cb8544a4f9ea836c77e4
Author: Boris Faure <bill...@gmail.com>
Date:   Sat Aug 23 17:01:20 2014 +0200

    store keybindings in a hash map
---
 src/bin/keyin.c  | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 src/bin/keyin.h  |  24 +++++++++-
 src/bin/main.c   |   8 ++++
 src/bin/termio.c |   4 +-
 4 files changed, 165 insertions(+), 11 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
    int         outlen;
 };
 
+static Eina_Hash *_key_bindings = NULL;
+
 
 
 #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,
      }
 }
 
+static Key_Binding *
+key_binding_lookup(const Evas_Event_Key_Down *ev,
+                   Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift)
+{
+   Key_Binding *kb;
+   size_t len = strlen(ev->keyname);
+
+   if (len > UINT16_MAX) return NULL;
+
+   kb = alloca(sizeof(Key_Binding) + len + 1);
+   if (!kb) return NULL;
+   kb->ctrl = ctrl;
+   kb->alt = alt;
+   kb->shift = shift;
+   kb->len = len;
+   strncpy(kb->keyname, ev->keyname, kb->len + 1);
+
+   return eina_hash_find(_key_bindings, kb);
+}
+
 Eina_Bool
 keyin_handle(Keys_Handler *khdl, Termpty *ty, const Evas_Event_Key_Down *ev,
-             int alt, int shift, int ctrl)
+             Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift)
 {
+   Key_Binding *kb;
+
+   kb = key_binding_lookup(ev, ctrl, alt, shift);
+   if (kb)
+     {
+        if (kb->cb(ty->obj))
+          goto end;
+     }
+
+
    if ((!alt) && (ctrl) && (!shift))
      {
-        if (!strcmp(ev->key, "Prior"))
-          {
-             keyin_compose_seq_reset(khdl);
-             evas_object_smart_callback_call(ty->obj, "prev", NULL);
-             return EINA_TRUE;
-          }
-        else if (!strcmp(ev->key, "Next"))
+        if (!strcmp(ev->key, "Next"))
           {
              keyin_compose_seq_reset(khdl);
              evas_object_smart_callback_call(ty->obj, "next", NULL);
@@ -877,3 +903,101 @@ keyin_handle_up(Keys_Handler *khdl, Evas_Event_Key_Up *ev)
           return;
      }
 }
+
+static Eina_Bool
+cb_term_prev(Evas_Object *term)
+{
+   evas_object_smart_callback_call(term, "prev", NULL);
+   return EINA_TRUE;
+}
+
+static unsigned int
+key_binding_key_length(EINA_UNUSED const void *key)
+{
+   return 0;
+}
+
+static int
+key_binding_key_cmp(const void *key1, int key1_length,
+                    const void *key2, int key2_length)
+{
+   const Key_Binding *kb1 = key1,
+                     *kb2 = key2;
+
+   if (key1_length < key2_length)
+     return -1;
+   else if (key1_length > key2_length)
+     return 1;
+   else
+     {
+        unsigned int m1 = (kb1->ctrl << 2) | (kb1->alt << 1) | kb1->shift,
+                     m2 = (kb2->ctrl << 2) | (kb2->alt << 1) | kb2->shift;
+        if (m1 < m2)
+          return -1;
+        else if (m1 > m2)
+          return 1;
+        else
+          return strncmp(kb1->keyname, kb2->keyname, kb1->len);
+     }
+}
+
+static int
+key_binding_key_hash(const void *key, int key_length)
+{
+   const Key_Binding *kb = key;
+   int hash;
+
+   hash = eina_hash_djb2(key, key_length);
+   hash &= 0x1fffffff;
+   hash |= (kb->ctrl << 31) | (kb->alt << 30) | (kb->shift << 29);
+   return hash;
+}
+
+
+Key_Binding *
+key_binding_new(const char *keyname,
+                Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift,
+                Key_Binding_Cb cb)
+{
+   Key_Binding *kb;
+   size_t len = strlen(keyname);
+
+   if (len > UINT16_MAX) return NULL;
+
+   kb = malloc(sizeof(Key_Binding) + len + 1);
+   if (!kb) return NULL;
+   kb->ctrl = ctrl;
+   kb->alt = alt;
+   kb->shift = shift;
+   kb->len = len;
+   strncpy(kb->keyname, keyname, kb->len + 1);
+   kb->cb = cb;
+
+   return kb;
+}
+
+int key_bindings_init(void)
+{
+   Key_Binding *kb;
+
+   _key_bindings = eina_hash_new(key_binding_key_length,
+                                 key_binding_key_cmp,
+                                 key_binding_key_hash,
+                                 free,
+                                 5);
+   if (!_key_bindings) return -1;
+
+   kb = key_binding_new("Prior", 1, 0, 0, cb_term_prev);
+   if (!kb) return -1;
+   if (!eina_hash_direct_add(_key_bindings, kb, kb)) return -1;
+
+
+   return 0;
+}
+
+void key_bindings_shutdown(void)
+{
+   if (_key_bindings)
+     eina_hash_free(_key_bindings);
+   _key_bindings = NULL;
+}
diff --git a/src/bin/keyin.h b/src/bin/keyin.h
index a959bbb..8cb4aa3 100644
--- a/src/bin/keyin.h
+++ b/src/bin/keyin.h
@@ -14,9 +14,31 @@ struct _Keys_Handler
 void keyin_compose_seq_reset(Keys_Handler *khdl);
 Eina_Bool key_is_modifier(const char *key);
 Eina_Bool keyin_handle(Keys_Handler *khdl, Termpty *ty, const 
Evas_Event_Key_Down *ev,
-                       int alt, int shift, int ctrl);
+                       Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift);
 
 void keyin_handle_up(Keys_Handler *khdl, Evas_Event_Key_Up *ev);
 
+typedef struct _Key_Binding Key_Binding;
+
+typedef Eina_Bool (*Key_Binding_Cb)(Evas_Object *term);
+struct _Key_Binding
+{
+   uint16_t ctrl  : 1;
+   uint16_t alt   : 1;
+   uint16_t shift : 1;
+
+   uint16_t len;
+
+   Key_Binding_Cb cb;
+   char keyname[];
+};
+
+Key_Binding *
+key_binding_new(const char *keyname,
+                Eina_Bool ctrl, Eina_Bool alt, Eina_Bool shift,
+                Key_Binding_Cb cb);
+int key_bindings_init(void);
+void key_bindings_shutdown(void);
+
 
 #endif
diff --git a/src/bin/main.c b/src/bin/main.c
index 708c320..3e250d2 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -19,6 +19,7 @@
 #include "dbus.h"
 #include "app_server.h"
 #include "miniview.h"
+#include "keyin.h"
 
 #if (ELM_VERSION_MAJOR == 1) && (ELM_VERSION_MINOR < 8)
   #define PANES_TOP "left"
@@ -2977,6 +2978,12 @@ elm_main(int argc, char **argv)
    elm_app_info_set(elm_main, "terminology", "themes/default.edj");
 
    config_init();
+   if (key_bindings_init() < 0)
+     {
+        ERR(_("Could not Initialize key bindings."));
+        retval = EXIT_FAILURE;
+        goto end;
+     }
 
    main_config = config_load("config");
 
@@ -3373,6 +3380,7 @@ remote:
 
 
    config_del(main_config);
+   key_bindings_shutdown();
    config_shutdown();
    eina_log_domain_unregister(_log_domain);
    _log_domain = -1;
diff --git a/src/bin/termio.c b/src/bin/termio.c
index 42f7e4e..f83ca7a 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -1850,9 +1850,9 @@ _smart_cb_key_down(void *data, Evas *e EINA_UNUSED,
 {
    const Evas_Event_Key_Down *ev = event;
    Termio *sd = evas_object_smart_data_get(data);
+   int ctrl = evas_key_modifier_is_set(ev->modifiers, "Control");
    int alt = evas_key_modifier_is_set(ev->modifiers, "Alt");
    int shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
-   int ctrl = evas_key_modifier_is_set(ev->modifiers, "Control");
 
    EINA_SAFETY_ON_NULL_RETURN(sd);
    EINA_SAFETY_ON_NULL_RETURN(ev->key);
@@ -1861,7 +1861,7 @@ _smart_cb_key_down(void *data, Evas *e EINA_UNUSED,
      return;
 
 
-   if (keyin_handle(&sd->khdl, sd->pty, ev, alt, shift, ctrl))
+   if (keyin_handle(&sd->khdl, sd->pty, ev, ctrl, alt, shift))
      goto end;
 
    if (sd->jump_on_keypress)

-- 


Reply via email to