1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-10-01 03:36:26 -04:00

Introduce get_action_from_keystroke and get_action_name_from_keystroke.

Introduce smjs_init_keybinding_interface, which creates elinks.keymaps.<map>
for <map> in "main", "edit", and "menu". elinks.keymaps.<map> is a hash
indexed by string representations of keystrokes, and can be used to get the
current action for a key and to set the action either to an internal ELinks
action or to an ECMAScript function.
This commit is contained in:
Miciah Dashiel Butler Masters 2005-12-24 06:54:01 +00:00 committed by Miciah Dashiel Butler Masters
parent 5714a8b54e
commit 80a5467b8d
6 changed files with 250 additions and 1 deletions

View File

@ -227,6 +227,26 @@ static struct keymap keymap_table[] = {
* Config file helpers.
*/
static struct action *
get_action_from_keystroke(enum keymap_id keymap_id,
unsigned char *keystroke_str)
{
struct keybinding *keybinding = kbd_stroke_lookup(keymap_id,
keystroke_str);
return keybinding ? get_action(keymap_id, keybinding->action_id) : NULL;
}
unsigned char *
get_action_name_from_keystroke(enum keymap_id keymap_id,
unsigned char *keystroke_str)
{
struct action *action = get_action_from_keystroke(keymap_id,
keystroke_str);
return action ? action->str : NULL;
}
action_id_T
get_action_from_string(enum keymap_id keymap_id, unsigned char *str)
{

View File

@ -123,6 +123,8 @@ void free_keybinding(struct keybinding *);
struct action *get_action(enum keymap_id keymap_id, action_id_T action_id);
unsigned char *get_action_name(enum keymap_id keymap_id, action_id_T action_id);
action_id_T get_action_from_string(enum keymap_id keymap_id, unsigned char *str);
unsigned char *get_action_name_from_keystroke(enum keymap_id keymap_id,
unsigned char *keystroke_str);
static inline unsigned int
action_is_anonymous_safe(enum keymap_id keymap_id, action_id_T action_id)

View File

@ -3,6 +3,7 @@ include $(top_builddir)/Makefile.config
INCLUDES += $(SPIDERMONKEY_CFLAGS)
OBJS = smjs.o core.o global_object.o hooks.o elinks_object.o cache_object.o
OBJS = smjs.o core.o global_object.o hooks.o elinks_object.o cache_object.o \
keybinding.o
include $(top_srcdir)/Makefile.lib

View File

@ -11,6 +11,7 @@
#include "scripting/smjs/core.h"
#include "scripting/smjs/elinks_object.h"
#include "scripting/smjs/global_object.h"
#include "scripting/smjs/keybinding.h"
static JSBool
@ -60,6 +61,8 @@ void
smjs_init_elinks_object(void)
{
smjs_elinks_object = smjs_get_elinks_object();
smjs_init_keybinding_interface();
}
/* If elinks.<method> is defined, call it with the given arguments,

View File

@ -0,0 +1,215 @@
/* "elinks.keymaps" */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "elinks.h"
#include "config/kbdbind.h"
#include "ecmascript/spidermonkey/util.h"
#include "main/event.h"
#include "scripting/smjs/core.h"
#include "scripting/smjs/elinks_object.h"
static JSBool
keymap_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
{
unsigned char *action_str;
unsigned char *keystroke_str;
int *data = JS_GetPrivate(ctx, obj);
enum keymap_id keymap_id = *data;
keystroke_str = JS_GetStringBytes(JS_ValueToString(ctx, id));
if (!keystroke_str) goto ret_null;
action_str = get_action_name_from_keystroke(keymap_id, keystroke_str);
if (!action_str) goto ret_null;
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(ctx, action_str));
return JS_TRUE;
ret_null:
*vp = JSVAL_NULL;
return JS_TRUE;
}
static enum evhook_status
smjs_keybinding_action_callback(va_list ap, void *data)
{
jsval rval;
struct session *ses = va_arg(ap, struct session *);
JSObject *jsobj = data;
JSFunction *func = JS_ValueToFunction(smjs_ctx, OBJECT_TO_JSVAL(jsobj));
evhook_use_params(ses);
assert(func);
JS_CallFunction(smjs_ctx, NULL, func, 0, NULL, &rval);
return EVENT_HOOK_STATUS_LAST;
}
static JSBool
keymap_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
{
int *data = JS_GetPrivate(ctx, obj);
enum keymap_id keymap_id = *data;
unsigned char *keymap_str;
unsigned char *keystroke_str;
/* Ugly fact: we need to get the string from the id to give to bind_do,
* which will of course then convert the string back to an id... */
keymap_str = get_keymap_name(keymap_id);
if (!keymap_str) return JS_FALSE;
keystroke_str = JS_GetStringBytes(JS_ValueToString(ctx, id));
if (!keystroke_str) return JS_FALSE;
if (JSVAL_IS_STRING(*vp)) {
unsigned char *action_str;
action_str = JS_GetStringBytes(JS_ValueToString(ctx, *vp));
if (!action_str) return JS_FALSE;
if (bind_do(keymap_str, keystroke_str, action_str, 0))
return JS_FALSE;
return JS_TRUE;
} else if (JSVAL_IS_OBJECT(*vp)) {
unsigned char *err = NULL;
int event_id;
struct string event_name = NULL_STRING;
JSObject *jsobj = JSVAL_TO_OBJECT(*vp);
if (JS_FALSE == JS_ObjectIsFunction(ctx, jsobj))
return JS_FALSE;
if (!init_string(&event_name)) return JS_FALSE;
add_format_to_string(&event_name, "smjs-run-func %p", jsobj);
event_id = bind_key_to_event_name(keymap_str,
keystroke_str,
event_name.source, &err);
done_string(&event_name);
if (err) {
alert_smjs_error(err);
return JS_FALSE;
}
event_id = register_event_hook(event_id,
smjs_keybinding_action_callback,
0, (void *) jsobj);
if (event_id == EVENT_NONE) {
alert_smjs_error("error registering event hook"
" for keybinding");
return JS_FALSE;
}
return JS_TRUE;
}
return JS_TRUE;
}
static void
keymap_finalize(JSContext *ctx, JSObject *obj)
{
void *data = JS_GetPrivate(ctx, obj);
mem_free(data);
}
static const JSClass keymap_class = {
"keymap",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub,
keymap_get_property, keymap_set_property,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, keymap_finalize,
};
static JSObject *
smjs_get_keymap_object(enum keymap_id keymap_id)
{
int *data;
JSObject *keymap_object;
assert(smjs_ctx);
keymap_object = JS_NewObject(smjs_ctx, (JSClass *) &keymap_class,
NULL, NULL);
if (!keymap_object) return NULL;
data = mem_alloc(sizeof(*data));
if (!data) return NULL;
*data = keymap_id;
if (JS_FALSE != JS_SetPrivate(smjs_ctx, keymap_object, data))
return keymap_object;
return NULL;
}
static const JSClass keymaps_hash_class = {
"keymaps_hash",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub,
NULL, NULL,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
};
static JSObject *
smjs_get_keymap_hash_object(void)
{
jsval val;
enum keymap_id keymap_id;
JSObject *keymaps_hash;
keymaps_hash = JS_NewObject(smjs_ctx, (JSClass *) &keymaps_hash_class,
NULL, NULL);
if (!keymaps_hash) return NULL;
for (keymap_id = 0; keymap_id < KEYMAP_MAX; ++keymap_id) {
unsigned char *keymap_str = get_keymap_name(keymap_id);
JSObject *map = smjs_get_keymap_object(keymap_id);
assert(keymap_str);
if (!map) return NULL;
val = OBJECT_TO_JSVAL(map);
JS_SetProperty(smjs_ctx, keymaps_hash, keymap_str, &val);
}
return keymaps_hash;
}
void
smjs_init_keybinding_interface(void)
{
jsval val;
struct JSObject *keymaps_hash;
if (!smjs_ctx || !smjs_elinks_object)
return;
keymaps_hash = smjs_get_keymap_hash_object();
if (!keymaps_hash) return;
val = OBJECT_TO_JSVAL(keymaps_hash);
JS_SetProperty(smjs_ctx, smjs_elinks_object, "keymaps", &val);
}

View File

@ -0,0 +1,8 @@
#ifndef EL__SCRIPTING_SMJS_KEYBINDING_H
#define EL__SCRIPTING_SMJS_KEYBINDING_H
#include "ecmascript/spidermonkey/util.h"
void smjs_init_keybinding_interface(void);
#endif