tts/bindings.c
2014-03-08 00:30:40 +00:00

194 lines
4.7 KiB
C

/*
* 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 <stdlib.h>
#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"<BREAK>" },
{ KEY_DOWN, L"<DOWN>" },
{ KEY_UP, L"<UP>" },
{ KEY_LEFT, L"<LEFT>" },
{ KEY_RIGHT, L"<RIGHT>" },
{ KEY_HOME, L"<HOME>" },
{ KEY_BACKSPACE, L"<BACKSPACE>" },
{ 0x7F, L"<BACKSPACE>" }, /* DEL */
{ KEY_F(0), L"<F0>" },
{ KEY_F(1), L"<F1>" },
{ KEY_F(2), L"<F2>" },
{ KEY_F(3), L"<F3>" },
{ KEY_F(4), L"<F4>" },
{ KEY_F(5), L"<F5>" },
{ KEY_F(6), L"<F6>" },
{ KEY_F(7), L"<F7>" },
{ KEY_F(8), L"<F8>" },
{ KEY_F(9), L"<F9>" },
{ KEY_F(10), L"<F10>" },
{ KEY_F(11), L"<F1l>" },
{ KEY_F(12), L"<F12>" },
{ KEY_F(13), L"<F13>" },
{ KEY_F(14), L"<F14>" },
{ KEY_F(15), L"<F15>" },
{ KEY_F(16), L"<F16>" },
{ KEY_F(17), L"<F17>" },
{ KEY_F(18), L"<F18>" },
{ KEY_F(19), L"<F19>" },
{ KEY_F(20), L"<F20>" },
{ KEY_F(21), L"<F21>" },
{ KEY_F(22), L"<F22>" },
{ KEY_F(23), L"<F23>" },
{ KEY_F(24), L"<F24>" },
{ KEY_NPAGE, L"<NEXT>" },
{ KEY_PPAGE, L"<PREV>" },
{ '\001', L"<CTRL-A>" },
{ '\002', L"<CTRL-B>" },
{ '\003', L"<CTRL-C>" },
{ '\004', L"<CTRL-D>" },
{ '\005', L"<CTRL-E>" },
{ '\006', L"<CTRL-F>" },
{ '\007', L"<CTRL-G>" },
{ '\010', L"<CTRL-H>" },
{ '\011', L"<CTRL-I>" },
{ '\011', L"<TAB>" },
{ '\012', L"<CTRL-J>" },
{ '\013', L"<CTRL-K>" },
{ '\014', L"<CTRL-L>" },
{ '\015', L"<CTRL-N>" },
{ '\016', L"<CTRL-O>" },
{ '\017', L"<CTRL-P>" },
{ '\020', L"<CTRL-Q>" },
{ '\021', L"<CTRL-R>" },
{ '\022', L"<CTRL-S>" },
{ '\023', L"<CTRL-T>" },
{ '\024', L"<CTRL-U>" },
{ '\025', L"<CTRL-V>" },
{ '\026', L"<CTRL-W>" },
{ '\027', L"<CTRL-X>" },
{ '\030', L"<CTRL-Y>" },
{ '\031', L"<CTRL-Z>" },
{ ' ', L"<SPACE>" },
{ KEY_ENTER, L"<ENTER>" },
{ KEY_BACKSPACE, L"<BACKSPACE>" },
{ KEY_DC, L"<DELETE>" }
};
/*
* 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"<CTRL-C>", 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"<SPACE>", L"startstop", 0);
bind_key(L"e", L"edit-desc", 0);
bind_key(L"\\", L"edit-time", 0);
bind_key(L"<TAB>", 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"<UP>", L"prev", 0);
bind_key(L"<DOWN>", 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);
}