1 /*
2  *			GPAC - Multimedia Framework C SDK
3  *
4  *				Authors: Jean Le Feuvre
5  *			Copyright (c) Telecom ParisTech 2019
6  *					All rights reserved
7  *
8  *  This file is part of GPAC / Scene Management sub-project
9  *
10  *  GPAC is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU Lesser General Public License as published by
12  *  the Free Software Foundation; either version 2, or (at your option)
13  *  any later version.
14  *
15  *  GPAC is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; see the file COPYING.  If not, write to
22  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 
26 #ifndef SG_QJS_COMMONE
27 #define SG_QJS_COMMONE
28 
29 #include <gpac/list.h>
30 #include <gpac/scenegraph.h>
31 
32 #include "../quickjs/quickjs.h"
33 
34 /********************************************
35 
36 	Common JS tools
37 
38 *********************************************/
39 
40 #ifndef countof
41 #define countof(x) (sizeof(x) / sizeof((x)[0]))
42 #endif
43 
44 #define JS_CHECK_STRING(_v) (JS_IsString(_v) || JS_IsNull(_v))
45 
46 struct JSContext *gf_js_create_context();
47 void gf_js_delete_context(struct JSContext *);
48 #ifdef GPAC_HAS_QJS
49 void gf_js_lock(struct JSContext *c, Bool LockIt);
50 Bool gf_js_try_lock(struct JSContext *c);
51 void gf_js_call_gc(struct JSContext *c);
52 #endif /* GPAC_HAS_QJS */
53 
54 /* throws an error with integer property 'code' set to err*/
55 JSValue js_throw_err(JSContext *ctx, s32 err);
56 /* throws an error with integer property 'code' set to err and string property 'message' set to the formatted string*/
57 JSValue js_throw_err_msg(JSContext *ctx, s32 err, const char *fmt, ...);
58 
59 void js_do_loop(JSContext *ctx);
60 void js_dump_error(JSContext *ctx);
61 JSValue js_print(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
62 
63 /********************************************
64 
65 	SceneGraph JS tools
66 
67 Note that the generic DOM API is also potentially used by XHR in JSFilter, not only by scenegraph
68 
69 *********************************************/
70 
71 #ifndef GPAC_DISABLE_SVG
72 
73 typedef struct __tag_html_media_script_ctx
74 {
75 	/*global script context for the scene*/
76 	struct JSContext *js_ctx;
77 	/*global object*/
78 	struct JSObject *global;
79 	/*global event object - used to update the associated DOMEvent (JS private stack) when dispatching events*/
80 	struct JSObject *event;
81 
82 	Bool force_gc;
83 } GF_HTMLMediaJS;
84 
85 #endif	/*GPAC_DISABLE_SVG*/
86 
87 typedef struct
88 {
89 	JSClassDef class;
90 	JSClassID class_id;
91 } GF_JSClass;
92 
93 
94 struct js_handler_context
95 {
96 	/* JavaScript context in which the listener is applicable */
97 	void *ctx;
98 	/*function value for handler */
99 	JSValue fun_val;
100 	/*target EventListener object (this) */
101 	JSValue evt_listen_obj;
102 };
103 
104 struct _node_js_binding
105 {
106 	JSValue obj;
107 	struct __gf_js_field *pf;
108 	GF_List *fields;
109 };
110 
111 
112 void dom_node_changed(GF_Node *n, Bool child_modif, GF_FieldInfo *info);
113 void dom_element_finalize(JSRuntime *rt, JSValue obj);
114 void dom_document_finalize(JSRuntime *rt, JSValue obj);
115 GF_Node *dom_get_element(JSContext *c, JSValue obj);
116 GF_SceneGraph *dom_get_doc(JSContext *c, JSValue obj);
117 
118 #ifndef GPAC_DISABLE_SVG
119 JSValue dom_element_construct(JSContext *c, GF_Node *n);
120 #endif
121 
122 /*initialize DOM Core (subset) + xmlHTTPRequest API. The global object MUST have private data storage
123 and its private data MUST be a scenegraph. This scenegraph is only used to create new documents
124 and setup the callback pointers*/
125 void dom_js_load(GF_SceneGraph *scene, struct JSContext *c);
126 /*unloads the DOM core support (to be called upon destruction only, once the JSContext has been destroyed
127 to releases all resources used by DOM JS)*/
128 void dom_js_unload();
129 /*unloads DOM core before the JSContext is being destroyed */
130 void gf_sg_js_dom_pre_destroy(struct JSRuntime *rt, GF_SceneGraph *sg, GF_Node *script_or_handler_node);
131 
132 JSValue dom_event_add_listener(JSContext *c, JSValueConst obj, int argc, JSValueConst *argv);
133 JSValue dom_event_remove_listener(JSContext *c, JSValueConst obj, int argc, JSValueConst *argv);
134 JSValue xml_dom3_not_implemented(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
135 
136 /*dom event listener interface, exported for XHR module*/
137 #define JS_DOM3_EVENT_TARGET_INTERFACE	\
138 	JS_CFUNC_DEF("addEventListenerNS", 3, dom_event_add_listener),	\
139 	JS_CFUNC_DEF("removeEventListenerNS", 3, dom_event_remove_listener),	\
140 	JS_CFUNC_DEF("addEventListener", 2, dom_event_add_listener),		\
141 	JS_CFUNC_DEF("removeEventListener", 2, dom_event_remove_listener),	\
142 	JS_CFUNC_DEF("dispatchEvent", 1, xml_dom3_not_implemented),
143 
144 /*defines a new global object "evt" of type Event*/
145 JSValue dom_js_define_event(struct JSContext *c);
146 
147 JSValue gf_dom_new_event(struct JSContext *c);
148 
149 JSValue dom_document_construct_external(JSContext *c, GF_SceneGraph *sg);
150 
151 /*
152 		Script node
153 */
154 struct _gf_vrml_script_priv
155 {
156 	//extra script fields
157 	GF_List *fields;
158 
159 	//BIFS coding stuff
160 	u32 numIn, numDef, numOut;
161 
162 	void (*JS_PreDestroy)(GF_Node *node);
163 	void (*JS_EventIn)(GF_Node *node, GF_FieldInfo *in_field);
164 
165 	Bool is_loaded;
166 
167 #ifdef GPAC_HAS_QJS
168 	struct JSContext *js_ctx;
169 	JSValue js_obj;
170 	/*all attached JS fields with associated JS objects (eg, not created by the script) are stored here so that we don't
171 	allocate them again and again when getting properties. Garbage collection is performed (if needed)
172 	on these objects after each eventIn execution*/
173 	GF_List *jsf_cache;
174 	//Event object, whose private is the pointer to current event being executed
175 	JSValue the_event;
176 	Bool use_strict;
177 
178 	/*VRML constructors*/
179 	JSValue SFNodeClass;
180 #ifndef GPAC_DISABLE_VRML
181 	JSValue globalClass;
182 	JSValue browserClass;
183 	JSValue SFVec2fClass;
184 	JSValue SFVec3fClass;
185 	JSValue SFRotationClass;
186 	JSValue SFColorClass;
187 	JSValue SFImageClass;
188 	JSValue MFInt32Class;
189 	JSValue MFBoolClass;
190 	JSValue MFFloatClass;
191 	JSValue MFTimeClass;
192 	JSValue MFVec2fClass;
193 	JSValue MFVec3fClass;
194 	JSValue MFRotationClass;
195 	JSValue MFColorClass;
196 	JSValue MFStringClass;
197 	JSValue MFUrlClass;
198 	JSValue MFNodeClass;
199 	JSValue AnyClass;
200 
201 	JSValue node_toString_fun;
202 	JSValue node_getTime_fun;
203 #endif //GPAC_DISABLE_VRML
204 
205 #ifndef GPAC_DISABLE_SVG
206 	JSValue node_addEventListener_fun;
207 	JSValue node_removeEventListener_fun;
208 #endif //GPAC_DISABLE_SVG
209 
210 #endif //GPAC_HAS_QJS
211 };
212 
213 /********************************************
214 
215 	JSFilter tools
216 
217 *********************************************/
218 
219 /*provided by JSFilter only*/
220 struct __gf_download_manager *jsf_get_download_manager(JSContext *c);
221 struct _gf_ft_mgr *jsf_get_font_manager(JSContext *c);
222 GF_Err jsf_request_opengl(JSContext *c);
223 GF_Err jsf_set_gl_active(JSContext *c);
224 GF_Err jsf_get_filter_packet_planes(JSContext *c, JSValue obj, u32 *width, u32 *height, u32 *pf, u32 *stride, u32 *stride_uv, const u8 **data, const u8 **p_u, const u8 **p_v, const u8 **p_a);
225 
226 Bool jsf_is_packet(JSContext *c, JSValue obj);
227 const char *jsf_get_script_filename(JSContext *c);
228 
229 
230 /*definitions of C modules in gpac, potentially used by both SceneGraph and JSFilter*/
231 void qjs_module_init_scenejs(JSContext *ctx);
232 void qjs_module_init_storage(JSContext *ctx);
233 void qjs_module_init_xhr_global(JSContext *c, JSValue global);
234 void qjs_module_init_xhr(JSContext *c);
235 void qjs_module_init_evg(JSContext *c);
236 void qjs_module_init_webgl(JSContext *c);
237 
238 
239 #ifdef __cplusplus
240 }
241 #endif
242 
243 #endif //SG_QJS_COMMONE
244