version 1.44, 2015/04/19 21:34:21 |
version 1.45, 2015/04/20 15:34:56 |
|
|
#include "tmux.h" |
#include "tmux.h" |
|
|
RB_GENERATE(key_bindings, key_binding, entry, key_bindings_cmp); |
RB_GENERATE(key_bindings, key_binding, entry, key_bindings_cmp); |
|
RB_GENERATE(key_tables, key_table, entry, key_table_cmp); |
|
struct key_tables key_tables = RB_INITIALIZER(&key_tables); |
|
|
struct key_bindings key_bindings; |
int |
|
key_table_cmp(struct key_table *e1, struct key_table *e2) |
|
{ |
|
return (strcmp(e1->name, e2->name)); |
|
} |
|
|
int |
int |
key_bindings_cmp(struct key_binding *bd1, struct key_binding *bd2) |
key_bindings_cmp(struct key_binding *bd1, struct key_binding *bd2) |
{ |
{ |
int key1, key2; |
return (bd1->key - bd2->key); |
|
} |
|
|
key1 = bd1->key & ~KEYC_PREFIX; |
struct key_table * |
key2 = bd2->key & ~KEYC_PREFIX; |
key_bindings_get_table(const char *name, int create) |
if (key1 != key2) |
{ |
return (key1 - key2); |
struct key_table table_find, *table; |
|
|
if (bd1->key & KEYC_PREFIX && !(bd2->key & KEYC_PREFIX)) |
table_find.name = name; |
return (-1); |
table = RB_FIND(key_tables, &key_tables, &table_find); |
if (bd2->key & KEYC_PREFIX && !(bd1->key & KEYC_PREFIX)) |
if (table != NULL || !create) |
return (1); |
return (table); |
return (0); |
|
|
table = xmalloc(sizeof *table); |
|
table->name = xstrdup(name); |
|
RB_INIT(&table->key_bindings); |
|
|
|
table->references = 1; /* one reference in key_tables */ |
|
RB_INSERT(key_tables, &key_tables, table); |
|
|
|
return (table); |
} |
} |
|
|
struct key_binding * |
void |
key_bindings_lookup(int key) |
key_bindings_unref_table(struct key_table *table) |
{ |
{ |
struct key_binding bd; |
struct key_binding *bd; |
|
|
bd.key = key; |
if (--table->references != 0) |
return (RB_FIND(key_bindings, &key_bindings, &bd)); |
return; |
|
|
|
while (!RB_EMPTY(&table->key_bindings)) { |
|
bd = RB_ROOT(&table->key_bindings); |
|
RB_REMOVE(key_bindings, &table->key_bindings, bd); |
|
cmd_list_free(bd->cmdlist); |
|
free(bd); |
|
} |
|
|
|
free((void *)table->name); |
|
free(table); |
} |
} |
|
|
void |
void |
key_bindings_add(int key, int can_repeat, struct cmd_list *cmdlist) |
key_bindings_add(const char *name, int key, int can_repeat, |
|
struct cmd_list *cmdlist) |
{ |
{ |
struct key_binding *bd; |
struct key_table *table; |
|
struct key_binding bd_find, *bd; |
|
|
key_bindings_remove(key); |
table = key_bindings_get_table(name, 1); |
|
|
|
bd_find.key = key; |
|
bd = RB_FIND(key_bindings, &table->key_bindings, &bd_find); |
|
if (bd != NULL) { |
|
RB_REMOVE(key_bindings, &table->key_bindings, bd); |
|
cmd_list_free(bd->cmdlist); |
|
free(bd); |
|
} |
|
|
bd = xmalloc(sizeof *bd); |
bd = xmalloc(sizeof *bd); |
bd->key = key; |
bd->key = key; |
RB_INSERT(key_bindings, &key_bindings, bd); |
RB_INSERT(key_bindings, &table->key_bindings, bd); |
|
|
bd->can_repeat = can_repeat; |
bd->can_repeat = can_repeat; |
bd->cmdlist = cmdlist; |
bd->cmdlist = cmdlist; |
} |
} |
|
|
void |
void |
key_bindings_remove(int key) |
key_bindings_remove(const char *name, int key) |
{ |
{ |
struct key_binding *bd; |
struct key_table *table; |
|
struct key_binding bd_find, *bd; |
|
|
if ((bd = key_bindings_lookup(key)) == NULL) |
table = key_bindings_get_table(name, 0); |
|
if (table == NULL) |
return; |
return; |
RB_REMOVE(key_bindings, &key_bindings, bd); |
|
|
bd_find.key = key; |
|
bd = RB_FIND(key_bindings, &table->key_bindings, &bd_find); |
|
if (bd == NULL) |
|
return; |
|
|
|
RB_REMOVE(key_bindings, &table->key_bindings, bd); |
cmd_list_free(bd->cmdlist); |
cmd_list_free(bd->cmdlist); |
free(bd); |
free(bd); |
|
|
|
if (RB_EMPTY(&table->key_bindings)) { |
|
RB_REMOVE(key_tables, &key_tables, table); |
|
key_bindings_unref_table(table); |
|
} |
} |
} |
|
|
void |
void |
|
key_bindings_remove_table(const char *name) |
|
{ |
|
struct key_table *table; |
|
|
|
table = key_bindings_get_table(name, 0); |
|
if (table != NULL) { |
|
RB_REMOVE(key_tables, &key_tables, table); |
|
key_bindings_unref_table(table); |
|
} |
|
} |
|
|
|
void |
key_bindings_init(void) |
key_bindings_init(void) |
{ |
{ |
static const char* defaults[] = { |
static const char* defaults[] = { |
|
|
char* cause; |
char* cause; |
int error; |
int error; |
struct cmd_q *cmdq; |
struct cmd_q *cmdq; |
|
|
RB_INIT(&key_bindings); |
|
|
|
cmdq = cmdq_new(NULL); |
cmdq = cmdq_new(NULL); |
for (i = 0; i < nitems(defaults); i++) { |
for (i = 0; i < nitems(defaults); i++) { |