ref: 1b81533742fa32d4ba26f7fcacb942becfd89c50
dir: /bindings.c/
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include "dat.h"
#include "fns.h"
Binding * BindingRoot = nil;
typedef struct DefaultBinding
{
int type;
int code;
char * command;
void (*func)(void);
} DefaultBinding;
DefaultBinding DefaultBindings[] =
{
{BKeyboard, 'q', nil, quitloop},
{BMouse, 1, nil, stroke}
};
void
freebinding(Binding * b)
{
if (b == nil)
return;
if (b->command != nil)
free(b->command);
free(b);
}
int
removebindings(int type, int code)
{
int rc;
Binding * e, * n;
rc = 0;
for (e = BindingRoot; e != nil; e = n) {
if (e->type != type || e->code != code) {
n = e->next;
continue;
}
if (e->prev != nil)
e->prev->next = e->next;
if (e->next != nil)
e->next->prev = e->prev;
n = e->next;
freebinding(e);
if (e == BindingRoot)
BindingRoot = nil;
rc++;
}
return rc;
}
Binding *
addbinding(int type, int code)
{
Binding * b, * e;
if ((b = calloc(sizeof(Binding), 1)) == nil) {
werrstr("failed to allocate Binding");
return nil;
}
b->next = b->prev = nil;
b->type = type;
b->code = code;
if (BindingRoot != nil) {
for (e = BindingRoot; e->next != nil; e = e->next)
;
e->next = b;
b->prev = e;
} else
BindingRoot = b;
return b;
}
int
runbindings(int type, int code)
{
int rc;
Binding * b;
// print("handling bindings for %d %d\n", type,code);
rc = 0;
for (b = BindingRoot; b != nil; b = b->next) {
if (b->type != type || b->code != code)
continue;
if (b->func != nil)
b->func();
if (b->command != nil)
NOOP(); // TODO: Add shell command support
rc++;
}
return rc;
}
Binding *
adduniquebinding(int type, int code)
{
removebindings(type, code);
return addbinding(type, code);
}
void
setdefaultbindings()
{
int i;
Binding * b;
DefaultBinding * db;
for (i = 0; i < ARRLEN(DefaultBindings); i++) {
db = &DefaultBindings[i];
if ((b = addbinding(db->type, db->code)) == nil)
sysfatal("addbinding: %r");
if (db->command != nil)
b->command = strdup(db->command);
if (db->func != nil)
b->func = db->func;
}
}