shithub: pain

ref: 1b81533742fa32d4ba26f7fcacb942becfd89c50
dir: /bindings.c/

View raw version
#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;
	}
}