FreeWRL/FreeX3D  3.0.0
jsVRMLBrowser.c
1 /*
2 
3 
4 Javascript C language binding.
5 
6 */
7 
8 /****************************************************************************
9  This file is part of the FreeWRL/FreeX3D Distribution.
10 
11  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12 
13  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14  it under the terms of the GNU Lesser Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  GNU General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25 ****************************************************************************/
26 
27 
28 #include <config.h>
29 #include <system.h>
30 #if !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK))
31 #include <display.h>
32 #include <internal.h>
33 
34 #include <libFreeWRL.h>
35 #include <list.h>
36 
37 #include "../vrml_parser/Structs.h"
38 #include "../vrml_parser/CRoutes.h"
39 #include "../opengl/OpenGL_Utils.h"
40 #include "../main/headers.h"
41 #include "../main/ProdCon.h"
42 #include "../scenegraph/RenderFuncs.h"
43 #include "../vrml_parser/CParseGeneral.h"
44 #include "../scenegraph/Vector.h"
45 #include "../vrml_parser/CFieldDecls.h"
46 #include "../vrml_parser/CParseParser.h"
47 #include "../vrml_parser/CParseLexer.h"
48 #include "../vrml_parser/CParse.h"
49 #include "../main/Snapshot.h"
50 #include "../scenegraph/Collision.h"
51 #include "../scenegraph/quaternion.h"
52 #include "../scenegraph/Viewer.h"
53 #include "../x3d_parser/Bindable.h"
54 #include "../input/EAIHeaders.h" /* for implicit declarations */
55 #include "../ui/common.h"
56 
57 #include "JScript.h"
58 #include "CScripts.h"
59 #include "fieldSet.h"
60 #include "jsUtils.h"
61 #include "jsNative.h"
62 #include "jsVRMLClasses.h"
63 #include "jsVRMLBrowser.h"
64 
65 
66 
67 #define X3DBROWSER 1
68 
69 
70 
71 #ifndef X3DBROWSER
72 #if JS_VERSION < 185
73 #define SetPropertyStub JS_PropertyStub
74 #else
75 #define SetPropertyStub JS_StrictPropertyStub
76 #endif
77 #endif // ndef X3DBROWSER
78 
79 #ifdef X3DBROWSER
80 JSBool
81 #if JS_VERSION < 185
82 BrowserGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
83 #else
84 BrowserGetProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp);
85 #endif
86 JSBool
87 #if JS_VERSION < 185
88 BrowserSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
89 #else
90 BrowserSetProperty(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp);
91 #endif
92 
93 #endif
94 int jsrrunScript(JSContext *_context, JSObject *_globalObj, char *script, jsval *rval);
95 
96 
97 //Q. is this a true sharable static?
98 static JSClass Browser = {
99  "Browser",
100  JSCLASS_HAS_PRIVATE,
101  JS_PropertyStub,
102  JS_PropertyStub,
103 #ifdef X3DBROWSER
104  BrowserGetProperty,
105  BrowserSetProperty,
106 #else
107  JS_PropertyStub,
108  SetPropertyStub,
109 #endif
110 
111  JS_EnumerateStub,
112  JS_ResolveStub,
113  JS_ConvertStub,
114  JS_FinalizeStub
115 };
116 
117 static JSBool doVRMLRoute(JSContext *context, JSObject *obj, uintN argc, jsval *argv, const char *browserFunc);
118 
119 static JSFunctionSpec (BrowserFunctions)[] = {
120  {"getName", VrmlBrowserGetName, 0},
121  {"getVersion", VrmlBrowserGetVersion, 0},
122  {"getCurrentSpeed", VrmlBrowserGetCurrentSpeed, 0},
123  {"getCurrentFrameRate", VrmlBrowserGetCurrentFrameRate, 0},
124  {"getWorldURL", VrmlBrowserGetWorldURL, 0},
125  {"replaceWorld", VrmlBrowserReplaceWorld, 0},
126  {"loadURL", VrmlBrowserLoadURL, 0},
127  {"setDescription", VrmlBrowserSetDescription, 0},
128  {"createVrmlFromString", VrmlBrowserCreateVrmlFromString, 0},
129  {"createVrmlFromURL", VrmlBrowserCreateVrmlFromURL, 0},
130  {"createX3DFromString", VrmlBrowserCreateX3DFromString, 0},
131  {"createX3DFromURL", VrmlBrowserCreateVrmlFromURL, 0},
132  {"addRoute", VrmlBrowserAddRoute, 0},
133  {"deleteRoute", VrmlBrowserDeleteRoute, 0},
134  {"print", VrmlBrowserPrint, 0},
135  {"println", VrmlBrowserPrintln, 0},
136 #ifdef X3DBROWSER
137  //{"replaceWorld", X3dBrowserReplaceWorld, 0}, //conflicts - X3DScene vs MFNode parameter - could detect?
138  //{"createX3DFromString", X3dBrowserCreateX3DFromString, 0}, //conflicts but above verion shouldn't be above, or could detect?
139  //{"createX3DFromURL", X3dBrowserCreateVrmlFromURL, 0}, //conflicts but above version shouldn't be above, or could detect?
140  //{importDocument, X3dBrowserImportDocument, 0), //not sure we need/want this, what does it do?
141  //{getRenderingProperty, X3dGetRenderingProperty, 0},
142  //{addBrowserListener, X3dAddBrowserListener, 0},
143  //{removeBrowserListener, X3dRemoveBrowserListener, 0},
144 #endif
145  {0}
146 };
147 #ifdef X3DBROWSER
148 
149 /* ProfileInfo, ProfileInfoArray, ComponentInfo, ComponentInfoArray
150  I decided to do these as thin getter wrappers on the bits and pieces defined
151  in Structs.h, GeneratedCode.c and capabilitiesHandler.c
152  The Array types return the info type wrapper with private native member == index into
153  the native array.
154 */
155 //ComonentInfo{
156 //String name;
157 //Numeric level;
158 //String Title;
159 //String providerUrl;
160 //}
161 int capabilitiesHandler_getTableLength(int* table);
162 int capabilitiesHandler_getComponentLevel(int *table, int comp);
163 int capabilitiesHandler_getProfileLevel(int prof);
164 const int *capabilitiesHandler_getProfileComponent(int prof);
165 const int *capabilitiesHandler_getCapabilitiesTable();
166 typedef struct intTableIndex{
167  int* table;
168  int index;
169 } *IntTableIndex;
170 
171 JSBool
172 #if JS_VERSION < 185
173 ComponentInfoGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
174 #else
175 ComponentInfoGetProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp)
176 #endif
177 {
178  IntTableIndex ptr;
179  int _index, *_table, _nameIndex;
180  jsval rval;
181  jsval id;
182 
183  UNUSED(rval); // compiler warning mitigation
184 
185 #if JS_VERSION >= 185
186  if (!JS_IdToValue(cx,iid,&id)) {
187  printf("JS_IdToValue failed in ComponentInfoGetProperty.\n");
188  return JS_FALSE;
189  }
190 #endif
191  if ((ptr = (IntTableIndex)JS_GetPrivate(cx, obj)) == NULL) {
192  printf( "JS_GetPrivate failed in ExecutionContextGetProperty.\n");
193  return JS_FALSE;
194  }
195  _index = ptr->index;
196  _table = ptr->table;
197 //extern const char *COMPONENTS[];
198 //extern const int COMPONENTS_COUNT;
199 
200  if (JSVAL_IS_INT(id))
201  {
202  int index = JSVAL_TO_INT(id);
203  switch(index){
204  case 0://name
205  case 1://Title
206  _nameIndex = _table[2*_index];
207 #if JS_VERSION < 185
208  *rval = STRING_TO_JSVAL(COMPONENTS[_index]);
209 #else
210  JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,COMPONENTS[_nameIndex])));
211 #endif
212  break;
213  case 2://level
214  {
215  int level = capabilitiesHandler_getComponentLevel(_table,_index);
216 #if JS_VERSION < 185
217  *rval = INT_TO_JSVAL(lev);
218 #else
219  JS_SET_RVAL(cx,vp,INT_TO_JSVAL(level));
220 #endif
221  }
222  break;
223  case 3://providerUrl
224 #if JS_VERSION < 185
225  *rval = STRING_TO_JSVAL("freewrl.sourceforge.net");
226 #else
227  JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,"freewrl.sourceforge.net")));
228 #endif
229  break;
230  }
231  }
232  return JS_TRUE;
233 }
234 JSBool
235 #if JS_VERSION < 185
236 ComponentInfoSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
237 #else
238 ComponentInfoSetProperty(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp)
239 #endif
240 {
241  //can I, should I force it to read-only this way?
242  return JS_FALSE;
243 }
244 void
245 ComponentInfoFinalize(JSContext *cx, JSObject *obj)
246 {
247  IntTableIndex ptr;
248  if ((ptr = (IntTableIndex)JS_GetPrivate(cx, obj)) == NULL) {
249  return;
250  } else {
251  FREE_IF_NZ (ptr);
252  }
253 }
254 
255 
256 static JSClass ComponentInfoClass = {
257  "ComponentInfo",
258  JSCLASS_HAS_PRIVATE,
259  JS_PropertyStub,
260  JS_PropertyStub,
261  ComponentInfoGetProperty,
262  ComponentInfoSetProperty,
263  JS_EnumerateStub,
264  JS_ResolveStub,
265  JS_ConvertStub,
266  ComponentInfoFinalize //JS_FinalizeStub
267 };
268 
269 static JSPropertySpec (ComponentInfoProperties)[] = {
270  //executionContext
271  {"name", 0, JSPROP_ENUMERATE}, //"Core"
272  {"Title", 1, JSPROP_ENUMERATE}, //"Core"
273  {"level", 2, JSPROP_ENUMERATE}, //4
274  {"providerUrl", 3, JSPROP_ENUMERATE}, //"freewrl.sourceforge.net"
275  {0}
276 };
277 
278 
279 //ComponentInfoArray{
280 //numeric length;
281 //ComponentInfo [integer index];
282 //}
283 
284 JSBool
285 #if JS_VERSION < 185
286 ComponentInfoArrayGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
287 #else
288 ComponentInfoArrayGetProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp)
289 #endif
290 {
291  int *_table;
292  jsval rval;
293  jsval id;
294 
295  UNUSED(rval); // compiler warning mitigation
296 
297 #if JS_VERSION >= 185
298  if (!JS_IdToValue(cx,iid,&id)) {
299  printf("JS_IdToValue failed in ComponentInfoArrayGetProperty.\n");
300  return JS_FALSE;
301  }
302 #endif
303  if ((_table = (int *)JS_GetPrivate(cx, obj)) == NULL) {
304  printf( "JS_GetPrivate failed in ProfileInfoGetProperty.\n");
305  return JS_FALSE;
306  }
307 
308  if (JSVAL_IS_INT(id))
309  {
310  int index = JSVAL_TO_INT(id);
311  if(index == -1){
312 //extern const char *COMPONENTS[];
313 //extern const int COMPONENTS_COUNT;
314 
315  int _length = capabilitiesHandler_getTableLength(_table); //COMPONENTS_COUNT;
316 #if JS_VERSION < 185
317  *rval = INT_TO_JSVAL(_length);
318 #else
319  JS_SET_RVAL(cx,vp,INT_TO_JSVAL(_length));
320 #endif
321  }else if(index > -1 && index < COMPONENTS_COUNT )
322  {
323  JSObject *_obj;
324  IntTableIndex tableindex = MALLOC(void *, sizeof(struct intTableIndex));
325  //int* _index = MALLOC(void *, sizeof(int));
326  _obj = JS_NewObject(cx,&ComponentInfoClass,NULL,obj);
327  tableindex->index = index;
328  tableindex->table = _table;
329  if (!JS_DefineProperties(cx, _obj, ComponentInfoProperties)) {
330  printf( "JS_DefineProperties failed in ComponentInfoProperties.\n");
331  return JS_FALSE;
332  }
333 
334  if (!JS_SetPrivate(cx, _obj, (void*)tableindex)) {
335  printf( "JS_SetPrivate failed in ComponentInfoArray.\n");
336  return JS_FALSE;
337  }
338 
339 #if JS_VERSION < 185
340  *rval = OBJECT_TO_JSVAL(_obj);
341 #else
342  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
343 #endif
344 
345  }
346  }
347  return JS_TRUE;
348 }
349 JSBool
350 #if JS_VERSION < 185
351 ComponentInfoArraySetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
352 #else
353 ComponentInfoArraySetProperty(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp)
354 #endif
355 {
356  //can I, should I force it to read-only this way?
357  return JS_FALSE;
358 }
359 
360 
361 static JSClass ComponentInfoArrayClass = {
362  "ComponentInfoArray",
363  JSCLASS_HAS_PRIVATE,
364  JS_PropertyStub,
365  JS_PropertyStub,
366  ComponentInfoArrayGetProperty,
367  ComponentInfoArraySetProperty,
368  JS_EnumerateStub,
369  JS_ResolveStub,
370  JS_ConvertStub,
371  JS_FinalizeStub
372 };
373 
374 static JSPropertySpec (ComponentInfoArrayProperties)[] = {
375  {"length", -1, JSPROP_READONLY | JSPROP_SHARED | JSPROP_PERMANENT}, //JSPROP_ENUMERATE},
376  {0}
377 };
378 
379 //ProfileInfo{
380 //String name;
381 //Numeric level;
382 //String Title;
383 //String providerUrl;
384 //ComonentInfoArray components;
385 //}
386 
387 JSBool
388 #if JS_VERSION < 185
389 ProfileInfoGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
390 #else
391 ProfileInfoGetProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp)
392 #endif
393 {
394  int *ptr;
395  int _index;
396  jsval rval;
397  jsval id;
398 
399  UNUSED(rval); // compiler warning mitigation
400 
401 #if JS_VERSION >= 185
402  if (!JS_IdToValue(cx,iid,&id)) {
403  printf("JS_IdToValue failed in ProfileInfoGetProperty.\n");
404  return JS_FALSE;
405  }
406 #endif
407  if ((ptr = (int *)JS_GetPrivate(cx, obj)) == NULL) {
408  printf( "JS_GetPrivate failed in ProfileInfoGetProperty.\n");
409  return JS_FALSE;
410  }
411  _index = *ptr;
412 //extern const char *PROFILES[];
413 //extern const int PROFILES_COUNT;
414 
415  if (JSVAL_IS_INT(id))
416  {
417  int index = JSVAL_TO_INT(id);
418  switch(index){
419  case 0://name
420  case 1://Title
421 #if JS_VERSION < 185
422  *rval = STRING_TO_JSVAL(COMPONENTS[_index]);
423 #else
424  JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,PROFILES[_index])));
425 #endif
426  break;
427  case 2://level
428  {
429  int level = capabilitiesHandler_getProfileLevel(_index);
430 #if JS_VERSION < 185
431  *rval = INT_TO_JSVAL(lev);
432 #else
433  JS_SET_RVAL(cx,vp,INT_TO_JSVAL(level));
434 #endif
435  }
436  break;
437  case 3://providerUrl
438 #if JS_VERSION < 185
439  *rval = STRING_TO_JSVAL("freewrl.sourceforge.net");
440 #else
441  JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,"freewrl.sourceforge.net")));
442 #endif
443  break;
444  case 4://components ComponentInfoArray
445  {
446  const int *_table = capabilitiesHandler_getProfileComponent(_index);
447  JSObject *_obj;
448  //malloc private not needed
449  _obj = JS_NewObject(cx,&ComponentInfoArrayClass,NULL,obj);
450  if (!JS_DefineProperties(cx, _obj, ComponentInfoArrayProperties)) {
451  printf( "JS_DefineProperties failed in ComponentInfoArrayProperties.\n");
452  return JS_FALSE;
453  }
454 
455  if (!JS_SetPrivate(cx, _obj, (void*)_table)) {
456  printf( "JS_SetPrivate failed in ComponentInfoArray.\n");
457  return JS_FALSE;
458  }
459 #if JS_VERSION < 185
460  *rval = OBJECT_TO_JSVAL(_obj);
461 #else
462  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
463 #endif
464  }
465  break;
466  }
467  }
468  return JS_TRUE;
469 }
470 JSBool
471 #if JS_VERSION < 185
472 ProfileInfoSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
473 #else
474 ProfileInfoSetProperty(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp)
475 #endif
476 {
477  //can I, should I force it to read-only this way?
478  return JS_FALSE;
479 }
480 
481 static JSClass ProfileInfoClass = {
482  "ProfileInfo",
483  JSCLASS_HAS_PRIVATE,
484  JS_PropertyStub,
485  JS_PropertyStub,
486  ProfileInfoGetProperty,
487  ProfileInfoSetProperty,
488  JS_EnumerateStub,
489  JS_ResolveStub,
490  JS_ConvertStub,
491  JS_FinalizeStub
492 };
493 
494 static JSPropertySpec (ProfileInfoProperties)[] = {
495  //executionContext
496  {"name", 0, JSPROP_ENUMERATE},
497  {"Title", 1, JSPROP_ENUMERATE},
498  {"level", 2, JSPROP_ENUMERATE},
499  {"providerUrl", 3, JSPROP_ENUMERATE},
500  {"components", 4, JSPROP_ENUMERATE},
501  {0}
502 };
503 
504 //ProfileInfoArray{
505 //numeric length;
506 //ProfileInfo [integer index];
507 //}
508 
509 JSBool
510 #if JS_VERSION < 185
511 ProfileInfoArrayGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
512 #else
513 ProfileInfoArrayGetProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp)
514 #endif
515 {
516  jsval rval;
517  jsval id;
518 
519  UNUSED(rval); // compiler warning mitigation
520 
521 #if JS_VERSION >= 185
522  if (!JS_IdToValue(cx,iid,&id)) {
523  printf("JS_IdToValue failed in ProfileInfoArrayGetProperty.\n");
524  return JS_FALSE;
525  }
526 #endif
527 
528  if (JSVAL_IS_INT(id))
529  {
530  int index = JSVAL_TO_INT(id);
531  if(index == -1){
532  int _length = PROFILES_COUNT;
533 #if JS_VERSION < 185
534  *rval = INT_TO_JSVAL(_length);
535 #else
536  JS_SET_RVAL(cx,vp,INT_TO_JSVAL(_length));
537 #endif
538  }else
539  //if(index < getNumberOfProfiles() )
540  {
541  JSObject *_obj;
542  int* _index = MALLOC(void *, sizeof(int));
543  _obj = JS_NewObject(cx,&ProfileInfoClass,NULL,obj);
544  *_index = index;
545  if (!JS_DefineProperties(cx, _obj, ProfileInfoProperties)) {
546  printf( "JS_DefineProperties failed in ProfileInfoProperties.\n");
547  return JS_FALSE;
548  }
549 
550  if (!JS_SetPrivate(cx, _obj, (void*)_index)) {
551  printf( "JS_SetPrivate failed in ProfileInfoArray.\n");
552  return JS_FALSE;
553  }
554 
555 #if JS_VERSION < 185
556  *rval = OBJECT_TO_JSVAL(_obj);
557 #else
558  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
559 #endif
560 
561  }
562  }
563  return JS_TRUE;
564 }
565 JSBool
566 #if JS_VERSION < 185
567 ProfileInfoArraySetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
568 #else
569 ProfileInfoArraySetProperty(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp)
570 #endif
571 {
572  //can I, should I force it to read-only this way?
573  return JS_FALSE;
574 }
575 
576 
577 static JSClass ProfileInfoArrayClass = {
578  "ProfileInfo",
579  JSCLASS_HAS_PRIVATE,
580  JS_PropertyStub,
581  JS_PropertyStub,
582  ProfileInfoArrayGetProperty,
583  ProfileInfoArraySetProperty,
584  JS_EnumerateStub,
585  JS_ResolveStub,
586  JS_ConvertStub,
587  JS_FinalizeStub
588 };
589 
590 static JSPropertySpec (ProfileInfoArrayProperties)[] = {
591  {"length", -1, JSPROP_READONLY | JSPROP_SHARED | JSPROP_PERMANENT}, //JSPROP_ENUMERATE},
592  {0}
593 };
594 
595 
596 
597 
598 //X3DRoute{
599 //SFNode sourceNode;
600 //String sourceField;
601 //SFNode destinationNode;
602 //String destinationField;
603 //}
604 struct CRStruct *getCRoutes();
605 int getCRouteCount();
606 
607 JSBool
608 #if JS_VERSION < 185
609 X3DRouteGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
610 #else
611 X3DRouteGetProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp)
612 #endif
613 {
614  int *ptr;
615  int _index;
616  JSString *_str;
617  jsval rval;
618  struct X3D_Node *fromNode, *toNode;
619  int fromOffset, toOffset;
620  const char *fieldname;
621  jsval id;
622 
623  UNUSED(rval); // compiler warning mitigation
624 
625 #if JS_VERSION >= 185
626  if (!JS_IdToValue(cx,iid,&id)) {
627  printf("JS_IdToValue failed in ProfileInfoGetProperty.\n");
628  return JS_FALSE;
629  }
630 #endif
631  if ((ptr = (int *)JS_GetPrivate(cx, obj)) == NULL) {
632  printf( "JS_GetPrivate failed in ProfileInfoGetProperty.\n");
633  return JS_FALSE;
634  }
635  _index = *ptr;
636  //routes = getCRoutes();
637  //route = routes[_index];
638  getSpecificRoute (_index,&fromNode, &fromOffset, &toNode, &toOffset);
639  //fromName = parser_getNameFromNode(fromNode);
640  //toName = parser_getNameFromNode(toNode);
641 
642  //fprintf (fp, " %p %s.%s TO %p %s.%s \n",fromNode,fromName,
643  // findFIELDNAMESfromNodeOffset0(fromNode,fromOffset),
644  // toNode,toName,
645  // findFIELDNAMESfromNodeOffset0(toNode,toOffset)
646  // );
647 
648  if (JSVAL_IS_INT(id))
649  {
650  int index = JSVAL_TO_INT(id);
651  switch(index){
652  case 0://sourceNode
653  case 2://destinationNode
654  //route.routeFromNode
655  {
656  JSObject *_obj;
657  SFNodeNative *sfnn = MALLOC(void *, sizeof(SFNodeNative));
658  memset(sfnn,0,sizeof(SFNodeNative)); //I don't know if I'm supposed to set something else dug9 aug5,2013
659  if(index==0)
660  sfnn->handle = fromNode;
661  if(index==2)
662  sfnn->handle = toNode;
663 
664  _obj = JS_NewObject(cx,&SFNodeClass,NULL,obj);
665  if (!JS_DefineProperties(cx, _obj, SFNodeProperties)) {
666  printf( "JS_DefineProperties failed in Route sourceNode.\n");
667  return JS_FALSE;
668  }
669  if (!JS_DefineFunctions(cx, _obj, SFNodeFunctions)) {
670  printf( "JS_DefineFunctions failed in Route sourceNode.\n");
671  return JS_FALSE;
672  }
673 
674  if (!JS_SetPrivate(cx, _obj, (void*)sfnn)) {
675  printf( "JS_SetPrivate failed in Route sourceNode.\n");
676  return JS_FALSE;
677  }
678 
679 #if JS_VERSION < 185
680  *rval = OBJECT_TO_JSVAL(_obj);
681 #else
682  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
683 #endif
684  }
685  break;
686 
687  case 1://sourceField
688  fieldname = findFIELDNAMESfromNodeOffset0(fromNode,fromOffset);
689  _str = JS_NewStringCopyZ(cx,fieldname);
690 #if JS_VERSION < 185
691  *rval = STRING_TO_JSVAL(_str);
692 #else
693  JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
694 #endif
695  break;
696  case 3://destinationField
697  fieldname = findFIELDNAMESfromNodeOffset0(toNode,toOffset);
698  _str = JS_NewStringCopyZ(cx,fieldname);
699 #if JS_VERSION < 185
700  *rval = STRING_TO_JSVAL(_str);
701 #else
702  JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
703 #endif
704 
705  break;
706  }
707  }
708  return JS_TRUE;
709 }
710 JSBool
711 #if JS_VERSION < 185
712 X3DRouteSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
713 #else
714 X3DRouteSetProperty(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp)
715 #endif
716 {
717  //can I, should I force it to read-only this way?
718  return JS_FALSE;
719 }
720 
721 static JSClass X3DRouteClass = {
722  "X3DRoute",
723  JSCLASS_HAS_PRIVATE,
724  JS_PropertyStub,
725  JS_PropertyStub,
726  X3DRouteGetProperty,
727  X3DRouteSetProperty,
728  JS_EnumerateStub,
729  JS_ResolveStub,
730  JS_ConvertStub,
731  JS_FinalizeStub
732 };
733 
734 static JSPropertySpec (X3DRouteProperties)[] = {
735  //executionContext
736  {"sourceNode", 0, JSPROP_ENUMERATE},
737  {"sourceField", 1, JSPROP_ENUMERATE},
738  {"destinationNode", 2, JSPROP_ENUMERATE},
739  {"destinationField", 3, JSPROP_ENUMERATE},
740  {0}
741 };
742 
743 
744 //ProfileInfoArray{
745 //numeric length;
746 //ProfileInfo [integer index];
747 //}
748 
749 JSBool
750 #if JS_VERSION < 185
751 RouteArrayGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
752 #else
753 RouteArrayGetProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp)
754 #endif
755 {
756  jsval rval;
757  jsval id;
758 
759  UNUSED(rval); //compiler warning mitigation
760 
761 #if JS_VERSION >= 185
762  if (!JS_IdToValue(cx,iid,&id)) {
763  printf("JS_IdToValue failed in RouteArrayGetProperty.\n");
764  return JS_FALSE;
765  }
766 #endif
767 
768  if (JSVAL_IS_INT(id))
769  {
770  int index = JSVAL_TO_INT(id);
771  if(index == -1){
772  int _length = getCRouteCount();
773 #if JS_VERSION < 185
774  *rval = INT_TO_JSVAL(_length);
775 #else
776  JS_SET_RVAL(cx,vp,INT_TO_JSVAL(_length));
777 #endif
778  }else
779  //if(index < getNumberOfProfiles() )
780  {
781  JSObject *_obj;
782  int* _index = MALLOC(void *, sizeof(int));
783  _obj = JS_NewObject(cx,&X3DRouteClass,NULL,obj);
784  *_index = index;
785  if (!JS_DefineProperties(cx, _obj, X3DRouteProperties)) {
786  printf( "JS_DefineProperties failed in RouteArray.\n");
787  return JS_FALSE;
788  }
789 
790  if (!JS_SetPrivate(cx, _obj, (void*)_index)) {
791  printf( "JS_SetPrivate failed in RouteArray.\n");
792  return JS_FALSE;
793  }
794 
795 #if JS_VERSION < 185
796  *rval = OBJECT_TO_JSVAL(_obj);
797 #else
798  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
799 #endif
800 
801  }
802  }
803  return JS_TRUE;
804 }
805 JSBool
806 #if JS_VERSION < 185
807 RouteArraySetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
808 #else
809 RouteArraySetProperty(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp)
810 #endif
811 {
812  //can I, should I force it to read-only this way?
813  return JS_FALSE;
814 }
815 
816 
817 static JSClass RouteArrayClass = {
818  "RouteArray",
819  JSCLASS_HAS_PRIVATE,
820  JS_PropertyStub,
821  JS_PropertyStub,
822  RouteArrayGetProperty,
823  RouteArraySetProperty,
824  JS_EnumerateStub,
825  JS_ResolveStub,
826  JS_ConvertStub,
827  JS_FinalizeStub
828 };
829 
830 static JSPropertySpec (RouteArrayProperties)[] = {
831  {"length", -1, JSPROP_READONLY | JSPROP_SHARED | JSPROP_PERMANENT}, //JSPROP_ENUMERATE},
832  {0}
833 };
834 
835 
836 
837 
838 static JSFunctionSpec (ExecutionContextFunctions)[] = {
839  //executionContext
840  //{"addRoute", X3DExecutionContext_addRoute, 0},
841  //{"deleteRoute", X3DExecutionContext_deleteRoute, 0},
842  //{"createNode", X3DExecutionContext_createNode, 0},
843  //{"createProto", X3DExecutionContext_createProto, 0},
844  //{"getImportedNode", X3DExecutionContext_getImportedNode, 0},
845  //{"updateImportedNode", X3DExecutionContext_updateImportedNode, 0},
846  //{"removeImportedNode", X3DExecutionContext_removeImportedNode, 0},
847  //{"getNamedNode", X3DExecutionContext_getNamedNode, 0},
848  //{"updateNamedNode", X3DExecutionContext_updateNamedNode, 0},
849  //{"removeNamedNode", X3DExecutionContext_removeNamedNode, 0},
851  //{"setMetaData", X3DScene_setMetaData, 0},
852  //{"getMetaData", X3DScene_getMetaData, 0},
853  //{"getExportedNode", X3DScene_getExportedNode, 0},
854  //{"updateExportedNode", X3DScene_updateExportedNode, 0},
855  //{"removeExportedNode", X3DScene_removeExportedNode, 0},
856  {0}
857 };
858 
859 
860 static JSPropertySpec (ExecutionContextProperties)[] = {
861  //executionContext
862  {"specificationVersion", 0, JSPROP_ENUMERATE},
863  {"encoding", 1, JSPROP_ENUMERATE},
864  {"profile", 2, JSPROP_ENUMERATE},
865  {"components", 3, JSPROP_ENUMERATE},
866  {"worldURL", 4, JSPROP_ENUMERATE},
867  {"rootNodes", 5, JSPROP_ENUMERATE},
868  {"protos", 6, JSPROP_ENUMERATE},
869  {"externprotos", 7, JSPROP_ENUMERATE},
870  {"routes", 8, JSPROP_ENUMERATE},
871  //scene
872  //{"specificationVersion", 9, JSPROP_ENUMERATE}, //already done for executionContext above
873  {"isScene", 9, JSPROP_ENUMERATE}, //else protoInstance. extra beyond specs - I think flux has it.
874  {0}
875 };
876 
877 //typedef struct _ExecutionContextNative {
878 // struct X3D_Node *handle;
879 //} ExecutionContextNative;
880 typedef struct X3D_Node * ExecutionContextNative;
881 
882 JSBool
883 #if JS_VERSION < 185
884 ExecutionContextGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
885 #else
886 ExecutionContextGetProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp)
887 #endif
888 {
889  ExecutionContextNative *ptr;
890  JSString *_str;
891  jsval rval;
892  jsval id;
893 
894  UNUSED(rval); //compiler warning mitigation
895 
896 #if JS_VERSION >= 185
897  if (!JS_IdToValue(cx,iid,&id)) {
898  printf("JS_IdToValue failed in ExecutionContextGetProperty.\n");
899  return JS_FALSE;
900  }
901 #endif
902 
903  if ((ptr = (ExecutionContextNative *)JS_GetPrivate(cx, obj)) == NULL) {
904  printf( "JS_GetPrivate failed in ExecutionContextGetProperty.\n");
905  return JS_FALSE;
906  }
907 
908  if (JSVAL_IS_INT(id)) {
909  switch (JSVAL_TO_INT(id)) {
910  case 0: //specificationVersion string readonly
911  {
912  char cs[100];
913  sprintf(cs,"{%d,%d,%d}",inputFileVersion[0],inputFileVersion[1],inputFileVersion[2]);
914  _str = JS_NewStringCopyZ(cx,cs);
915  }
916 #if JS_VERSION < 185
917  *rval = STRING_TO_JSVAL(_str);
918 #else
919  JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
920 #endif
921  break;
922  case 1: //encoding string readonly
923  //Valid values are "ASCII", "VRML", "XML", "BINARY", "SCRIPTED", "BIFS", "NONE"
924  _str = JS_NewStringCopyZ(cx, "not filled in yet sb. VRML or XML or ..");
925 #if JS_VERSION < 185
926  *rval = STRING_TO_JSVAL(_str);
927 #else
928  JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
929 #endif
930  break;
931  case 2: //profile ProfileInfo readonly
932  {
933  int index = gglobal()->Mainloop.scene_profile;
934 
935  JSObject *_obj;
936  int* _index = MALLOC(void *, sizeof(int));
937  _obj = JS_NewObject(cx,&ProfileInfoClass,NULL,obj);
938  *_index = index;
939  if (!JS_DefineProperties(cx, _obj, ProfileInfoProperties)) {
940  printf( "JS_DefineProperties failed in ExecutionContextProfileInfoProperties.\n");
941  return JS_FALSE;
942  }
943 
944  if (!JS_SetPrivate(cx, _obj, (void*)_index)) {
945  printf( "JS_SetPrivate failed in ExecutionContextProfileInfoArray.\n");
946  return JS_FALSE;
947  }
948 
949 #if JS_VERSION < 185
950  *rval = OBJECT_TO_JSVAL(_obj);
951 #else
952  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
953 #endif
954  }
955  break;
956  case 3: //components ComponentInfoArray readonly
957  {
958  JSObject *_obj;
959  //int ncomp;
960  const int *_table = gglobal()->Mainloop.scene_components; //capabilitiesHandler_getProfileComponent(_index);
961  //ncomp = capabilitiesHandler_getTableLength(_table);
962  //malloc private not needed
963  _obj = JS_NewObject(cx,&ComponentInfoArrayClass,NULL,obj);
964  if (!JS_DefineProperties(cx, _obj, ComponentInfoArrayProperties)) {
965  printf( "JS_DefineProperties failed in ExecutionContext_ComponentInfoArrayProperties.\n");
966  return JS_FALSE;
967  }
968 
969  if (!JS_SetPrivate(cx, _obj, (void*)_table)) {
970  printf( "JS_SetPrivate failed in ExecutionContext_ComponentInfoArray.\n");
971  return JS_FALSE;
972  }
973 #if JS_VERSION < 185
974  *rval = OBJECT_TO_JSVAL(_obj);
975 #else
976  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
977 #endif
978  }
979  break;
980  case 4: //worldURL string readonly
981  _str = JS_NewStringCopyZ(cx, gglobal()->Mainloop.url);
982 #if JS_VERSION < 185
983  *rval = STRING_TO_JSVAL(_str);
984 #else
985  JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
986 #endif
987  break;
988  case 5: //rootNodes MFNode (readonly if !isScene, else rw)
989  {
990  JSObject *_obj;
991  //MFNodeNative *mfn;
992 
993  //struct X3D_Group* scene = (struct X3D_Group*)(struct X3D_Node*)ptr; //->handle;
994  return JS_FALSE;
995 
996  //scene->children;
997  //somehow return children as an MFNode
998  //mfn = MALLOC(void *, sizeof(MFNodeNative));
999  _obj = JS_NewObject(cx,&MFNodeClass,NULL,obj);
1000 
1001  //mfn->handle = (struct X3D_Node*)rootNode(); //change this to (Script)._executionContext when brotos working fully
1002  //if (!JS_DefineProperties(cx, _obj, MFNodeProperties)) {
1003  // printf( "JS_DefineProperties failed in SFRotationConstr.\n");
1004  // return JS_FALSE;
1005  //}
1006  if (!JS_DefineFunctions(cx, _obj, MFNodeFunctions)) {
1007  printf( "JS_DefineProperties failed in SFRotationConstr.\n");
1008  return JS_FALSE;
1009  }
1010 //OUCH NEEDS WORK i DON'T KNOW WHAT I'M DOING
1011  //if (!JS_SetPrivate(cx, _obj, &scene->children)) {
1012  // printf( "JS_SetPrivate failed in ExecutionContext.\n");
1013  // return JS_FALSE;
1014  //}
1015 
1016 #if JS_VERSION < 185
1017  *rval = OBJECT_TO_JSVAL(_obj);
1018 #else
1019  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
1020 #endif
1021  }
1022  break;
1023  case 6: //protos protoDeclarationArray rw
1024  case 7: //externprotos externProtoDeclarationArray rw
1025  return JS_FALSE;
1026  case 8: //routes RouteArray readonly
1027  {
1028  JSObject *_obj;
1029  //malloc private not needed
1030  _obj = JS_NewObject(cx,&RouteArrayClass,NULL,obj);
1031  if (!JS_DefineProperties(cx, _obj, RouteArrayProperties)) {
1032  printf( "JS_DefineProperties failed in ExecutionContext_X3DRouteArrayProperties.\n");
1033  return JS_FALSE;
1034  }
1035  //if (!JS_SetPrivate(cx, _obj, (void*)_table)) {
1036  // printf( "JS_SetPrivate failed in ExecutionContext_X3DRouteArray.\n");
1037  // return JS_FALSE;
1038  //}
1039 #if JS_VERSION < 185
1040  *rval = OBJECT_TO_JSVAL(_obj);
1041 #else
1042  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
1043 #endif
1044  }
1045  break;
1046  case 9: //isScene readonly (extra to specs)
1047  //once brotos are working then the main scene broto will need a flag to say it's a scene
1048  JS_SET_RVAL(cx,vp,BOOLEAN_TO_JSVAL(JS_TRUE));
1049  break;
1050  }
1051  }
1052  return JS_TRUE;
1053 }
1054 
1055 
1056 JSBool
1057 #if JS_VERSION < 185
1058 ExecutionContextSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
1059 #else
1060 ExecutionContextSetProperty(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp)
1061 #endif
1062 {
1063  //can I, should I force it to read-only this way?
1064  return JS_FALSE;
1065 }
1066 static JSClass ExecutionContextClass = {
1067  "ExecutionContext",
1068  JSCLASS_HAS_PRIVATE,
1069  JS_PropertyStub,
1070  JS_PropertyStub,
1071  ExecutionContextGetProperty,
1072  ExecutionContextSetProperty,
1073  JS_EnumerateStub,
1074  JS_ResolveStub,
1075  JS_ConvertStub,
1076  JS_FinalizeStub
1077 };
1078 
1079 
1080 static JSPropertySpec (BrowserProperties)[] = {
1081  {"name", 0, JSPROP_ENUMERATE},
1082  {"version", 1, JSPROP_ENUMERATE},
1083  {"currentSpeed", 2, JSPROP_ENUMERATE},
1084  {"currentFrameRate", 3, JSPROP_ENUMERATE},
1085  {"description", 4, JSPROP_ENUMERATE},
1086  {"supportedComponents", 5, JSPROP_ENUMERATE},
1087  {"supportedProfiles", 6, JSPROP_ENUMERATE},
1088  {"currentScene", 7, JSPROP_ENUMERATE},
1089  {0}
1090 };
1091 
1092 JSBool
1093 #if JS_VERSION < 185
1094 BrowserGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
1095 #else
1096 BrowserGetProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp)
1097 #endif
1098 {
1099  BrowserNative *ptr;
1100  jsdouble d;
1101  JSString *_str;
1102  jsval rval;
1103  jsval id;
1104 
1105  UNUSED(rval); // compiler warning mitigation
1106 
1107 #if JS_VERSION >= 185
1108  if (!JS_IdToValue(cx,iid,&id)) {
1109  printf("JS_IdToValue failed in BrowserGetProperty.\n");
1110  return JS_FALSE;
1111  }
1112 #endif
1113 
1114  //right now we don't need/use the ptr to BrowserNative which is a stub struct,
1115  //because browser is conceptually a global static singleton
1116  //(or more precisely 1:1 with a gglobal[i] 'browser instance' for things like framerate,
1117  // and 1:1 with static for unchanging things like browser version, components and profiles supported),
1118  //and in practice all the bits and pieces are scattered throughout freewrl
1119  //but for fun we'll get it:
1120  if ((ptr = (BrowserNative *)JS_GetPrivate(cx, obj)) == NULL) {
1121  printf( "JS_GetPrivate failed in BrowserGetProperty.\n");
1122  return JS_FALSE;
1123  }
1124 
1125  if (JSVAL_IS_INT(id)) {
1126  switch (JSVAL_TO_INT(id)) {
1127  case 0: //name
1128  _str = JS_NewStringCopyZ(cx,BrowserName);
1129 #if JS_VERSION < 185
1130  *rval = STRING_TO_JSVAL(_str);
1131 #else
1132  JS_SET_RVAL(cx,vp,STRING_TO_JSVAL(_str));
1133 #endif
1134  break;
1135  case 1: //version
1136  _str = JS_NewStringCopyZ(cx, libFreeWRL_get_version());
1137 #if JS_VERSION < 185
1138  *rval = STRING_TO_JSVAL(_str);
1139 #else
1140  JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
1141 #endif
1142  break;
1143  case 2: //currentSpeed
1144  /* get the variable updated */
1145  getCurrentSpeed();
1146  d = gglobal()->Mainloop.BrowserSpeed;
1147  if (JS_NewNumberValue(cx, d, vp) == JS_FALSE) {
1148  printf("JS_NewDouble failed for %f in BrowserGetProperty.\n",d);
1149  return JS_FALSE;
1150  }
1151  break;
1152  case 3: //currentFrameRate
1153  d = gglobal()->Mainloop.BrowserFPS;
1154  if (JS_NewNumberValue(cx, d, vp) == JS_FALSE) {
1155  printf("JS_NewDouble failed for %f in BrowserGetProperty.\n",d);
1156  return JS_FALSE;
1157  }
1158  break;
1159  case 4: //description
1160  _str = JS_NewStringCopyZ(cx, get_status());
1161 #if JS_VERSION < 185
1162  *rval = STRING_TO_JSVAL(_str);
1163 #else
1164  JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
1165 #endif
1166  break;
1167  case 5: //supportedComponents
1168  {
1169  JSObject *_obj;
1170  //malloc private not needed
1171  _obj = JS_NewObject(cx,&ComponentInfoArrayClass,NULL,obj);
1172  if (!JS_DefineProperties(cx, _obj, ComponentInfoArrayProperties)) {
1173  printf( "JS_DefineProperties failed in ComponentInfoArrayProperties.\n");
1174  return JS_FALSE;
1175  }
1176  //if (!JS_DefineFunctions(cx, _obj, ProfileInfoArrayFunctions)) {
1177  // printf( "JS_DefineProperties failed in ExecutionContextFunctions.\n");
1178  // return JS_FALSE;
1179  //}
1180  if (!JS_SetPrivate(cx, _obj, (void*)capabilitiesHandler_getCapabilitiesTable())) {
1181  printf( "JS_SetPrivate failed in ExecutionContext.\n");
1182  return JS_FALSE;
1183  }
1184 
1185 #if JS_VERSION < 185
1186  *rval = OBJECT_TO_JSVAL(_obj);
1187 #else
1188  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
1189 #endif
1190 
1191  }
1192  break;
1193 
1194  case 6: //supportedProfiles
1195  {
1196  JSObject *_obj;
1197  //malloc private not needed
1198  _obj = JS_NewObject(cx,&ProfileInfoArrayClass,NULL,obj);
1199  if (!JS_DefineProperties(cx, _obj, ProfileInfoArrayProperties)) {
1200  printf( "JS_DefineProperties failed in ExecutionContextProperties.\n");
1201  return JS_FALSE;
1202  }
1203  //if (!JS_DefineFunctions(cx, _obj, ProfileInfoArrayFunctions)) {
1204  // printf( "JS_DefineProperties failed in ExecutionContextFunctions.\n");
1205  // return JS_FALSE;
1206  //}
1207  //set private not needed
1208  //if (!JS_SetPrivate(cx, _obj, ec)) {
1209  // printf( "JS_SetPrivate failed in ExecutionContext.\n");
1210  // return JS_FALSE;
1211  //}
1212 
1213 #if JS_VERSION < 185
1214  *rval = OBJECT_TO_JSVAL(_obj);
1215 #else
1216  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
1217 #endif
1218 
1219  }
1220  break;
1221  case 7: //currentScene
1222 #ifdef sceneIsBroto
1223  //someday soon I hope, the ScriptNode._executionContext might be working,
1224  //and give you the currentScene native pointer to put as PRIVATE in BrowserNative
1225 #else
1226  //in theory it's rootNode() in
1227  //struct X3D_Group *rootNode()
1228  //H: I have to return an ExecutionContextNative here with its guts set to our rootNode or ???
1229  {
1230  JSObject *_obj;
1231  ExecutionContextNative ec = MALLOC(void *, sizeof(ExecutionContextNative));
1232  _obj = JS_NewObject(cx,&ExecutionContextClass,NULL,obj);
1233 
1234  //ec->handle = (struct X3D_Node*)rootNode(); //change this to (Script)._executionContext when brotos working fully
1235  ec = (struct X3D_Node*)rootNode(); //change this to (Script)._executionContext when brotos working fully
1236  if (!JS_DefineProperties(cx, _obj, ExecutionContextProperties)) {
1237  printf( "JS_DefineProperties failed in ExecutionContextProperties.\n");
1238  return JS_FALSE;
1239  }
1240  if (!JS_DefineFunctions(cx, _obj, ExecutionContextFunctions)) {
1241  printf( "JS_DefineProperties failed in ExecutionContextFunctions.\n");
1242  return JS_FALSE;
1243  }
1244 
1245  if (!JS_SetPrivate(cx, _obj, ec)) {
1246  printf( "JS_SetPrivate failed in ExecutionContext.\n");
1247  return JS_FALSE;
1248  }
1249 
1250 #if JS_VERSION < 185
1251  *rval = OBJECT_TO_JSVAL(_obj);
1252 #else
1253  JS_SET_RVAL(cx,vp,OBJECT_TO_JSVAL(_obj));
1254 #endif
1255 
1256  }
1257 
1258 #endif
1259  }
1260  }
1261  return JS_TRUE;
1262 }
1263 
1264 
1265 JSBool
1266 #if JS_VERSION < 185
1267 BrowserSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
1268 #else
1269 BrowserSetProperty(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp)
1270 #endif
1271 {
1272  BrowserNative *ptr;
1273  jsval _val;
1274  JSString *ss;
1275  char *cs;
1276 #if JS_VERSION >= 185
1277  jsval id;
1278  if (!JS_IdToValue(cx,iid,&id)) {
1279  printf("JS_IdToValue failed in BrowserSetProperty.\n");
1280  return JS_FALSE;
1281  }
1282 #endif
1283 
1284  if ((ptr = (BrowserNative *)JS_GetPrivate(cx, obj)) == NULL) {
1285  printf( "JS_GetPrivate failed in BrowserSetProperty.\n");
1286  return JS_FALSE;
1287  }
1288  //ptr->valueChanged++;
1289 
1290  if (!JS_ConvertValue(cx, *vp, JSTYPE_STRING, &_val)) {
1291  printf( "JS_ConvertValue failed in BrowserSetProperty.\n");
1292  return JS_FALSE;
1293  }
1294 
1295  if (JSVAL_IS_INT(id)) {
1296  switch (JSVAL_TO_INT(id)) {
1297  case 0:
1298  case 1:
1299  case 2:
1300  case 3:
1301  return JS_FALSE;
1302  case 4: //description
1303  ss = JS_ValueToString(cx, _val);
1304  cs = JS_EncodeString(cx, ss);
1305  update_status(cs); //script node setting the statusbar text
1306  break;
1307  case 5:
1308  case 6:
1309  case 7:
1310  return JS_FALSE;
1311 
1312  }
1313  }
1314  return JS_TRUE;
1315 }
1316 
1317 
1318 #endif
1319 
1320 
1323 //jsval JSCreate_global_return_val;
1324 typedef struct pjsVRMLBrowser{
1325  int ijunk;
1326 
1327  jsval JSCreate_global_return_val;
1328 
1329 
1330 }* ppjsVRMLBrowser;
1331 void *jsVRMLBrowser_constructor(){
1332  void *v = MALLOC(void *, sizeof(struct pjsVRMLBrowser));
1333  memset(v,0,sizeof(struct pjsVRMLBrowser));
1334  return v;
1335 }
1336 void jsVRMLBrowser_init(struct tjsVRMLBrowser *t){
1337  //public
1338  //private
1339  t->prv = jsVRMLBrowser_constructor();
1340  {
1341  ppjsVRMLBrowser p = (ppjsVRMLBrowser)t->prv;
1342  /* Script name/type table */
1343 
1344  t->JSCreate_global_return_val = &p->JSCreate_global_return_val;
1345 
1346  }
1347 
1348 }
1349 // ppjsVRMLBrowser p = (ppjsVRMLBrowser)gglobal()->jsVRMLBrowser.prv;
1350 /* we add/remove routes with this call */
1351 void jsRegisterRoute(
1352  struct X3D_Node* from, int fromOfs,
1353  struct X3D_Node* to, int toOfs,
1354  int len, const char *adrem) {
1355  int ad;
1356 
1357  if (strcmp("addRoute",adrem) == 0)
1358  ad = 1;
1359  else ad = 0;
1360 
1361  CRoutes_Register(ad, from, fromOfs, to, toOfs , len,
1362  returnInterpolatorPointer(to->_nodeType), 0, 0);
1363 }
1364 
1365 
1366 /* used in loadURL*/
1367 void conCat (char *out, char *in) {
1368 
1369  while (strlen (in) > 0) {
1370  strcat (out," :loadURLStringBreak:");
1371  while (*out != '\0') out++;
1372 
1373  if (*in == '[') in++;
1374  while ((*in != '\0') && (*in == ' ')) in++;
1375  if (*in == '"') {
1376  in++;
1377  /* printf ("have the initial quote string here is %s\n",in); */
1378  while (*in != '"') { *out = *in; out++; in++; }
1379  *out = '\0';
1380  /* printf ("found string is :%s:\n",tfilename); */
1381  }
1382 
1383  /* skip along to the start of the next name */
1384  if (*in == '"') in++;
1385  if (*in == ',') in++;
1386  if (*in == ']') in++; /* this allows us to leave */
1387  }
1388 }
1389 
1390 
1391 
1392 void createLoadUrlString(char *out, int outLen, char *url, char *param) {
1393  int commacount1;
1394  int commacount2;
1395  char *tptr;
1396 
1397  /* mimic the EAI loadURL, java code is:
1398  // send along sizes of the Strings
1399  SysString = "" + url.length + " " + parameter.length;
1400 
1401  for (count=0; count<url.length; count++) {
1402  SysString = SysString + " :loadURLStringBreak:" + url[count];
1403  }
1404 
1405  for (count=0; count<parameter.length; count++) {
1406  SysString = SysString + " :loadURLStringBreak:" + parameter[count];
1407  }
1408  */
1409 
1410  /* find out how many elements there are */
1411 
1412  commacount1 = 0; commacount2 = 0;
1413  tptr = url; while (*tptr != '\0') { if (*tptr == '"') commacount1 ++; tptr++; }
1414  tptr = param; while (*tptr != '\0') { if (*tptr == '"') commacount2 ++; tptr++; }
1415  commacount1 = commacount1 / 2;
1416  commacount2 = commacount2 / 2;
1417 
1418  if ((int)(strlen(url) +
1419  strlen(param) +
1420  (commacount1 * strlen (" :loadURLStringBreak:")) +
1421  (commacount2 * strlen (" :loadURLStringBreak:"))) > (outLen - 20)) {
1422  printf ("createLoadUrlString, string too long\n");
1423  return;
1424  }
1425 
1426  sprintf (out,"%d %d",commacount1,commacount2);
1427 
1428  /* go to the end of this string */
1429  while (*out != '\0') out++;
1430 
1431  /* go through the elements and find which (if any) url exists */
1432  conCat (out,url);
1433  while (*out != '\0') out++;
1434  conCat (out,param);
1435 }
1436 
1437 
1438 JSBool
1439 VrmlBrowserInit(JSContext *context, JSObject *globalObj, BrowserNative *brow)
1440 {
1441  JSObject *obj;
1442  ttglobal tg = gglobal();
1443  *(jsval *)tg->jsVRMLBrowser.JSCreate_global_return_val = INT_TO_JSVAL(0);
1444 
1445  #ifdef JSVERBOSE
1446  printf("VrmlBrowserInit\n");
1447  #endif
1448 
1449  obj = JS_DefineObject(context, globalObj, "Browser", &Browser, NULL,
1450  JSPROP_ENUMERATE | JSPROP_PERMANENT);
1451  if (!JS_DefineFunctions(context, obj, BrowserFunctions)) {
1452  printf( "JS_DefineFunctions failed in VrmlBrowserInit.\n");
1453  return JS_FALSE;
1454  }
1455 #ifdef X3DBROWSER
1456 
1457  if (!JS_DefineProperties(context, obj, BrowserProperties)) {
1458  printf( "JS_DefineProperties failed in VrmlBrowserInit.\n");
1459  return JS_FALSE;
1460  }
1461 #endif
1462  if (!JS_SetPrivate(context, obj, brow)) {
1463  printf( "JS_SetPrivate failed in VrmlBrowserInit.\n");
1464  return JS_FALSE;
1465  }
1466  return JS_TRUE;
1467 }
1468 
1469 
1470 JSBool
1471 #if JS_VERSION < 185
1472 VrmlBrowserGetName(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
1473 #else
1474 VrmlBrowserGetName(JSContext *context, uintN argc, jsval *vp) {
1475  JSObject *obj = JS_THIS_OBJECT(context,vp);
1476  jsval *argv = JS_ARGV(context,vp);
1477 #endif
1478  JSString *_str;
1479 
1480  UNUSED(obj);
1481  UNUSED(argc);
1482  UNUSED(argv);
1483 
1484  _str = JS_NewStringCopyZ(context,BrowserName);
1485 #if JS_VERSION < 185
1486  *rval = STRING_TO_JSVAL(_str);
1487 #else
1488  JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
1489 #endif
1490  return JS_TRUE;
1491 }
1492 
1493 
1494 /* get the string stored in FWVER into a jsObject */
1495 JSBool
1496 #if JS_VERSION < 185
1497 VrmlBrowserGetVersion(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
1498 #else
1499 VrmlBrowserGetVersion(JSContext *context, uintN argc, jsval *vp) {
1500  JSObject *obj = JS_THIS_OBJECT(context,vp);
1501  jsval *argv = JS_ARGV(context,vp);
1502 #endif
1503  JSString *_str;
1504 
1505  UNUSED(obj);
1506  UNUSED(argc);
1507  UNUSED(argv);
1508 
1509  _str = JS_NewStringCopyZ(context, libFreeWRL_get_version());
1510 #if JS_VERSION < 185
1511  *rval = STRING_TO_JSVAL(_str);
1512 #else
1513  JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
1514 #endif
1515  return JS_TRUE;
1516 }
1517 
1518 
1519 JSBool
1520 #if JS_VERSION < 185
1521 VrmlBrowserGetCurrentSpeed(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
1522 #else
1523 VrmlBrowserGetCurrentSpeed(JSContext *context, uintN argc, jsval *vp) {
1524  JSObject *obj = JS_THIS_OBJECT(context,vp);
1525  jsval *argv = JS_ARGV(context,vp);
1526 #endif
1527  JSString *_str;
1528  char string[1000];
1529 
1530  UNUSED(obj);
1531  UNUSED(argc);
1532  UNUSED(argv);
1533 
1534  /* get the variable updated */
1535  getCurrentSpeed();
1536  sprintf (string,"%f",gglobal()->Mainloop.BrowserSpeed);
1537  _str = JS_NewStringCopyZ(context,string);
1538 #if JS_VERSION < 185
1539  *rval = STRING_TO_JSVAL(_str);
1540 #else
1541  JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
1542 #endif
1543  return JS_TRUE;
1544 }
1545 
1546 
1547 JSBool
1548 #if JS_VERSION < 185
1549 VrmlBrowserGetCurrentFrameRate(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
1550 #else
1551 VrmlBrowserGetCurrentFrameRate(JSContext *context, uintN argc, jsval *vp) {
1552  JSObject *obj = JS_THIS_OBJECT(context,vp);
1553  jsval *argv = JS_ARGV(context,vp);
1554 #endif
1555  JSString *_str;
1556  char FPSstring[1000];
1557 
1558  UNUSED(obj);
1559  UNUSED(argc);
1560  UNUSED(argv);
1561 
1562  sprintf (FPSstring,"%6.2f",gglobal()->Mainloop.BrowserFPS);
1563  _str = JS_NewStringCopyZ(context,FPSstring);
1564 #if JS_VERSION < 185
1565  *rval = STRING_TO_JSVAL(_str);
1566 #else
1567  JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
1568 #endif
1569  return JS_TRUE;
1570 }
1571 
1572 
1573 JSBool
1574 #if JS_VERSION < 185
1575 VrmlBrowserGetWorldURL(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
1576 #else
1577 VrmlBrowserGetWorldURL(JSContext *context, uintN argc, jsval *vp) {
1578  JSObject *obj = JS_THIS_OBJECT(context,vp);
1579  jsval *argv = JS_ARGV(context,vp);
1580 #endif
1581  JSString *_str;
1582 
1583  UNUSED(obj);
1584  UNUSED(argc);
1585  UNUSED(argv);
1586 
1587  _str = JS_NewStringCopyZ(context,BrowserFullPath);
1588 #if JS_VERSION < 185
1589  *rval = STRING_TO_JSVAL(_str);
1590 #else
1591  JS_SET_RVAL(context,vp,STRING_TO_JSVAL(_str));
1592 #endif
1593  return JS_TRUE;
1594 }
1595 
1596 
1597 JSBool
1598 #if JS_VERSION < 185
1599 VrmlBrowserReplaceWorld(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
1600 #else
1601 VrmlBrowserReplaceWorld(JSContext *context, uintN argc, jsval *vp) {
1602  jsval *argv = JS_ARGV(context,vp);
1603 #endif
1604  JSObject *_obj;
1605  JSString *_str;
1606  JSClass *_cls;
1607  jsval _rval = INT_TO_JSVAL(0);
1608  char *_c_args = "MFNode nodes",
1609  *_costr,
1610  *_c_format = "o";
1611  char *tptr;
1612 
1613  if (JS_ConvertArguments(context, argc, argv, _c_format, &_obj)) {
1614  if ((_cls = JS_GET_CLASS(context, _obj)) == NULL) {
1615  printf("JS_GetClass failed in VrmlBrowserReplaceWorld.\n");
1616  return JS_FALSE;
1617  }
1618 
1619  if (memcmp("MFNode", _cls->name, strlen(_cls->name)) != 0) {
1620  printf( "\nIncorrect argument in VrmlBrowserReplaceWorld.\n");
1621  return JS_FALSE;
1622  }
1623  _str = JS_ValueToString(context, argv[0]);
1624 #if JS_VERSION < 185
1625  _costr = JS_GetStringBytes(_str);
1626 #else
1627  _costr = JS_EncodeString(context,_str);
1628 #endif
1629  /* sanitize string, for the EAI_RW call (see EAI_RW code) */
1630  tptr = _costr;
1631  while (*tptr != '\0') {
1632  if(*tptr == '[') *tptr = ' ';
1633  if(*tptr == ']') *tptr = ' ';
1634  if(*tptr == ',') *tptr = ' ';
1635  tptr++;
1636  }
1637  EAI_RW(_costr);
1638 #if JS_VERSION >= 185
1639  JS_free(context,_costr);
1640 #endif
1641  } else {
1642  printf( "\nIncorrect argument format for replaceWorld(%s).\n", _c_args);
1643  return JS_FALSE;
1644  }
1645 #if JS_VERSION < 185
1646  *rval = _rval;
1647 #else
1648  JS_SET_RVAL(context,vp,_rval);
1649 #endif
1650 
1651  return JS_TRUE;
1652 }
1653 struct X3D_Anchor* get_EAIEventsIn_AnchorNode();
1654 JSBool
1655 #if JS_VERSION < 185
1656 VrmlBrowserLoadURL(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
1657 #else
1658 VrmlBrowserLoadURL(JSContext *context, uintN argc, jsval *vp) {
1659  jsval *argv = JS_ARGV(context,vp);
1660 #endif
1661  JSObject *_obj[2];
1662  JSString *_str[2];
1663  JSClass *_cls[2];
1664  char *_c_args = "MFString url, MFString parameter",
1665  *_costr[2],
1666  *_c_format = "o o";
1667  #define myBufSize 2000
1668  char myBuf[myBufSize];
1669 
1670  if (JS_ConvertArguments(context, argc, argv, _c_format, &(_obj[0]), &(_obj[1]))) {
1671  if ((_cls[0] = JS_GET_CLASS(context, _obj[0])) == NULL) {
1672  printf( "JS_GetClass failed for arg 0 in VrmlBrowserLoadURL.\n");
1673  return JS_FALSE;
1674  }
1675  if ((_cls[1] = JS_GET_CLASS(context, _obj[1])) == NULL) {
1676  printf( "JS_GetClass failed for arg 1 in VrmlBrowserLoadURL.\n");
1677  return JS_FALSE;
1678  }
1679  if (memcmp("MFString", (_cls[0])->name, strlen((_cls[0])->name)) != 0 &&
1680  memcmp("MFString", (_cls[1])->name, strlen((_cls[1])->name)) != 0) {
1681  printf( "\nIncorrect arguments in VrmlBrowserLoadURL.\n");
1682  return JS_FALSE;
1683  }
1684  _str[0] = JS_ValueToString(context, argv[0]);
1685 #if JS_VERSION < 185
1686  _costr[0] = JS_GetStringBytes(_str[0]);
1687 #else
1688  _costr[0] = JS_EncodeString(context,_str[0]);
1689 #endif
1690 
1691  _str[1] = JS_ValueToString(context, argv[1]);
1692 #if JS_VERSION < 185
1693  _costr[1] = JS_GetStringBytes(_str[1]);
1694 #else
1695  _costr[1] = JS_EncodeString(context,_str[1]);
1696 #endif
1697 
1698  /* we use the EAI code for this - so reformat this for the EAI format */
1699  {
1700  //extern struct X3D_Anchor EAI_AnchorNode; /* win32 C doesnt like new declarations in the middle of executables - start a new scope {} and put dec at top */
1701 
1702  /* make up the URL from what we currently know */
1703  createLoadUrlString(myBuf,myBufSize,_costr[0], _costr[1]);
1704  createLoadURL(myBuf);
1705 
1706  /* now tell the fwl_RenderSceneUpdateScene that BrowserAction is requested... */
1707  setAnchorsAnchor( get_EAIEventsIn_AnchorNode()); //&gglobal()->EAIEventsIn.EAI_AnchorNode;
1708  }
1709  gglobal()->RenderFuncs.BrowserAction = TRUE;
1710 
1711 #if JS_VERSION >= 185
1712  JS_free(context,_costr[0]);
1713  JS_free(context,_costr[1]);
1714 #endif
1715  } else {
1716  printf( "\nIncorrect argument format for loadURL(%s).\n", _c_args);
1717  return JS_FALSE;
1718  }
1719 #if JS_VERSION < 185
1720  *rval = INT_TO_JSVAL(0);
1721 #else
1722  JS_SET_RVAL(context,vp,JSVAL_ZERO);
1723 #endif
1724 
1725  return JS_TRUE;
1726 }
1727 
1728 
1729 JSBool
1730 #if JS_VERSION < 185
1731 VrmlBrowserSetDescription(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
1732  char *_c_format = "s";
1733 #else
1734 VrmlBrowserSetDescription(JSContext *context, uintN argc, jsval *vp) {
1735  jsval *argv = JS_ARGV(context,vp);
1736  JSString *js_c;
1737  char *_c_format = "S";
1738 #endif
1739  char *_c, *_c_args = "SFString description";
1740 
1741  UNUSED(_c); // compiler warning mitigation
1742 
1743  if (argc == 1 &&
1744 #if JS_VERSION < 185
1745  JS_ConvertArguments(context, argc, argv, _c_format, &_c)) {
1746 #else
1747  JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
1748  /* _c = JS_EncodeString(context,js_c);
1749  ...why encode the string when we just have to JS_free it later? */
1750 #endif
1751 
1752  /* we do not do anything with the description. If we ever wanted to, it is in _c */
1753 #if JS_VERSION < 185
1754  *rval = INT_TO_JSVAL(0);
1755 #else
1756  JS_SET_RVAL(context,vp,JSVAL_ZERO);
1757 #endif
1758  } else {
1759  printf( "\nIncorrect argument format for setDescription(%s).\n", _c_args);
1760  return JS_FALSE;
1761  }
1762  return JS_TRUE;
1763 }
1764 
1765 
1766 JSBool
1767 #if JS_VERSION < 185
1768 VrmlBrowserCreateVrmlFromString(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
1769  char *_c_format = "s";
1770 #else
1771 VrmlBrowserCreateVrmlFromString(JSContext *context, uintN argc, jsval *vp) {
1772  JSObject *obj = JS_THIS_OBJECT(context,vp);
1773  jsval *argv = JS_ARGV(context,vp);
1774  jsval _my_rval;
1775  jsval *rval = &_my_rval;
1776  char *_c_format = "S";
1777  JSString *js_c;
1778 #endif
1779  char *_c, *_c_args = "SFString vrmlSyntax";
1780 
1781  /* for the return of the nodes */
1782  struct X3D_Group *retGroup;
1783  char *xstr;
1784  char *tmpstr;
1785  char *separator;
1786  int ra;
1787  int count;
1788  int wantedsize;
1789  int MallocdSize;
1790  ttglobal tg = gglobal();
1791  struct VRMLParser *globalParser = (struct VRMLParser *)tg->CParse.globalParser;
1792 
1793  UNUSED(ra); //compiler warning mitigation
1794 
1795  /* make this a default value */
1796  *rval = INT_TO_JSVAL(0);
1797 
1798  if (argc == 1 &&
1799 #if JS_VERSION < 185
1800  JS_ConvertArguments(context, argc, argv, _c_format, &_c)) {
1801 #else
1802  JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
1803  _c = JS_EncodeString(context,js_c);
1804 #endif
1805  #ifdef JSVERBOSE
1806  printf("VrmlBrowserCreateVrmlFromString: obj = %u, str = \"%s\"\n",
1807  obj, _c);
1808  #endif
1809 
1810  /* do the call to make the VRML code - create a new browser just for this string */
1811  gglobal()->ProdCon.savedParser = (void *)globalParser; globalParser = NULL;
1812  retGroup = createNewX3DNode0(NODE_Group); //don't register
1813  ra = EAI_CreateVrml("String",_c,X3D_NODE(rootNode()),retGroup);
1814  globalParser = (struct VRMLParser*)gglobal()->ProdCon.savedParser; /* restore it */
1815 
1816 
1817  /* and, make a string that we can use to create the javascript object */
1818  MallocdSize = 200;
1819  xstr = MALLOC (char *, MallocdSize);
1820  strcpy (xstr,"new MFNode(");
1821  separator = " ";
1822  for (count=0; count<retGroup->children.n; count ++) {
1823  tmpstr = MALLOC(char *, strlen(_c) + 100);
1824  sprintf (tmpstr,"%s new SFNode('%s','%p')",separator, _c, (void*) retGroup->children.p[count]);
1825  // +1 to account for the ")" being added later ...
1826  wantedsize = (int) (strlen(tmpstr) + strlen(xstr) + 1);
1827  // sometimes wantedsize is borderline so alloc some more if it's equal
1828  if (wantedsize >= MallocdSize) {
1829  MallocdSize = wantedsize +200;
1830  xstr = REALLOC (xstr,MallocdSize);
1831  }
1832 
1833 
1834  strncat (xstr,tmpstr,strlen(tmpstr));
1835  FREE_IF_NZ (tmpstr);
1836  separator = ", ";
1837  }
1838  strcat (xstr,")");
1839  //markForDispose(X3D_NODE(retGroup),FALSE); //change in Nov 2014 does FREE_IF_NZ
1840 
1841 #if JS_VERSION >= 185
1842  JS_free(context,_c);
1843 #endif
1844 
1845  #ifdef JSVERBOSE
1846  printf ("running runscript on :%s:\n",xstr);
1847  #endif
1848 
1849  /* create this value NOTE: rval is set here. */
1850  jsrrunScript(context, obj, xstr, rval);
1851  FREE_IF_NZ (xstr);
1852 
1853  } else {
1854  printf("\nIncorrect argument format for createVrmlFromString(%s).\n", _c_args);
1855  return JS_FALSE;
1856  }
1857 
1858  /* save this value, in case we need it */
1859 #if JS_VERSION < 185
1860  tg->jsVRMLBrowser.JSCreate_global_return_val = *rval;
1861 #else
1862  JS_SET_RVAL(context,vp,*rval);
1863 #endif
1864  return JS_TRUE;
1865 }
1866 
1867 JSBool
1868 #if JS_VERSION < 185
1869 VrmlBrowserCreateX3DFromString(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
1870  char *_c_format = "s";
1871 #else
1872 VrmlBrowserCreateX3DFromString(JSContext *context, uintN argc, jsval *vp) {
1873  JSObject *obj = JS_THIS_OBJECT(context,vp);
1874  jsval *argv = JS_ARGV(context,vp);
1875  jsval _my_rval;
1876  jsval *rval = &_my_rval;
1877  char *_c_format = "S";
1878  JSString *js_c;
1879 #endif
1880  char *_c, *_c_args = "SFString x3dSyntax"; //x3d
1881 
1882  /* for the return of the nodes */
1883  struct X3D_Group *retGroup;
1884  char *xstr;
1885  char *tmpstr;
1886  char *separator;
1887  int ra;
1888  int count;
1889  int wantedsize;
1890  int MallocdSize;
1891  //ttglobal tg = gglobal();
1892  //struct VRMLParser *globalParser = (struct VRMLParser *)tg->CParse.globalParser;
1893 
1894  UNUSED(ra); //compiler warning mitigation
1895 
1896  /* make this a default value */
1897  *rval = INT_TO_JSVAL(0);
1898 
1899  if (argc == 1 &&
1900 #if JS_VERSION < 185
1901  JS_ConvertArguments(context, argc, argv, _c_format, &_c)) {
1902 #else
1903  JS_ConvertArguments(context, argc, argv, _c_format, &js_c)) {
1904  _c = JS_EncodeString(context,js_c);
1905 #endif
1906  #ifdef JSVERBOSE
1907  printf("VrmlBrowserCreateVrmlFromString: obj = %u, str = \"%s\"\n",
1908  obj, _c);
1909  #endif
1910 
1911  /* do the call to make the VRML code - create a new browser just for this string */
1912  //gglobal()->ProdCon.savedParser = (void *)globalParser; globalParser = NULL;
1913  retGroup = createNewX3DNode(NODE_Group);
1914  ra = EAI_CreateX3d("String",_c,X3D_NODE(retGroup),retGroup);
1915  //globalParser = (struct VRMLParser*)gglobal()->ProdCon.savedParser; /* restore it */
1916 
1917 
1918  /* and, make a string that we can use to create the javascript object */
1919  MallocdSize = 200;
1920  xstr = MALLOC (char *, MallocdSize);
1921  strcpy (xstr,"new MFNode(");
1922  separator = " ";
1923  for (count=0; count<retGroup->children.n; count ++) {
1924  tmpstr = MALLOC(char *, strlen(_c) + 100);
1925  sprintf (tmpstr,"%s new SFNode('%s','%p')",separator, _c, (void*) retGroup->children.p[count]);
1926  wantedsize = (int) (strlen(tmpstr) + strlen(xstr));
1927  if (wantedsize > MallocdSize) {
1928  MallocdSize = wantedsize +200;
1929  xstr = REALLOC (xstr,MallocdSize);
1930  }
1931 
1932 
1933  strncat (xstr,tmpstr,strlen(tmpstr));
1934  FREE_IF_NZ (tmpstr);
1935  separator = ", ";
1936  }
1937  strcat (xstr,")");
1938  markForDispose(X3D_NODE(retGroup),FALSE);
1939 
1940 #if JS_VERSION >= 185
1941  JS_free(context,_c);
1942 #endif
1943 
1944  #ifdef JSVERBOSE
1945  printf ("running runscript on :%s:\n",xstr);
1946  #endif
1947 
1948  /* create this value NOTE: rval is set here. */
1949  jsrrunScript(context, obj, xstr, rval);
1950  FREE_IF_NZ (xstr);
1951 
1952  } else {
1953  printf("\nIncorrect argument format for createVrmlFromString(%s).\n", _c_args);
1954  return JS_FALSE;
1955  }
1956 
1957  /* save this value, in case we need it */
1958 #if JS_VERSION < 185
1959  *(jsval*)(gglobal()->jsVRMLBrowser.JSCreate_global_return_val) = *rval;
1960 #else
1961  JS_SET_RVAL(context,vp,*rval);
1962 #endif
1963  return JS_TRUE;
1964 }
1965 
1966 
1967 JSBool
1968 #if JS_VERSION < 185
1969 VrmlBrowserCreateVrmlFromURL(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
1970 #else
1971 VrmlBrowserCreateVrmlFromURL(JSContext *context, uintN argc, jsval *vp) {
1972  jsval *argv = JS_ARGV(context,vp);
1973  jsval _my_rval;
1974  jsval *rval = &_my_rval;
1975 #endif
1976  JSString *_str[2];
1977  JSClass *_cls[2];
1978  SFNodeNative *oldPtr;
1979  char *fieldStr,
1980  *_costr0;
1981  struct X3D_Node *myptr;
1982  #define myFileSizeLimit 4000
1983 
1984 /* DJ Tue May 4 21:25:15 BST 2010 Old stuff, no longer applicable
1985  int count;
1986  int offset;
1987  int fromtype;
1988  int xxx;
1989  int myField;
1990  char *address;
1991  struct X3D_Group *subtree;
1992 */
1993  resource_item_t *res = NULL;
1994  int fieldInt;
1995  int offs;
1996  int type;
1997  int accessType;
1998  struct Multi_String url;
1999 
2000 
2001  #ifdef JSVERBOSE
2002  printf ("JS start of createVrmlFromURL\n");
2003  #endif
2004 
2005  /* rval is always zero, so lets just set it */
2006 #if JS_VERSION < 185
2007  *rval = INT_TO_JSVAL(0);
2008 #else
2009  *rval = JSVAL_ZERO;
2010 #endif
2011 
2012  /* first parameter - expect a MFString Object here */
2013  if (JSVAL_IS_OBJECT(argv[0])) {
2014  if ((_cls[0] = JS_GET_CLASS(context, JSVAL_TO_OBJECT(argv[0]))) == NULL) {
2015  printf( "JS_GetClass failed for arg 0 in VrmlBrowserLoadURL.\n");
2016  return JS_FALSE;
2017  }
2018  } else {
2019  printf ("VrmlBrowserCreateVrmlFromURL - expect first parameter to be an object\n");
2020  return JS_FALSE;
2021  }
2022 
2023  /* second parameter - expect a SFNode Object here */
2024  if (JSVAL_IS_OBJECT(argv[1])) {
2025  if ((_cls[1] = JS_GET_CLASS(context, JSVAL_TO_OBJECT(argv[1]))) == NULL) {
2026  printf( "JS_GetClass failed for arg 1 in VrmlBrowserLoadURL.\n");
2027  return JS_FALSE;
2028  }
2029  } else {
2030  printf ("VrmlBrowserCreateVrmlFromURL - expect first parameter to be an object\n");
2031  return JS_FALSE;
2032  }
2033 
2034  #ifdef JSVERBOSE
2035  printf ("JS createVrml - step 2\n");
2036  printf ("JS create - we should havve a MFString and SFNode, have :%s: :%s:\n",(_cls[0])->name, (_cls[1])->name);
2037  #endif
2038 
2039  /* make sure these 2 objects are really MFString and SFNode */
2040  if (memcmp("MFString", (_cls[0])->name, strlen((_cls[0])->name)) != 0 &&
2041  memcmp("SFNode", (_cls[1])->name, strlen((_cls[1])->name)) != 0) {
2042  printf( "Incorrect arguments in VrmlBrowserLoadURL.\n");
2043  return JS_FALSE;
2044  }
2045 
2046  /* third parameter should be a string */
2047  if (JSVAL_IS_STRING(argv[2])) {
2048  _str[1] = JSVAL_TO_STRING(argv[2]);
2049 #if JS_VERSION < 185
2050  fieldStr = JS_GetStringBytes(_str[1]);
2051 #else
2052  fieldStr = JS_EncodeString(context,_str[1]);
2053 #endif
2054  #ifdef JSVERBOSE
2055  printf ("field string is :%s:\n",fieldStr);
2056  #endif
2057  } else {
2058  printf ("Expected a string in createVrmlFromURL\n");
2059  return JS_FALSE;
2060  }
2061 
2062  #ifdef JSVERBOSE
2063  printf ("passed object type tests\n");
2064  #endif
2065 
2066  /* get the URL listing as a string */
2067  _str[0] = JS_ValueToString(context, argv[0]);
2068 #if JS_VERSION < 185
2069  _costr0 = JS_GetStringBytes(_str[0]);
2070 #else
2071  _costr0 = JS_EncodeString(context,_str[0]);
2072 #endif
2073 
2074 
2075  #ifdef JSVERBOSE
2076  printf ("URL string is %s\n",_costr0);
2077  #endif
2078 
2079 
2080  /* get a pointer to the SFNode structure, in order to properly place the new string */
2081  if ((oldPtr = (SFNodeNative *)JS_GetPrivate(context, JSVAL_TO_OBJECT(argv[1]))) == NULL) {
2082  printf( "JS_GetPrivate failed in VrmlBrowserLoadURL for SFNode parameter.\n");
2083 #if JS_VERSION >= 185
2084  JS_free(context,_costr0);
2085  JS_free(context,fieldStr);
2086 #endif
2087  return JS_FALSE;
2088  }
2089  myptr = X3D_NODE(oldPtr->handle);
2090  if (myptr == NULL) {
2091  printf ("CreateVrmlFromURL, internal error - SFNodeNative memory pointer is NULL\n");
2092 #if JS_VERSION >= 185
2093  JS_free(context,_costr0);
2094  JS_free(context,fieldStr);
2095 #endif
2096  return JS_FALSE;
2097  }
2098 
2099 
2100  #ifdef JSVERBOSE
2101  printf ("SFNode handle %d, old X3DString %s\n",oldPtr->handle, oldPtr->X3DString);
2102  printf ("myptr %d\n",myptr);
2103  printf ("points to a %s\n",stringNodeType(myptr->_nodeType));
2104  #endif
2105 
2106 
2107  /* bounds checks */
2108  if (sizeof (_costr0) > (myFileSizeLimit-200)) {
2109  printf ("VrmlBrowserCreateVrmlFromURL, url too long...\n");
2110 #if JS_VERSION >= 185
2111  JS_free(context,_costr0);
2112  JS_free(context,fieldStr);
2113 #endif
2114  return JS_FALSE;
2115  }
2116 
2117  /* ok - here we have:
2118  _costr0 : the url string array; eg: [ "vrml.wrl" ]
2119  opldPtr : pointer to a SFNode, with oldPtr->handle as C memory location.
2120  fielsStr : the field to send this to, eg: addChildren
2121  */
2122 
2123  url.n = 0;
2124  url.p = NULL;
2125 
2126  /* parse the string, put it into the "url" struct defined here */
2127  Parser_scanStringValueToMem(X3D_NODE(&url),0,FIELDTYPE_MFString, _costr0, FALSE);
2128 
2129  /* find a file name that exists. If not, return JS_FALSE */
2130  res = resource_create_multi(&url);
2131  res->whereToPlaceData = myptr;
2132 
2133 
2134  /* lets see if this node has a routed field fromTo = 0 = from node, anything else = to node */
2135  fieldInt = findRoutedFieldInFIELDNAMES (myptr, fieldStr, TRUE);
2136 
2137  if (fieldInt >=0) {
2138  findFieldInOFFSETS(myptr->_nodeType, fieldInt, &offs, &type, &accessType);
2139  } else {
2140  ConsoleMessage ("Can not find field :%s: in nodeType :%s:",fieldStr,stringNodeType(myptr->_nodeType));
2141 #if JS_VERSION >= 185
2142  JS_free(context,_costr0);
2143  JS_free(context,fieldStr);
2144 #endif
2145  return JS_FALSE;
2146  }
2147 
2148  /* printf ("type of field %s, accessType %s\n",stringFieldtypeType(type),stringKeywordType(accessType)); */
2149  res->offsetFromWhereToPlaceData = offs;
2150  parser_process_res_VRML_X3D(res);
2151  //send_resource_to_parser(res);
2152  //resource_wait(res);
2153  //
2154  //if (res->status == ress_parsed) {
2155  // /* Cool :) */
2156  //}
2157 
2158  MARK_EVENT(myptr,offs);
2159 #if JS_VERSION >= 185
2160  JS_SET_RVAL(context,vp,*rval);
2161  JS_free(context,fieldStr);
2162  JS_free(context,_costr0);
2163 #endif
2164  return JS_TRUE;
2165 }
2166 
2167 JSBool
2168 #if JS_VERSION < 185
2169 VrmlBrowserAddRoute(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
2170  jsval _rval = INT_TO_JSVAL(0);
2171 #else
2172 VrmlBrowserAddRoute(JSContext *context, uintN argc, jsval *vp) {
2173  JSObject *obj = JS_THIS_OBJECT(context,vp);
2174  jsval *argv = JS_ARGV(context,vp);
2175 #endif
2176  if (!doVRMLRoute(context, obj, argc, argv, "addRoute")) {
2177  printf( "doVRMLRoute failed in VrmlBrowserAddRoute.\n");
2178  return JS_FALSE;
2179  }
2180 #if JS_VERSION < 185
2181  *rval = _rval;
2182 #else
2183  JS_SET_RVAL(context,vp,JSVAL_ZERO);
2184 #endif
2185  return JS_TRUE;
2186 }
2187 
2188 JSBool
2189 #if JS_VERSION < 185
2190 VrmlBrowserPrint(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
2191  jsval _rval = INT_TO_JSVAL(0);
2192 #else
2193 VrmlBrowserPrint(JSContext *context, uintN argc, jsval *vp) {
2194  JSObject *obj = JS_THIS_OBJECT(context,vp);
2195  jsval *argv = JS_ARGV(context,vp);
2196 #endif
2197  unsigned int count;
2198  JSString *_str;
2199  char *_id_c;
2200 
2201  UNUSED (context); UNUSED(obj);
2202  /* printf ("FreeWRL:javascript: "); */
2203  for (count=0; count < argc; count++) {
2204  if (JSVAL_IS_STRING(argv[count])) {
2205  _str = JSVAL_TO_STRING(argv[count]);
2206 #if JS_VERSION < 185
2207  _id_c = JS_GetStringBytes(_str);
2208 #else
2209  _id_c = JS_EncodeString(context,_str);
2210 #endif
2211  // OLD_IPHONE_AQUA #if defined(AQUA) || defined(_MSC_VER)
2212  #if defined(_MSC_VER)
2213  ConsoleMessage(_id_c); /* statusbar hud */
2214  gglobal()->ConsoleMessage.consMsgCount = 0; /* reset the "Maximum" count */
2215  #else
2216  #ifdef HAVE_NOTOOLKIT
2217  printf ("%s", _id_c);
2218  #else
2219  printf ("%s\n", _id_c);
2220  ConsoleMessage(_id_c); /* statusbar hud */
2221  gglobal()->ConsoleMessage.consMsgCount = 0; /* reset the "Maximum" count */
2222  #endif
2223  #endif
2224 #if JS_VERSION >= 185
2225  JS_free(context,_id_c);
2226 #endif
2227  } else {
2228  /* printf ("unknown arg type %d\n",count); */
2229  }
2230  }
2231  /* the \n should be done with println below, or in javascript print("\n");
2232  except web3d V3 specs don't have Browser.println so print will do \n like the old days*/
2233  // OLD_IPHONE_AQUA #if defined(AQUA) || defined(_MSC_VER)
2234  #if defined(_MSC_VER)
2235  ConsoleMessage("\n"); /* statusbar hud */
2236  gglobal()->ConsoleMessage.consMsgCount = 0; /* reset the "Maximum" count */
2237  #elif !defined(_MSC_VER)
2238  #ifdef HAVE_NOTOOLKIT
2239  printf ("\n");
2240  #endif
2241  #endif
2242 #if JS_VERSION < 185
2243  *rval = _rval;
2244 #else
2245  JS_SET_RVAL(context,vp,JSVAL_ZERO);
2246 #endif
2247  return JS_TRUE;
2248 }
2249 
2250 JSBool
2251 #if JS_VERSION < 185
2252 VrmlBrowserPrintln(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
2253  VrmlBrowserPrint(context,obj,argc,argv,rval);
2254 #else
2255 VrmlBrowserPrintln(JSContext *context, uintN argc, jsval *vp) {
2256  /* note, vp holds rval, since it is set in here we should be good */
2257  VrmlBrowserPrint(context,argc,vp);
2258 #endif
2259  // OLD_IPHONE_AQUA #if defined(AQUA) || defined(_MSC_VER)
2260  #if defined(_MSC_VER)
2261  //ConsoleMessage("\n"); /* statusbar hud */
2262  gglobal()->ConsoleMessage.consMsgCount = 0; /* reset the "Maximum" count */
2263  #else
2264  #ifdef HAVE_NOTOOLKIT
2265  printf ("\n");
2266  #endif
2267  #endif
2268  return JS_TRUE;
2269 }
2270 
2271 JSBool
2272 #if JS_VERSION < 185
2273 VrmlBrowserDeleteRoute(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
2274  jsval _rval = INT_TO_JSVAL(0);
2275 #else
2276 VrmlBrowserDeleteRoute(JSContext *context, uintN argc, jsval *vp) {
2277  JSObject *obj = JS_THIS_OBJECT(context,vp);
2278  jsval *argv = JS_ARGV(context,vp);
2279 #endif
2280  if (!doVRMLRoute(context, obj, argc, argv, "deleteRoute")) {
2281  printf( "doVRMLRoute failed in VrmlBrowserDeleteRoute.\n");
2282  return JS_FALSE;
2283  }
2284 #if JS_VERSION < 185
2285  *rval = _rval;
2286 #else
2287  JS_SET_RVAL(context,vp,JSVAL_ZERO);
2288 #endif
2289  return JS_TRUE;
2290 }
2291 
2292 /****************************************************************************************/
2293 
2294 
2295 /****************************************************************************************************/
2296 
2297 /* internal to add/remove a ROUTE */
2298 static JSBool doVRMLRoute(JSContext *context, JSObject *obj, uintN argc, jsval *argv, const char *callingFunc) {
2299  JSObject *fromNodeObj, *toNodeObj;
2300  SFNodeNative *fromNative, *toNative;
2301  JSClass *_cls[2];
2302  char
2303  *fromFieldString, *toFieldString,
2304  *_c_args =
2305  "SFNode fromNode, SFString fromEventOut, SFNode toNode, SFString toEventIn",
2306 #if JS_VERSION < 185
2307  *_c_format = "o s o s";
2308 #else
2309  *_c_format = "oSoS";
2310  JSString *fromFieldStringJS, *toFieldStringJS;
2311 #endif
2312  struct X3D_Node *fromNode;
2313  struct X3D_Node *toNode;
2314  int fromOfs, toOfs, len;
2315  int fromtype, totype;
2316  int xxx;
2317  int myField;
2318 
2319  /* first, are there 4 arguments? */
2320  if (argc != 4) {
2321  printf ("Problem with script - add/delete route command needs 4 parameters\n");
2322  return JS_FALSE;
2323  }
2324 
2325  /* get the arguments, and ensure that they are obj, string, obj, string */
2326  if (JS_ConvertArguments(context, argc, argv, _c_format,
2327 #if JS_VERSION < 185
2328  &fromNodeObj, &fromFieldString, &toNodeObj, &toFieldString)) {
2329 #else
2330  &fromNodeObj, &fromFieldStringJS, &toNodeObj, &toFieldStringJS)) {
2331  fromFieldString = JS_EncodeString(context,fromFieldStringJS);
2332  toFieldString = JS_EncodeString(context,toFieldStringJS);
2333 #endif
2334  if ((_cls[0] = JS_GET_CLASS(context, fromNodeObj)) == NULL) {
2335  printf("JS_GetClass failed for arg 0 in doVRMLRoute called from %s.\n",
2336  callingFunc);
2337  return JS_FALSE;
2338  }
2339  if ((_cls[1] = JS_GET_CLASS(context, toNodeObj)) == NULL) {
2340  printf("JS_GetClass failed for arg 2 in doVRMLRoute called from %s.\n",
2341  callingFunc);
2342  return JS_FALSE;
2343  }
2344 
2345  /* make sure these are both SFNodes */
2346  if (memcmp("SFNode", (_cls[0])->name, strlen((_cls[0])->name)) != 0 &&
2347  memcmp("SFNode", (_cls[1])->name, strlen((_cls[1])->name)) != 0) {
2348  printf("\nArguments 0 and 2 must be SFNode in doVRMLRoute called from %s(%s): %s\n",
2349  callingFunc, _c_args, callingFunc);
2350  return JS_FALSE;
2351  }
2352 
2353  /* get the "private" data for these nodes. It will consist of a SFNodeNative structure */
2354  if ((fromNative = (SFNodeNative *)JS_GetPrivate(context, fromNodeObj)) == NULL) {
2355  printf ("problem getting native props\n");
2356  return JS_FALSE;
2357  }
2358  if ((toNative = (SFNodeNative *)JS_GetPrivate(context, toNodeObj)) == NULL) {
2359  printf ("problem getting native props\n");
2360  return JS_FALSE;
2361  }
2362  /* get the "handle" for the actual memory pointer */
2363  fromNode = X3D_NODE(fromNative->handle);
2364  toNode = X3D_NODE(toNative->handle);
2365 
2366  #ifdef JSVERBOSE
2367  printf ("routing from a node of type %s to a node of type %s\n",
2368  stringNodeType(fromNode->_nodeType),
2369  stringNodeType(toNode->_nodeType));
2370  #endif
2371 
2372  /* From field */
2373  /* try finding it, maybe with a "set_" or "changed" removed */
2374  myField = findRoutedFieldInFIELDNAMES(fromNode,fromFieldString,0);
2375  if (myField == -1)
2376  myField = findRoutedFieldInFIELDNAMES(fromNode,fromFieldString,1);
2377 
2378  /* find offsets, etc */
2379  findFieldInOFFSETS(fromNode->_nodeType, myField, &fromOfs, &fromtype, &xxx);
2380 
2381  /* To field */
2382  /* try finding it, maybe with a "set_" or "changed" removed */
2383  myField = findRoutedFieldInFIELDNAMES(toNode,toFieldString,0);
2384  if (myField == -1)
2385  myField = findRoutedFieldInFIELDNAMES(toNode,toFieldString,1);
2386 
2387  /* find offsets, etc */
2388  findFieldInOFFSETS(toNode->_nodeType, myField, &toOfs, &totype, &xxx);
2389 
2390  /* do we have a mismatch here? */
2391  if (fromtype != totype) {
2392  printf ("Javascript routing problem - can not route from %s to %s\n",
2393  stringNodeType(fromNode->_nodeType),
2394  stringNodeType(toNode->_nodeType));
2395  return JS_FALSE;
2396  }
2397 
2398  len = returnRoutingElementLength(totype);
2399 
2400  jsRegisterRoute(fromNode, fromOfs, toNode, toOfs, len,callingFunc);
2401 
2402 #if JS_VERSION >= 185
2403  JS_free(context,fromFieldString);
2404  JS_free(context,toFieldString);
2405 #endif
2406  } else {
2407  printf( "\nIncorrect argument format for %s(%s).\n",
2408  callingFunc, _c_args);
2409  return JS_FALSE;
2410  }
2411 
2412  return JS_TRUE;
2413 }
2414 
2415 //dug9 - first look at x3dbrowser and x3dscene/executionContext
2416 #ifdef X3DBROWSER
2417 /* The Browser's supportedComponents and supportedProfiles are statically defined
2418  in 'bits and pieces' in generatedCode.c and capabilitiesHandler.c and Structs.h.
2419  The Scene/ExecutionContext Profile and Components should be created during parsing
2420  (as of Aug 3, 2013 the parser calls handleProfile() or handleComponent() which
2421  just complains with printfs if freewrl can't handle the scene, and doesn't save them)
2422 
2423  For the browser's supportedComponents and supportedProfiles, we'll have
2424  indexable arrays, and on getting an index, we'll construct a throwaway JS object.
2425 */
2426 
2427 
2428 
2429 
2430 #endif
2431 /*
2432 ComonentInfo{
2433 String name;
2434 Numeric level;
2435 String Title;
2436 String providerUrl;
2437 }
2438 
2439 ComponentInfoArray{
2440 numeric length;
2441 ComponentInfo [integer index];
2442 }
2443 
2444 
2445 ProfileInfo{
2446 String name;
2447 Numeric level;
2448 String Title;
2449 String providerUrl;
2450 ComonentInfoArray components;
2451 }
2452 ProfileInfoArray{
2453 numeric length;
2454 ProfileInfo [integer index];
2455 }
2456 
2457 X3DFieldDefinition{
2458 //properties
2459 String name;
2460 numeric accessType; //e.g.. inputOnly
2461 numeric dataType; //e.g. SFBool
2462 }
2463 
2464 FieldDefinitionArray{
2465 numeric length;
2466 X3DFieldDefinition [integer index];
2467 }
2468 
2469 
2470 ProtoDeclaration{
2471 //properties
2472 String name;
2473 FieldDefinitionArray fields;
2474 Boolean isExternProto;
2475 //functions
2476 SFNode newInstance();
2477 }
2478 
2479 ExternProtoDeclaration : ProtoDeclaration {
2480 //properties
2481 MFString urls;
2482 numeric loadState;
2483 //functions
2484 void loadNow();
2485 }
2486 
2487 ProtoDeclarationArray{
2488 numeric length;
2489 X3DProtoDeclaration [integer index];
2490 }
2491 
2492 ExternProtoDeclarationArray{
2493 numeric length;
2494 X3DExternProtoDeclaration [integer index];
2495 }
2496 
2497 Route{
2498 }
2499 RouteArray{
2500 numeric length;
2501 Route [integer index];
2502 }
2503 
2504 
2505 ExecutionContext{
2506 //properties
2507 String specificationVersion;
2508 String encoding;
2509 ProfileInfo profile;
2510 ComponentInfoArray components;
2511 String worldURL;
2512 MFNode rootNodes; //R + writable except in protoInstance
2513 ProtoDeclarationArray protos; //RW
2514 ExternProtoDeclarationArray externprotos; //RW
2515 RouteArray routes;
2516 //functions
2517 X3DRoute addRoute(SFNode fromNode, String fromReadableField, SFNode toNode, String toWriteableField);
2518 void deleteRoute(X3DRoute route);
2519 SFNode createNode(String x3dsyntax);
2520 SFNode createProto(String x3dsyntax);
2521 SFNode getImportedNode(String defname, String);
2522 void updateImportedNode(String defname, String);
2523 void removeImportedNode(String defname);
2524 SFNode getNamedNode(String defname):
2525 void updateNamedNode(String defname, SFNode);
2526 void removeNamedNode(String defname);
2527 }
2528 
2529 Scene : ExecutionContext{
2530 //properties
2531 String specificationVersion;
2532 //functions
2533 void setMetaData(String name, String value);
2534 String getMetaData(String name);
2535 SFNode getExportedNode(String defname);
2536 void updateExportedNode(String defname, SFNode node);
2537 void removeExportedNode(String defname);
2538 }
2539 
2540 //just createX3DFromString, createX3DFromURL and replaceWorld differ in signature between VRML and X3D browser classes
2541 X3DBrowser{
2542 //properties
2543 String name;
2544 String version;
2545 numeric currentSpeed;
2546 numeric currentFrameRate;
2547 String description; //R/W
2548 CompnentInfoArray supportedComponents;
2549 ProfileInfoArray supportedProfiles;
2550 //functions
2551 X3DScene currentScene; //since X3DScene : X3DExecutionContext, use Scene w/flag
2552 void replaceWorld(X3DScene);
2553 X3DScene createX3DFromString(String x3dsyntax);
2554 X3DScene createX3DFromURL(MFString url, String callbackFunctionName, Object cbContextObject);
2555 void loadURL(MFString url, MFString parameter);
2556 X3DScene importDocument(DOMNode domNodeObject);
2557 void getRenderingProperty(String propertyName);
2558 void print(Object or String);
2559 void println(Object or String);
2560 }
2561 */
2562 
2563 
2564 #endif /* !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK) */