/* * TTS - track your time. * Copyright (c) 2012-2014 Felicity Tarnell. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely. This software is provided 'as-is', without any express or implied * warranty. */ #include #include "bindings.h" #include "wide.h" #include "ui.h" binding_list_t bindings = TTS_TAILQ_HEAD_INITIALIZER(bindings); static tkey_t keys[] = { { KEY_BREAK, L"" }, { KEY_DOWN, L"" }, { KEY_UP, L"" }, { KEY_LEFT, L"" }, { KEY_RIGHT, L"" }, { KEY_HOME, L"" }, { KEY_BACKSPACE, L"" }, { 0x7F, L"" }, /* DEL */ { KEY_F(0), L"" }, { KEY_F(1), L"" }, { KEY_F(2), L"" }, { KEY_F(3), L"" }, { KEY_F(4), L"" }, { KEY_F(5), L"" }, { KEY_F(6), L"" }, { KEY_F(7), L"" }, { KEY_F(8), L"" }, { KEY_F(9), L"" }, { KEY_F(10), L"" }, { KEY_F(11), L"" }, { KEY_F(12), L"" }, { KEY_F(13), L"" }, { KEY_F(14), L"" }, { KEY_F(15), L"" }, { KEY_F(16), L"" }, { KEY_F(17), L"" }, { KEY_F(18), L"" }, { KEY_F(19), L"" }, { KEY_F(20), L"" }, { KEY_F(21), L"" }, { KEY_F(22), L"" }, { KEY_F(23), L"" }, { KEY_F(24), L"" }, { KEY_NPAGE, L"" }, { KEY_PPAGE, L"" }, { '\001', L"" }, { '\002', L"" }, { '\003', L"" }, { '\004', L"" }, { '\005', L"" }, { '\006', L"" }, { '\007', L"" }, { '\010', L"" }, { '\011', L"" }, { '\011', L"" }, { '\012', L"" }, { '\013', L"" }, { '\014', L"" }, { '\015', L"" }, { '\016', L"" }, { '\017', L"" }, { '\020', L"" }, { '\021', L"" }, { '\022', L"" }, { '\023', L"" }, { '\024', L"" }, { '\025', L"" }, { '\026', L"" }, { '\027', L"" }, { '\030', L"" }, { '\031', L"" }, { ' ', L"" }, { KEY_ENTER, L"" }, { KEY_BACKSPACE, L"" }, { KEY_DC, L"" } }; /* * Bind .keyname to run the function .funcname. If a binding for .keyname * already exists, overwrite it. * * If .keyname is a single character, e.g. 'a', it is used as a key name * directly, rather than being looked up in the key table. */ void bind_key(keyname, funcname, is_macro) const wchar_t *keyname, *funcname; { tkey_t *key = NULL; function_t *func; binding_t *binding; wint_t code; /* Find the key and the function */ if (wcslen(keyname) > 1) { if ((key = find_key(keyname)) == NULL) { errbox(L"Unknown key \"%ls\"", keyname); return; } code = key->ky_code; } else code = *keyname; if (!is_macro) { if ((func = find_func(funcname)) == NULL) { errbox(L"Unknown function \"%ls\"", funcname); return; } } /* Do we already have a binding for this key? */ TTS_TAILQ_FOREACH(binding, &bindings, bi_entries) { if (binding->bi_code == code) { if (is_macro) { binding->bi_func = NULL; binding->bi_macro = wcsdup(funcname); } else { free(binding->bi_macro); binding->bi_func = func; } return; } } /* No, add a new one */ if ((binding = calloc(1, sizeof(*binding))) == NULL) return; binding->bi_key = key; binding->bi_code = code; if (is_macro) binding->bi_macro = wcsdup(funcname); else binding->bi_func = func; TTS_TAILQ_INSERT_TAIL(&bindings, binding, bi_entries); } /* * Return the tkey_t for the key called .name, or NULL if such a key doesn't * exist. */ tkey_t * find_key(name) const wchar_t *name; { size_t i; for (i = 0; i < sizeof(keys) / sizeof(*keys); i++) if (wcscmp(name, keys[i].ky_name) == 0) return &keys[i]; return NULL; } void bind_defaults(void) { bind_key(L"?", L"help", 0); bind_key(L"a", L"add", 0); bind_key(L"A", L"add-old", 0); bind_key(L"d", L"delete", 0); bind_key(L"u", L"undelete", 0); bind_key(L"q", L"quit", 0); bind_key(L"", L"quit", 0); bind_key(L"i", L"invoice", 0); bind_key(L"b", L"billable", 0); bind_key(L"m", L"mark", 0); bind_key(L"U", L"unmarkall", 0); bind_key(L"", L"startstop", 0); bind_key(L"e", L"edit-desc", 0); bind_key(L"\\", L"edit-time", 0); bind_key(L"", L"showhide-inv", 0); bind_key(L"c", L"copy", 0); bind_key(L"+", L"add-time", 0); bind_key(L"-", L"sub-time", 0); bind_key(L"/", L"search", 0); bind_key(L"$", L"sync", 0); bind_key(L"", L"prev", 0); bind_key(L"", L"next", 0); bind_key(L":", L"execute", 0); bind_key(L"M", L"merge", 0); bind_key(L"r", L"interrupt", 0); bind_key(L"R", L"interrupt", 0); }