9 #include "config/kbdbind.h"
10 #include "ecmascript/spidermonkey/util.h"
11 #include "main/event.h"
12 #include "scripting/smjs/core.h"
13 #include "scripting/smjs/elinks_object.h"
14 #include "util/memory.h"
16 static const JSClass keymap_class
; /* defined below */
18 /* @keymap_class.getProperty */
20 keymap_get_property(JSContext
*ctx
, JSObject
*obj
, jsval id
, jsval
*vp
)
22 unsigned char *action_str
;
23 const unsigned char *keystroke_str
;
26 /* This can be called if @obj if not itself an instance of the
27 * appropriate class but has one in its prototype chain. Fail
29 if (!JS_InstanceOf(ctx
, obj
, (JSClass
*) &keymap_class
, NULL
))
32 data
= JS_GetInstancePrivate(ctx
, obj
,
33 (JSClass
*) &keymap_class
, NULL
);
35 keystroke_str
= JS_GetStringBytes(JS_ValueToString(ctx
, id
));
36 if (!keystroke_str
) goto ret_null
;
38 action_str
= get_action_name_from_keystroke((enum keymap_id
) *data
,
40 if (!action_str
) goto ret_null
;
42 *vp
= STRING_TO_JSVAL(JS_NewStringCopyZ(ctx
, action_str
));
52 static enum evhook_status
53 smjs_keybinding_action_callback(va_list ap
, void *data
)
56 struct session
*ses
= va_arg(ap
, struct session
*);
57 JSObject
*jsobj
= data
;
58 JSFunction
*func
= JS_ValueToFunction(smjs_ctx
, OBJECT_TO_JSVAL(jsobj
));
60 evhook_use_params(ses
);
66 JS_CallFunction(smjs_ctx
, NULL
, func
, 0, NULL
, &rval
);
70 return EVENT_HOOK_STATUS_LAST
;
73 /* @keymap_class.setProperty */
75 keymap_set_property(JSContext
*ctx
, JSObject
*obj
, jsval id
, jsval
*vp
)
78 unsigned char *keymap_str
;
79 const unsigned char *keystroke_str
;
81 /* This can be called if @obj if not itself an instance of the
82 * appropriate class but has one in its prototype chain. Fail
84 if (!JS_InstanceOf(ctx
, obj
, (JSClass
*) &keymap_class
, NULL
))
87 data
= JS_GetInstancePrivate(ctx
, obj
,
88 (JSClass
*) &keymap_class
, NULL
);
90 /* Ugly fact: we need to get the string from the id to give to bind_do,
91 * which will of course then convert the string back to an id... */
92 keymap_str
= get_keymap_name((enum keymap_id
) *data
);
93 if (!keymap_str
) return JS_FALSE
;
95 keystroke_str
= JS_GetStringBytes(JS_ValueToString(ctx
, id
));
96 if (!keystroke_str
) return JS_FALSE
;
98 if (JSVAL_IS_STRING(*vp
)) {
99 unsigned char *action_str
;
101 action_str
= JS_GetStringBytes(JS_ValueToString(ctx
, *vp
));
102 if (!action_str
) return JS_FALSE
;
104 if (bind_do(keymap_str
, keystroke_str
, action_str
, 0))
109 } else if (JSVAL_IS_OBJECT(*vp
)) {
110 unsigned char *err
= NULL
;
112 struct string event_name
= NULL_STRING
;
113 JSObject
*jsobj
= JSVAL_TO_OBJECT(*vp
);
115 if (JS_FALSE
== JS_ObjectIsFunction(ctx
, jsobj
))
118 if (!init_string(&event_name
)) return JS_FALSE
;
120 add_format_to_string(&event_name
, "smjs-run-func %p", jsobj
);
122 event_id
= bind_key_to_event_name(keymap_str
,
124 event_name
.source
, &err
);
126 done_string(&event_name
);
129 alert_smjs_error(err
);
134 event_id
= register_event_hook(event_id
,
135 smjs_keybinding_action_callback
,
138 if (event_id
== EVENT_NONE
) {
139 alert_smjs_error("error registering event hook"
151 /* @keymap_class.finalize */
153 keymap_finalize(JSContext
*ctx
, JSObject
*obj
)
157 assert(JS_InstanceOf(ctx
, obj
, (JSClass
*) &keymap_class
, NULL
));
158 if_assert_failed
return;
160 data
= JS_GetInstancePrivate(ctx
, obj
,
161 (JSClass
*) &keymap_class
, NULL
);
166 static const JSClass keymap_class
= {
168 JSCLASS_HAS_PRIVATE
, /* int * */
169 JS_PropertyStub
, JS_PropertyStub
,
170 keymap_get_property
, keymap_set_property
,
171 JS_EnumerateStub
, JS_ResolveStub
, JS_ConvertStub
, keymap_finalize
,
175 smjs_get_keymap_object(enum keymap_id keymap_id
)
178 JSObject
*keymap_object
;
182 keymap_object
= JS_NewObject(smjs_ctx
, (JSClass
*) &keymap_class
,
185 if (!keymap_object
) return NULL
;
187 data
= intdup(keymap_id
);
188 if (!data
) return NULL
;
190 if (JS_TRUE
== JS_SetPrivate(smjs_ctx
, keymap_object
, data
)) /* to @keymap_class */
191 return keymap_object
;
198 static const JSClass keymaps_hash_class
= {
201 JS_PropertyStub
, JS_PropertyStub
,
202 JS_PropertyStub
, JS_PropertyStub
,
203 JS_EnumerateStub
, JS_ResolveStub
, JS_ConvertStub
, JS_FinalizeStub
,
207 smjs_get_keymap_hash_object(void)
210 enum keymap_id keymap_id
;
211 JSObject
*keymaps_hash
;
213 keymaps_hash
= JS_NewObject(smjs_ctx
, (JSClass
*) &keymaps_hash_class
,
215 if (!keymaps_hash
) return NULL
;
217 for (keymap_id
= 0; keymap_id
< KEYMAP_MAX
; ++keymap_id
) {
218 unsigned char *keymap_str
= get_keymap_name(keymap_id
);
219 JSObject
*map
= smjs_get_keymap_object(keymap_id
);
223 if (!map
) return NULL
;
225 val
= OBJECT_TO_JSVAL(map
);
227 JS_SetProperty(smjs_ctx
, keymaps_hash
, keymap_str
, &val
);
234 smjs_init_keybinding_interface(void)
237 struct JSObject
*keymaps_hash
;
239 if (!smjs_ctx
|| !smjs_elinks_object
)
242 keymaps_hash
= smjs_get_keymap_hash_object();
243 if (!keymaps_hash
) return;
245 val
= OBJECT_TO_JSVAL(keymaps_hash
);
247 JS_SetProperty(smjs_ctx
, smjs_elinks_object
, "keymaps", &val
);