#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "keybinder.h"
static
HV * cb_mapping = (HV*)NULL;
void
_initialize() {
keybinder_init();
cb_mapping = newHV();
}
void
callback_bridge(
const
char
*keystring,
void
*user_data){
dSP;
SV** cb = hv_fetch(cb_mapping, keystring,
strlen
(keystring), 0);
if
(cb == (SV**)NULL)
croak(
"Internal error: no callback can't be found\n"
);
PUSHMARK(SP);
call_sv(*cb, G_NOARGS|G_DISCARD|G_VOID);
}
gboolean bind_key(
const
char
*keystring, SV* cb){
SvGETMAGIC(cb);
if
(!SvROK(cb)
|| (SvTYPE(SvRV(cb)) != SVt_PVCV))
{
croak(
"Second argument for bind_key should be a closure...\n"
);
}
if
(!cb_mapping) _initialize();
SV* cb_copy = newSVsv(cb);
gboolean success = keybinder_bind(keystring, callback_bridge, (
void
*) cb_copy);
if
( success ) {
hv_store(cb_mapping, keystring,
strlen
(keystring), cb_copy, 0);
}
else
{
SvREFCNT_dec(cb_copy);
}
return
success;
}
void
unbind_key(
const
char
*keystring){
if
(!cb_mapping) _initialize();
SV** cb_copy = (SV**)hv_delete(cb_mapping, keystring,
strlen
(keystring), 0);
if
( cb_copy ) {
keybinder_unbind(keystring, callback_bridge);
}
}
MODULE = Keybinder PACKAGE = Keybinder
gboolean
bind_key(keystring, cb)
const
char
*keystring
SV* cb
PROTOTYPE: $$
void
unbind_key(keystring)
const
char
*keystring
PROTOTYPE: $