FreeWRL/FreeX3D  3.0.0
JScript.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 
36 #include "../vrml_parser/Structs.h"
37 #include "../main/headers.h"
38 #include "../vrml_parser/CParseGeneral.h"
39 #include "../vrml_parser/CRoutes.h"
40 #include "../main/Snapshot.h"
41 #include "../scenegraph/Collision.h"
42 #include "../scenegraph/quaternion.h"
43 #include "../scenegraph/Viewer.h"
44 #include "../input/EAIHelpers.h"
45 #include "../input/SensInterps.h"
46 #include "../x3d_parser/Bindable.h"
47 
48 #include "JScript.h"
49 #include "CScripts.h"
50 #include "jsUtils.h"
51 #include "jsNative.h"
52 #include "jsVRMLClasses.h"
53 #include "jsVRMLBrowser.h"
54 
55 
56 
57 
58 #ifndef JSCLASS_GLOBAL_FLAGS
59 //spidermonkey < 1.7 doesn't have so define here
60 #define JSCLASS_GLOBAL_FLAGS 0
61 #endif
62 
63 #ifdef JAVASCRIPTVERBOSE
64 int ActualrunScript(int num, char *script, jsval *rval, char *fn, int line);
65 #else
66 int ActualrunScript(int num, char *script, jsval *rval);
67 #endif
68 
69 
70 static JSClass staticGlobalClass = {
71  "global", // char *name
72  JSCLASS_GLOBAL_FLAGS, // uint32 flags
73  JS_PropertyStub, // JSPropertyOp addProperty
74  JS_PropertyStub, // JSPropertyOp delProperty
75  JS_PropertyStub, // JSPropertyOp getProperty
76  JS_StrictPropertyStub, // JSStrictPropertyOp setProperty
77  JS_EnumerateStub, // JSEnumerateOp enumerate
78  globalResolve, // JSResolveOp resolve
79  JS_ConvertStub, // JSConvertOp convert
80  // following are optional and can be NULL
81  JS_FinalizeStub, // JSFinalizeOp finalize
82  NULL, // JSClassInternal reserved
83  NULL, // JSCheckAccessOp checkAccess
84  NULL, // JSNative call
85  NULL, // JSNative construct
86  NULL, // JSXDRObjectOp xdrObject
87  NULL, // JSJasInstanceOp hasInstance
88  NULL // JSTraceOp trace
89 };
90 
91 
92 
93 
94 
95 typedef struct pJScript{
96 
97 
98 
99  JSRuntime *runtime;// = NULL;
100  JSClass globalClass;
101  jsval JSglobal_return_value;
102 
103  int ijunk;
104 }* ppJScript;
105 
106 
107 void *JScript_constructor(){
108  void *v = MALLOCV(sizeof(struct pJScript));
109  memset(v,0,sizeof(struct pJScript));
110  return v;
111 }
112 void JScript_init(struct tJScript *t){
113  //public
114  t->JSglobal_return_val = NULL;
115  //private
116  t->prv = JScript_constructor();
117  {
118  ppJScript p = (ppJScript)t->prv;
119 
120  p->runtime = NULL;
121  memcpy(&p->globalClass,&staticGlobalClass,sizeof(staticGlobalClass));
122  t->JSglobal_return_val = &p->JSglobal_return_value;
123 
124  }
125 }
126 // ppJScript p = (ppJScript)gglobal()->JScript.prv;
127 
128 
129 void js_cleanup_script_context(int counter){
130  //ttglobal tg = gglobal();
131  //ppJScript p = (ppJScript)tg->JScript.prv;
132  //CLEANUP_JAVASCRIPT(p->ScriptControl[counter].cx);
133  CLEANUP_JAVASCRIPT(getScriptControlIndex(counter)->cx);
134 }
135 
136 /********************************************************************
137 
138 process_eventsProcessed()
139 
140 According to the spec, all scripts can have an eventsProcessed
141 function - see section C.4.3 of the spec.
142 
143 ********************************************************************/
144 /* run the script from within C */
145 void process_eventsProcessed() {
146 
147  int counter;
148  jsval retval;
149  struct CRscriptStruct *scriptcontrol;
150  ttglobal tg = gglobal();
151  //ppJScript p = (ppJScript)tg->JScript.prv;
152  for (counter = 0; counter <= tg->CRoutes.max_script_found_and_initialized; counter++) {
153  scriptcontrol = getScriptControlIndex(counter);
154  if(scriptcontrol->thisScriptType != NOSCRIPT ){
155  if (scriptcontrol->eventsProcessed == NULL) {
156 #if defined(JS_THREADSAFE)
157  JS_BeginRequest(scriptcontrol->cx);
158 #endif
159  scriptcontrol->eventsProcessed = (void *)JS_CompileScript(
160  scriptcontrol->cx,
161  scriptcontrol->glob,
162  "eventsProcessed()", strlen ("eventsProcessed()"),
163  "compile eventsProcessed()", 1);
164 #if JS_VERSION >= 185
165  if (!JS_AddObjectRoot(scriptcontrol->cx,(JSSCRIPT**)(&scriptcontrol->eventsProcessed))) {
166  printf ("can not add object root for compiled eventsProcessed() for script %d\n",counter);
167  }
168 #endif
169 #if defined(JS_THREADSAFE)
170  JS_EndRequest(scriptcontrol->cx);
171 #endif
172  }
173 
174 #if defined(JS_THREADSAFE)
175  JS_BeginRequest(scriptcontrol->cx);
176 #endif
177  if (!JS_ExecuteScript( scriptcontrol->cx,
178  scriptcontrol->glob,
179  scriptcontrol->eventsProcessed, &retval)) {
180 #if defined(_MSC_VER)
181  printf ("can not run eventsProcessed() for script %d thread %u\n",counter,(unsigned int)pthread_self().x);
182 #else
183  printf ("can not run eventsProcessed() for script %d thread %p\n",counter,(void *)pthread_self());
184 #endif
185  }
186 #if defined(JS_THREADSAFE)
187  JS_EndRequest(scriptcontrol->cx);
188 #endif
189  }
190 
191  }
192 
193 }
194 
195 
196 
197 
198 void jsClearScriptControlEntries(int num) //struct CRscriptStruct *ScriptControl)
199 {
200  struct CRscriptStruct *ScriptControl;
201  ScriptControl = getScriptControlIndex(num);
202  if (ScriptControl->eventsProcessed != NULL) {
203 #if JS_VERSION >= 185
204  if (ScriptControl->cx != NULL) {
205  JS_RemoveObjectRoot(ScriptControl->cx,(JSSCRIPT**)(&ScriptControl->eventsProcessed));
206  }
207 #endif
208  ScriptControl->eventsProcessed = NULL;
209  }
210 }
211 
212 
213 
214 /* MAX_RUNTIME_BYTES controls when garbage collection takes place. */
215 /* #define MAX_RUNTIME_BYTES 0x1000000 */
216 #define MAX_RUNTIME_BYTES 0x4000000L
217 /* #define MAX_RUNTIME_BYTES 0xC00000L */
218 
219 #define STACK_CHUNK_SIZE 8192
220 
221 static int JSaddGlobalECMANativeProperty(int num, const char *name);
222 static int JSaddGlobalAssignProperty(int num, const char *name, const char *str);
223 
224 /*
225  * Global JS variables (from Brendan Eichs short embedding tutorial):
226  *
227  * JSRuntime - 1 runtime per process
228  * JSContext - 1 CONTEXT per thread
229  * global JSObject - 1 global object per CONTEXT
230  *
231  * struct JSClass {
232  * char *name;
233  * uint32 flags;
234  * Mandatory non-null function pointer members:
235  * JSPropertyOp addProperty;
236  * JSPropertyOp delProperty;
237  * JSPropertyOp getProperty;
238  * JSPropertyOp setProperty;
239  * JSEnumerateOp enumerate;
240  * JSResolveOp resolve;
241  * JSConvertOp convert;
242  * JSFinalizeOp finalize;
243  * Optionally non-null members start here:
244  * JSGetObjectOps getObjectOps;
245  * JSCheckAccessOp checkAccess;
246  * JSNative call;
247  * JSNative construct;
248  * JSXDRObjectOp xdrObject;
249  * JSHasInstanceOp hasInstance;
250  * prword spare[2];
251  * };
252  *
253  * global JSClass - populated by stubs
254  *
255  */
256 
257 static char *DefaultScriptMethods = "function initialize() {}; " \
258  " function shutdown() {}; " \
259  " function eventsProcessed() {}; " \
260  " TRUE=true; FALSE=false; " \
261  " function print(x) {Browser.print(x)}; " \
262  " function println(x) {Browser.println(x)}; " \
263  " function getName() {return Browser.getName()}; "\
264  " function getVersion() {return Browser.getVersion()}; "\
265  " function getCurrentSpeed() {return Browser.getCurrentSpeed()}; "\
266  " function getCurrentFrameRate() {return Browser.getCurrentFrameRate()}; "\
267  " function getWorldURL() {return Browser.getWorldURL()}; "\
268  " function replaceWorld(x) {Browser.replaceWorld(x)}; "\
269  " function loadURL(x,y) {Browser.loadURL(x,y)}; "\
270  " function setDescription(x) {Browser.setDescription(x)}; "\
271  " function createVrmlFromString(x) {Browser.createVrmlFromString(x)}; "\
272  " function createVrmlFromURL(x,y,z) {Browser.createVrmlFromURL(x,y,z)}; "\
273  " function createX3DFromString(x) {Browser.createX3DFromString(x)}; "\
274  " function createX3DFromURL(x,y,z) {Browser.createX3DFromURL(x,y,z)}; "\
275  " function addRoute(a,b,c,d) {Browser.addRoute(a,b,c,d)}; "\
276  " function deleteRoute(a,b,c,d) {Browser.deleteRoute(a,b,c,d)}; "
277  "";
278 
279 /* housekeeping routines */
280 int jsIsRunning(){
281  ppJScript p = (ppJScript)gglobal()->JScript.prv;
282  return p->runtime ? 1 : 0;
283 }
284 void JSDeleteScriptContext(int num){
285  struct CRscriptStruct *ScriptControl;
286  //ppJScript p = (ppJScript)gglobal()->JScript.prv;
287  /* printf ("kill_javascript, context is %p\n",ScriptControl[i].cx); */
288  ScriptControl = getScriptControlIndex(num);
289 #if JS_VERSION >= 185
290  if (ScriptControl->eventsProcessed != NULL) {
291  JS_RemoveObjectRoot(ScriptControl->cx,(JSSCRIPT **)(&ScriptControl->eventsProcessed));
292  }
293 #endif
294  JS_DestroyContextMaybeGC(ScriptControl->cx);
295 }
296 void jsShutdown(){
297  ttglobal tg = gglobal();
298  ppJScript p = (ppJScript)tg->JScript.prv;
299  if(p->runtime)
300  JS_DestroyRuntime(p->runtime);
301  p->runtime = NULL;
302 }
303 //========================
304 
305 
306 
307 
308 
309 
310 /* create the script context for this script. This is called from the thread
311  that handles script calling in the fwl_RenderSceneUpdateScene */
312 void JSCreateScriptContext(int num) {
313  jsval rval;
314  JSContext *_context; /* these are set here */
315  JSObject *_globalObj; /* these are set here */
316  BrowserNative *br; /* these are set here */
317  ppJScript p = (ppJScript)gglobal()->JScript.prv;
318  struct CRscriptStruct *ScriptControl;
319 
320  ScriptControl = getScriptControlIndex(num);
321 
322  /* is this the first time through? */
323  if (p->runtime == NULL) {
324  p->runtime = JS_NewRuntime(MAX_RUNTIME_BYTES);
325  if (!p->runtime) freewrlDie("JS_NewRuntime failed");
326 
327  #ifdef JAVASCRIPTVERBOSE
328  printf("\tJS runtime created,\n");
329  #endif
330  }
331 
332 
333  _context = JS_NewContext(p->runtime, STACK_CHUNK_SIZE);
334  if (!_context) freewrlDie("JS_NewContext failed");
335 
336  #ifdef JAVASCRIPTVERBOSE
337  printf("\tJS context created,\n");
338  #endif
339 
340 #if defined(JS_THREADSAFE)
341  JS_BeginRequest(_context);
342 #endif
343  #if JS_VERSION >= 185
344  if (num == 0) {
345  _globalObj = JS_NewCompartmentAndGlobalObject(_context, &p->globalClass, NULL);
346  } else {
347  struct CRscriptStruct *cs = getScriptControlIndex(0);
348  JS_SetGlobalObject(_context,cs->glob); //ScriptControl[0].glob);
349  _globalObj = JS_NewGlobalObject(_context,&p->globalClass);
350  JS_SetGlobalObject(_context,_globalObj);
351  }
352  #else
353  _globalObj = JS_NewObject(_context, &p->globalClass, NULL, NULL);
354  #endif
355 #if defined(JS_THREADSAFE)
356  JS_EndRequest(_context);
357 #endif
358  if (!_globalObj) freewrlDie("JS_NewObject failed");
359 
360  #ifdef JAVASCRIPTVERBOSE
361  printf("\tJS global object created,\n");
362  #endif
363 
364 
365  /* gets JS standard classes */
366 #if defined(JS_THREADSAFE)
367  JS_BeginRequest(_context);
368 #endif
369  if (!JS_InitStandardClasses(_context, _globalObj))
370 #if defined(JS_THREADSAFE)
371  { JS_EndRequest(_context);
372 #endif
373  freewrlDie("JS_InitStandardClasses failed");
374 #if defined(JS_THREADSAFE)
375  } else {
376  JS_EndRequest(_context);
377  }
378 #endif
379  #ifdef JAVASCRIPTVERBOSE
380  printf("\tJS standard classes initialized,\n");
381  #endif
382 
383  #ifdef JAVASCRIPTVERBOSE
384  reportWarningsOn();
385  #endif
386 
387  JS_SetErrorReporter(_context, errorReporter);
388 
389  #ifdef JAVASCRIPTVERBOSE
390  printf("\tJS error reporter set,\n");
391  #endif
392 
393  br = (BrowserNative *) JS_malloc(_context, sizeof(BrowserNative));
394 
395  /* for this script, here are the necessary data areas */
396  ScriptControl->cx = _context;
397  ScriptControl->glob = _globalObj;
398 
399 
400 #if defined(JS_THREADSAFE)
401  JS_BeginRequest(_context);
402 #endif
403  if (!loadVrmlClasses(_context, _globalObj))
404 #if defined(JS_THREADSAFE)
405  { JS_EndRequest(_context);
406 #endif
407  freewrlDie("loadVrmlClasses failed");
408 #if defined(JS_THREADSAFE)
409  } else {
410  JS_EndRequest(_context);
411  }
412 #endif
413 
414 
415  #ifdef JAVASCRIPTVERBOSE
416  printf("\tVRML classes loaded,\n");
417  #endif
418 
419 #if defined(JS_THREADSAFE)
420  JS_BeginRequest(_context);
421 #endif
422  if (!VrmlBrowserInit(_context, _globalObj, br))
423 #if defined(JS_THREADSAFE)
424  { JS_EndRequest(_context);
425 #endif
426  freewrlDie("VrmlBrowserInit failed");
427 #if defined(JS_THREADSAFE)
428  } else {
429  JS_EndRequest(_context);
430  }
431 #endif
432 
433  #ifdef JAVASCRIPTVERBOSE
434  printf("\tVRML Browser interface loaded,\n");
435  #endif
436 
437 
438  if (!ACTUALRUNSCRIPT(num,DefaultScriptMethods,&rval))
439  cleanupDie(num,"runScript failed in VRML::newJS DefaultScriptMethods");
440 
441  /* send this data over to the routing table functions. */
442  CRoutes_js_new (num, JAVASCRIPT);
443 
444  #ifdef JAVASCRIPTVERBOSE
445  printf("\tVRML browser initialized, thread %u\n",pthread_self());
446  #endif
447 }
448 
449 
450 /* run the script from within C */
451 #ifdef JAVASCRIPTVERBOSE
452 int ActualrunScript(int num, char *script, jsval *rval, char *fn, int line) {
453 #else
454 int ActualrunScript(int num, char *script, jsval *rval) {
455 #endif
456  int len;
457  JSContext *_context;
458  JSObject *_globalObj;
459  struct CRscriptStruct *ScriptControl;
460 
461  ScriptControl = getScriptControlIndex(num);
462 
463  /* get context and global object for this script */
464  _context = (JSContext*)ScriptControl->cx;
465  _globalObj = (JSObject*)ScriptControl->glob;
466 
467  #ifdef JAVASCRIPTVERBOSE
468  printf("ActualrunScript script called at %s:%d num: %d cx %p \"%s\", \n",
469  fn, line, num, _context, script);
470  #endif
471 
472 #if defined(JS_THREADSAFE)
473  JS_BeginRequest(_context);
474 #endif
475  CLEANUP_JAVASCRIPT(_context)
476 #if defined(JS_THREADSAFE)
477  JS_EndRequest(_context);
478 #endif
479 
480  len = (int) strlen(script);
481 #if defined(JS_THREADSAFE)
482  JS_BeginRequest(_context);
483 #endif
484  if (!JS_EvaluateScript(_context, _globalObj, script, len, FNAME_STUB, LINENO_STUB, rval)) {
485  printf ("ActualrunScript - JS_EvaluateScript failed for %s", script);
486  printf ("\n");
487  ConsoleMessage ("ActualrunScript - JS_EvaluateScript failed for %s", script);
488 #if defined(JS_THREADSAFE)
489  JS_EndRequest(_context);
490 #endif
491  return JS_FALSE;
492 #if defined(JS_THREADSAFE)
493  } else {
494  JS_EndRequest(_context);
495 #endif
496  }
497 
498  #ifdef JAVASCRIPTVERBOSE
499  printf ("runscript passed\n");
500  #endif
501 
502  return JS_TRUE;
503 }
504 
505 int jsActualrunScript(int num, char *script) {
506  jsval rval; //discard
507  return ACTUALRUNSCRIPT(num,script,&rval);
508 }
509 
510 /* run the script from within Javascript */
511 int jsrrunScript(JSContext *_context, JSObject *_globalObj, char *script, jsval *rval) {
512 
513  int len;
514 
515  #ifdef JAVASCRIPTVERBOSE
516  printf("jsrrunScript script cx %p \"%s\", \n",
517  _context, script);
518  #endif
519 
520  len = (int) strlen(script);
521 #if defined(JS_THREADSAFE)
522  JS_BeginRequest(_context);
523 #endif
524  if (!JS_EvaluateScript(_context, _globalObj, script, len,
525  FNAME_STUB, LINENO_STUB, rval)) {
526  ConsoleMessage ("jsrunScript - JS_EvaluateScript failed for %s", script);
527 #if defined(JS_THREADSAFE)
528  JS_EndRequest(_context);
529 #endif
530  return JS_FALSE;
531 #if defined(JS_THREADSAFE)
532  } else {
533  JS_EndRequest(_context);
534 #endif
535  }
536 
537  #ifdef JAVASCRIPTVERBOSE
538  printf ("runscript passed\n");
539  #endif
540 
541  return JS_TRUE;
542 }
543 
544 /* FROM VRMLC.pm */
545 void *SFNodeNativeNew()
546 {
547  SFNodeNative *ptr;
548  ptr = MALLOC(SFNodeNative *, sizeof(*ptr));
549 
550  /* printf ("SFNodeNativeNew; string len %d handle_len %d\n",vrmlstring_len,handle_len);*/
551 
552  ptr->handle = 0;
553  ptr->valueChanged = 0;
554  ptr->X3DString = NULL;
555  ptr->fieldsExpanded = FALSE;
556  return ptr;
557 }
558 
559 /* assign this internally to the Javascript engine environment */
560 int SFNodeNativeAssign(void *top, void *fromp)
561 {
562  SFNodeNative *to = (SFNodeNative *)top;
563  SFNodeNative *from = (SFNodeNative *)fromp;
564 
565  /* indicate that this was touched; and copy contents over */
566  to->valueChanged++;
567 
568  if (from != NULL) {
569  to->handle = from->handle;
570  to->X3DString = STRDUP(from->X3DString);
571 
572  #ifdef JAVASCRIPTVERBOSE
573  printf ("SFNodeNativeAssign, copied %p to %p, handle %p, string %s\n", from, to, to->handle, to->X3DString);
574  #endif
575  } else {
576  to->handle = 0;
577  to->X3DString = STRDUP("from a NULL assignment");
578  }
579 
580  return JS_TRUE;
581 }
582 
583 void *SFColorRGBANativeNew()
584 {
585  SFColorRGBANative *ptr;
586  ptr = MALLOC(SFColorRGBANative *, sizeof(*ptr));
587  ptr->valueChanged = 0;
588  return ptr;
589 }
590 
591 void SFColorRGBANativeAssign(void *top, void *fromp)
592 {
594  SFColorRGBANative *from = (SFColorRGBANative *)fromp;
595  to->valueChanged ++;
596  (to->v) = (from->v);
597 }
598 
599 void *SFColorNativeNew()
600 {
601  SFColorNative *ptr;
602  ptr = MALLOC(SFColorNative *, sizeof(*ptr));
603  ptr->valueChanged = 0;
604  return ptr;
605 }
606 
607 void SFColorNativeAssign(void *top, void *fromp)
608 {
609  SFColorNative *to = (SFColorNative *)top;
610  SFColorNative *from = (SFColorNative *)fromp;
611  to->valueChanged++;
612  (to->v) = (from->v);
613 }
614 
615 void *SFImageNativeNew()
616 {
617  SFImageNative *ptr;
618  ptr =MALLOC(SFImageNative *, sizeof(*ptr));
619  ptr->valueChanged = 0;
620  return ptr;
621 }
622 
623 void SFImageNativeAssign(void *top, void *fromp)
624 {
625  SFImageNative *to = (SFImageNative *)top;
626  /* SFImageNative *from = fromp; */
627  UNUSED(fromp);
628 
629  to->valueChanged++;
630 /* (to->v) = (from->v); */
631 }
632 
633 void *SFRotationNativeNew()
634 {
635  SFRotationNative *ptr;
636  ptr = MALLOC(SFRotationNative *, sizeof(*ptr));
637  ptr->valueChanged = 0;
638  return ptr;
639 }
640 
641 void SFRotationNativeAssign(void *top, void *fromp)
642 {
643  SFRotationNative *to = (SFRotationNative *)top;
644  SFRotationNative *from = (SFRotationNative *)fromp;
645  to->valueChanged++;
646  (to->v) = (from->v);
647 }
648 
649 void *SFVec2fNativeNew()
650 {
651  SFVec2fNative *ptr;
652  ptr = MALLOC(SFVec2fNative *, sizeof(*ptr));
653  ptr->valueChanged = 0;
654  return ptr;
655 }
656 
657 void SFVec2fNativeAssign(void *top, void *fromp)
658 {
659  SFVec2fNative *to = (SFVec2fNative *)top;
660  SFVec2fNative *from = (SFVec2fNative *)fromp;
661  to->valueChanged++;
662  (to->v) = (from->v);
663 }
664 
665 void *SFVec3fNativeNew() {
666  SFVec3fNative *ptr;
667  ptr = MALLOC(SFVec3fNative *, sizeof(*ptr));
668  ptr->valueChanged = 0;
669  return ptr;
670 }
671 
672 void SFVec3fNativeAssign(void *top, void *fromp) {
673  SFVec3fNative *to = (SFVec3fNative *)top;
674  SFVec3fNative *from = (SFVec3fNative *)fromp;
675  to->valueChanged++;
676  (to->v) = (from->v);
677 }
678 
679 void *SFVec3dNativeNew() {
680  SFVec3dNative *ptr;
681  ptr = MALLOC(SFVec3dNative *, sizeof(*ptr));
682  ptr->valueChanged = 0;
683  return ptr;
684 }
685 
686 void SFVec3dNativeAssign(void *top, void *fromp) {
687  SFVec3dNative *to = (SFVec3dNative *)top;
688  SFVec3dNative *from = (SFVec3dNative *)fromp;
689  to->valueChanged++;
690  (to->v) = (from->v);
691 }
692 
693 void *SFVec4fNativeNew() {
694  SFVec4fNative *ptr;
695  ptr = MALLOC(SFVec4fNative *, sizeof(*ptr));
696  ptr->valueChanged = 0;
697  return ptr;
698 }
699 
700 void SFVec4fNativeAssign(void *top, void *fromp) {
701  SFVec4fNative *to = (SFVec4fNative *)top;
702  SFVec4fNative *from = (SFVec4fNative *)fromp;
703  to->valueChanged++;
704  (to->v) = (from->v);
705 }
706 
707 void *SFVec4dNativeNew() {
708  SFVec4dNative *ptr;
709  ptr = MALLOC(SFVec4dNative *, sizeof(*ptr));
710  ptr->valueChanged = 0;
711  return ptr;
712 }
713 
714 void SFVec4dNativeAssign(void *top, void *fromp) {
715  SFVec4dNative *to = (SFVec4dNative *)top;
716  SFVec4dNative *from = (SFVec4dNative *)fromp;
717  to->valueChanged++;
718  (to->v) = (from->v);
719 }
720 
721 
722 
723 static char* re_strcat(char *_Dest, char *_Source, int *destLen, int *destDim)
724 {
725  /* strcats, but first checks strlen on source and destination
726  and reallocs if necessary - good when you are doing a lot of strcatting of un-pre-known elements
727  (Q. is there something for this already?)
728  _Dest, _Source - as with strcat(_Dest,_Source)
729  destLen - current cumulative strlen(_Dest)
730  destDim - current malloc/realloc dimension
731  Usage example:
732  dstdim = (rows+1)*(elements*15) + 100; //a guess
733  dstlen = 0;
734  smallfield = MALLOC (char *, dstdim+1); //rows+1)*(elements*15) + 100);
735  smallfield[0] = '\0';
736  ...
737  for(;;)
738  {
739  ...
740  smallfield = re_strcat(smallfield, "new ",&dstlen,&dstdim);
741  ...
742  FREE_IF_NZ(smallfield)
743  */
744  int srclen = (int) strlen(_Source);
745  *destLen = *destLen + srclen;
746  if(*destLen > *destDim -1)
747  {
748  *destDim = *destDim + srclen + 1 + 100;
749  _Dest = REALLOC(_Dest,*destDim);
750  }
751  _Dest = strcat(_Dest,_Source);
752  return _Dest;
753 }
754 /* the fwl_RenderSceneUpdateScene is initializing this field now */
755 /* A new version of InitScriptField which takes "nicer" arguments; currently a
756  * simple and restricted wrapper, but it could replace it soon? */
757 /* Parameters:
758  num: Script number. Starts at 0.
759  kind: One of PKW_initializeOnly PKW_outputOnly PKW_inputOutput PKW_inputOnly
760  type: One of the FIELDTYPE_ defines, eg, FIELDTYPE_MFFloat
761  field: the field name as found in the VRML/X3D file. eg "set_myField"
762 
763 */
764 void InitScriptField(int num, indexT kind, indexT type, const char* field, union anyVrml value) {
765  jsval rval;
766  char *smallfield = NULL;
767  char mynewname[400];
768  char *thisValue;
769  int rows, elements;
770  char *sftype = NULL;
771 
772  int haveMulti;
773  int MFhasECMAtype;
774  int rowCount, eleCount;
775 
776  int tlen;
777  float *FloatPtr;
778  struct X3D_Node **VoidPtr;
779  int *IntPtr;
780  double *DoublePtr;
781  struct Uni_String **SVPtr;
782 
783  float defaultFloat[] = {0.0f,0.0f,0.0f,0.0f};
784  int defaultInt[] = {0,0,0,0};
785  double defaultDouble[] = {0.0, 0.0, 0.0, 0.0};
786  struct Uni_String *sptr[1];
787  struct X3D_Node *defaultVoid[] = {NULL,NULL};
788  struct CRscriptStruct *ScriptControl; //= getScriptControl();
789 
790  #ifdef JAVASCRIPTVERBOSE
791  printf ("calling InitScriptField from thread %u\n",pthread_self());
792  printf ("\nInitScriptField, num %d, kind %s type %s field %s value %d\n", num,PROTOKEYWORDS[kind],FIELDTYPES[type],field,value);
793  #endif
794 
795  if ((kind != PKW_inputOnly) && (kind != PKW_outputOnly) && (kind != PKW_initializeOnly) && (kind != PKW_inputOutput)) {
796  ConsoleMessage ("InitScriptField: invalid kind for script: %d\n",kind);
797  return;
798  }
799 
800  if (type >= FIELDTYPES_COUNT) {
801  ConsoleMessage ("InitScriptField: invalid type for script: %d\n",type);
802  return;
803  }
804 
805  /* first, make a new name up */
806  if (kind == PKW_inputOnly) {
807  sprintf (mynewname,"__eventIn_Value_%s",field);
808  } else strcpy(mynewname,field);
809 
810  /* ok, lets handle the types here */
811  switch (type) {
812  /* ECMA types */
813  case FIELDTYPE_SFBool:
814  case FIELDTYPE_SFFloat:
815  case FIELDTYPE_SFTime:
816  case FIELDTYPE_SFDouble:
817  case FIELDTYPE_SFInt32:
818  case FIELDTYPE_SFString: {
819  /* do not care about eventIns */
820  if (kind != PKW_inputOnly) {
821  JSaddGlobalECMANativeProperty(num, field);
822  if (kind == PKW_initializeOnly || kind == PKW_inputOutput) {
823  if (type == FIELDTYPE_SFString) {
824  tlen = (int) strlen(value.sfstring->strptr) + strlen(field) + 20;
825  } else {
826  tlen = (int) strlen(field) + 400; /* long, in the case of doubles */
827  }
828  smallfield = MALLOC (char *, tlen);
829  smallfield[0] = '\0';
830 
831  switch (type) {
832  case FIELDTYPE_SFFloat: sprintf (smallfield,"%s=%f\n",field,value.sffloat);break;
833  case FIELDTYPE_SFTime: sprintf (smallfield,"%s=%f\n",field,value.sftime);break;
834  case FIELDTYPE_SFDouble: sprintf (smallfield,"%s=%f\n",field,value.sftime);break;
835  case FIELDTYPE_SFInt32: sprintf (smallfield,"%s=%d\n",field,value.sfint32); break;
836  case FIELDTYPE_SFBool:
837  if (value.sfbool == 1) sprintf (smallfield,"%s=true",field);
838  else sprintf (smallfield,"%s=false",field);
839  break;
840  case FIELDTYPE_SFString:
841  sprintf (smallfield,"%s=\"%s\"\n",field,value.sfstring->strptr); break;
842  }
843 
844  if (!ACTUALRUNSCRIPT(num,smallfield,&rval))
845  printf ("huh??? Field initialization script failed %s\n",smallfield);
846  }
847  }
848  break;
849  }
850  /* non ECMA types */
851  default: {
852  /* get an appropriate pointer - we either point to the initialization value
853  in the script header, or we point to some data here that are default values */
854 
855  /* does this MF type have an ECMA type as a single element? */
856  switch (type) {
857  case FIELDTYPE_MFString:
858  case FIELDTYPE_MFTime:
859  case FIELDTYPE_MFBool:
860  case FIELDTYPE_MFInt32:
861  case FIELDTYPE_MFFloat:
862  JSaddGlobalECMANativeProperty(num, field);
863  MFhasECMAtype = TRUE;
864  break;
865  default: {
866  MFhasECMAtype = FALSE;
867  }
868  }
869 
870  elements=0;
871  IntPtr = NULL;
872  FloatPtr = NULL;
873  DoublePtr = NULL;
874  SVPtr = NULL;
875  VoidPtr = NULL;
876  if (kind == PKW_initializeOnly || kind == PKW_inputOutput) {
877  switch (type) {
878  //case FIELDTYPE_SFImage:
879  // VoidPtr = (struct X3D_Node **) (&(value.sfimage)); elements = 1;
880  // break;
881  case FIELDTYPE_SFNode:
882  VoidPtr = (struct X3D_Node **) (&(value.sfnode)); elements = 1;
883  break;
884  case FIELDTYPE_MFColor:
885  FloatPtr = (float *) value.mfcolor.p; elements = value.mfcolor.n;
886  break;
887  case FIELDTYPE_MFColorRGBA:
888  FloatPtr = (float *) value.mfcolorrgba.p; elements = value.mfcolorrgba.n;
889  break;
890  case FIELDTYPE_MFVec2f:
891  FloatPtr = (float *) value.mfvec2f.p; elements = value.mfvec2f.n;
892  break;
893  case FIELDTYPE_MFVec3f:
894  FloatPtr = (float *) value.mfvec3f.p; elements = value.mfvec3f.n;
895  break;
896  case FIELDTYPE_MFRotation:
897  FloatPtr = (float *) value.mfrotation.p; elements = value.mfrotation.n;
898  break;
899  case FIELDTYPE_SFVec2f:
900  FloatPtr = (float *) value.sfvec2f.c; elements = 1;
901  break;
902  case FIELDTYPE_SFColor:
903  FloatPtr = value.sfcolor.c; elements = 1;
904  break;
905  case FIELDTYPE_SFColorRGBA:
906  FloatPtr = value.sfcolorrgba.c; elements = 1;
907  break;
908  case FIELDTYPE_SFRotation:
909  FloatPtr = value.sfrotation.c; elements = 1;
910  break;
911  case FIELDTYPE_SFVec3f:
912  FloatPtr = value.sfvec3f.c; elements =1;
913  break;
914  case FIELDTYPE_SFVec3d:
915  DoublePtr = value.sfvec3d.c; elements =1;
916  break;
917  case FIELDTYPE_MFString:
918  SVPtr = value.mfstring.p; elements = value.mfstring.n;
919  break;
920  case FIELDTYPE_MFTime:
921  DoublePtr = value.mftime.p; elements = value.mftime.n;
922  break;
923  case FIELDTYPE_MFBool:
924  IntPtr = value.mfbool.p; elements = value.mfbool.n;
925  break;
926  case FIELDTYPE_SFImage:
927  case FIELDTYPE_MFInt32:
928  IntPtr = value.mfint32.p; elements = value.mfint32.n;
929  break;
930  case FIELDTYPE_MFNode:
931  VoidPtr = (struct X3D_Node **)(value.mfnode.p); elements = value.mfnode.n;
932  break;
933  case FIELDTYPE_MFFloat:
934  FloatPtr = value.mffloat.p; elements = value.mffloat.n;
935  break;
936  case FIELDTYPE_SFVec4f:
937  FloatPtr = value.sfvec4f.c; elements = 1;
938  break;
939  case FIELDTYPE_SFVec4d:
940  DoublePtr = value.sfvec4d.c; elements = 1;
941  break;
942 
943  default: {
944  printf ("unhandled type, in InitScriptField %d\n",type);
945  return;
946  }
947  }
948 
949  } else {
950  /* make up a default pointer */
951  elements = 1;
952  switch (type) {
953  /* Void types */
954  case FIELDTYPE_SFNode:
955  case FIELDTYPE_MFNode:
956  VoidPtr = (struct X3D_Node **) &defaultVoid;
957  break;
958 
959  /* Float types */
960  case FIELDTYPE_MFColor:
961  case FIELDTYPE_MFColorRGBA:
962  case FIELDTYPE_MFVec2f:
963  case FIELDTYPE_MFVec3f:
964  case FIELDTYPE_MFRotation:
965  case FIELDTYPE_SFVec2f:
966  case FIELDTYPE_SFColor:
967  case FIELDTYPE_SFColorRGBA:
968  case FIELDTYPE_SFRotation:
969  case FIELDTYPE_SFVec3f:
970  case FIELDTYPE_SFVec4f:
971  case FIELDTYPE_MFFloat:
972  FloatPtr = defaultFloat;
973  break;
974 
975  /* Int types */
976  case FIELDTYPE_MFBool:
977  case FIELDTYPE_MFInt32:
978  IntPtr = defaultInt;
979  break;
980 
981  /* String types */
982  case FIELDTYPE_SFString:
983  case FIELDTYPE_MFString:
984  sptr[0] = newASCIIString("");
985  SVPtr = sptr;
986  break;
987 
988  /* SFImage */
989  case FIELDTYPE_SFImage:
990  IntPtr = defaultInt;
991  break;
992 
993  /* Double types */
994  case FIELDTYPE_SFVec2d:
995  case FIELDTYPE_SFVec3d:
996  case FIELDTYPE_MFTime:
997  case FIELDTYPE_SFTime:
998  case FIELDTYPE_SFDouble:
999  case FIELDTYPE_SFVec4d:
1000  DoublePtr = defaultDouble;
1001  break;
1002 
1003  default: {
1004  printf ("unhandled type, in InitScriptField part 2 %d\n",type);
1005  return;
1006  }
1007  }
1008 
1009  }
1010 
1011  rows = returnElementRowSize (type);
1012 
1013  #ifdef JAVASCRIPTVERBOSE
1014  printf ("in fieldSet, we have ElementRowSize %d and individual elements %d\n",rows,elements);
1015  #endif
1016 
1017  /* make this at least as large as required, then add some more on to the end... */
1018  /*
1019  Old Approach
1020  step1: compute using guestimate formulas
1021  step2: malloc
1022  step3: loop through strcat() and hope no overrun
1023  Problem: heap corruption from array overrun - the guestimate has been bad
1024  a few times in 2010 with MFVec2fs and MFStrings with 42 and 47 elements, strings of varying length
1025  example for MFVec2f
1026  'new MFVec2f(new SFVec2f(1234.678910,1234.678910),...)'
1027  each SF 2 numbers each 10 digits plus new type(,), 15 chars =35.
1028  3 x 15 = 45 (or (rows+1)x(elements*15)+100)
1029  old formula falls short:
1030  old formula: smallfield = MALLOC (rows*((elements*15) + 100));
1031  example 47 SFVec2fs
1032  actual bytes: 47 x 35 bytes = 1645 + 13 for the MF = 1658
1033  old formula 2 x ((47*15)+100) = 1610 //thats 48 bytes short and I bomb out
1034  better formula 3 x (47*15) + 100 = 2215
1035  New Approach (July 28, 2010)
1036  step1: compute using guestimate formulas
1037  step2: malloc
1038  step3: loop through and realloc before strcat() if short
1039  */
1040  {
1041  int dstlen, dstdim, tdim;
1042  tdim = 200;
1043  thisValue = MALLOC(char *, tdim+1);
1044  dstdim = (rows+1)*(elements*15) + 100; /* a guess */
1045  dstlen = 0;
1046  smallfield = MALLOC (char *, dstdim+1); //rows+1)*(elements*15) + 100);
1047  /* what is the equivalent SF for this MF?? */
1048  if (type != convertToSFType(type)) haveMulti = TRUE;
1049  else haveMulti = FALSE;
1050 
1051  /* the sftype is the SF form of either the MF or SF */
1052  sftype = STRDUP((char *)FIELDTYPES[convertToSFType(type)]);
1053 
1054  /* SFStrings are Strings */
1055  if (strncmp(sftype,"SFString",8)==0) strcpy (sftype,"String");
1056 
1057 
1058  /* start the string */
1059  smallfield[0] = '\0';
1060 
1061  /* is this an MF variable, with SFs in it? */
1062  if (haveMulti) {
1063  smallfield = re_strcat(smallfield, "new ",&dstlen,&dstdim);
1064  smallfield = re_strcat(smallfield, (char *)FIELDTYPES[type],&dstlen,&dstdim);
1065  smallfield = re_strcat(smallfield, "(",&dstlen,&dstdim);
1066  }
1067 
1068  /* loop through, and put values in */
1069  for (eleCount=0; eleCount<elements; eleCount++) {
1070  /* ECMA native types can just be passed in... */
1071  if (!MFhasECMAtype) {
1072  smallfield = re_strcat(smallfield, "new ",&dstlen,&dstdim);
1073  smallfield = re_strcat(smallfield, sftype,&dstlen,&dstdim);
1074  smallfield = re_strcat(smallfield, "(",&dstlen,&dstdim);
1075  }
1076 
1077  /* go through the SF type; SFints will have 1; SFVec3f's will have 3, etc */
1078  for (rowCount=0; rowCount<rows; rowCount++ ) {
1079  if (IntPtr != NULL) {
1080  sprintf (thisValue,"%d",*IntPtr); IntPtr++;
1081  } else if (FloatPtr != NULL) {
1082  sprintf (thisValue,"%f",*FloatPtr); FloatPtr++;
1083  } else if (DoublePtr != NULL) {
1084  sprintf (thisValue,"%f",*DoublePtr); DoublePtr++;
1085  } else if (SVPtr != NULL) {
1086  sptr[0] = *SVPtr; SVPtr++;
1087  if((int)strlen(sptr[0]->strptr)+2 > tdim-1)
1088  {
1089  tdim = (int) strlen(sptr[0]->strptr) + 1 + 100;
1090  thisValue = REALLOC(thisValue,tdim);
1091  }
1092  sprintf (thisValue,"\"%s\"",sptr[0]->strptr);
1093  } else { /* must be a Void */
1094  /* printf ("sending in a VoidPtr, it is %p\n",VoidPtr[0]);
1095  if (VoidPtr[0] != NULL) {printf ("it is a %s type\n",stringNodeType(X3D_NODE(VoidPtr[0])->_nodeType));} */
1096  sprintf (thisValue,"\"%p\"", VoidPtr[0]); VoidPtr++;
1097  }
1098  smallfield = re_strcat(smallfield, thisValue,&dstlen,&dstdim);
1099  if (rowCount < (rows-1)) smallfield = re_strcat(smallfield,",",&dstlen,&dstdim);
1100  }
1101 
1102  if (!MFhasECMAtype) smallfield = re_strcat(smallfield, ")",&dstlen,&dstdim);
1103  if (eleCount < (elements-1)) smallfield = re_strcat(smallfield,",",&dstlen,&dstdim);
1104 
1105  }
1106 
1107 
1108  if (haveMulti) {
1109  smallfield = re_strcat(smallfield,")",&dstlen,&dstdim);
1110  }
1111  /* printf("dstlen=%d dstdim=%d\n",dstlen,dstdim); */
1112  FREE_IF_NZ (thisValue);
1113  }
1114  /* Warp factor 5, Dr Sulu... */
1115  #ifdef JAVASCRIPTVERBOSE
1116  printf ("JScript, for non-ECMA newname %s, sending :%s:\n",mynewname,smallfield);
1117  #endif
1118 
1119  JSaddGlobalAssignProperty (num,mynewname,smallfield);
1120  }
1121  }
1122 
1123  /* Fields can generate an event, so we allow the touched flag to remain set. eventOuts have just
1124  been initialized, and as such, should not send events, until after they really have been set.
1125  */
1126  if (kind == PKW_outputOnly) {
1127  int fptr;
1128  int touched;
1129 
1130  UNUSED(touched); // compiler warning mitigation
1131 
1132  /* get the number representing this type */
1133  fptr = JSparamIndex (field, FIELDTYPES[type]);
1134 
1135  /* set up global variables so that we can reset the touched flag */
1136  touched = get_valueChanged_flag (fptr, num);
1137 
1138  /* and, reset the touched flag, knowing that we have the variables set properly */
1139  resetScriptTouchedFlag(num, fptr);
1140  }
1141  ScriptControl = getScriptControlIndex(num);
1142 #if defined(JS_THREADSAFE)
1143  JS_BeginRequest(ScriptControl->cx);
1144 #endif
1145  CLEANUP_JAVASCRIPT(ScriptControl->cx)
1146 #if defined(JS_THREADSAFE)
1147  JS_EndRequest(ScriptControl->cx);
1148 #endif
1149 
1150  FREE_IF_NZ (smallfield);
1151  FREE_IF_NZ (sftype);
1152 
1153  #ifdef JAVASCRIPTVERBOSE
1154  printf ("finished InitScriptField\n");
1155  #endif
1156 }
1157 
1158 static int JSaddGlobalECMANativeProperty(int num, const char *name) {
1159  JSContext *_context;
1160  JSObject *_globalObj;
1161  jsval rval = INT_TO_JSVAL(0);
1162  struct CRscriptStruct *ScriptControl; // = getScriptControl();
1163 
1164  ScriptControl = getScriptControlIndex(num);
1165  /* get context and global object for this script */
1166  _context = (JSContext*)ScriptControl->cx;
1167  _globalObj = (JSObject*)ScriptControl->glob;
1168 
1169  #ifdef JAVASCRIPTVERBOSE
1170  printf("addGlobalECMANativeProperty: name \"%s\"\n", name);
1171  #endif
1172 
1173 #if defined(JS_THREADSAFE)
1174  JS_BeginRequest(_context);
1175 #endif
1176 
1177 /* Note, for JS-185+, JSPROP_PERMANENT makes properties non-configurable, which can cause runtime
1178  * errors from the JS engine when said property gets redefined to a function by the script. The
1179  * example file tests/Javascript_tests/MFFloat.wrl had this issue. */
1180 
1181  if (!JS_DefineProperty(_context, _globalObj, name, rval, NULL, setECMANative,
1182 #if JS_VERSION < 185
1183  0 | JSPROP_PERMANENT
1184 #else
1185  0
1186 #endif
1187  )) {
1188  printf("JS_DefineProperty failed for \"%s\" in addGlobalECMANativeProperty.\n", name);
1189 #if defined(JS_THREADSAFE)
1190  JS_EndRequest(_context);
1191 #endif
1192  return JS_FALSE;
1193 #if defined(JS_THREADSAFE)
1194  } else {
1195  JS_EndRequest(_context);
1196 #endif
1197  }
1198 
1199  return JS_TRUE;
1200 }
1201 
1202 static int JSaddGlobalAssignProperty(int num, const char *name, const char *str) {
1203  jsval _rval = INT_TO_JSVAL(0);
1204  JSContext *_context;
1205  JSObject *_globalObj;
1206  struct CRscriptStruct *ScriptControl;
1207 
1208  ScriptControl = getScriptControlIndex(num);
1209 
1210  /* get context and global object for this script */
1211  _context = (JSContext*)ScriptControl->cx;
1212  _globalObj = (JSObject*)ScriptControl->glob;
1213 
1214  #ifdef JAVASCRIPTVERBOSE
1215  printf("addGlobalAssignProperty: cx: %p obj %p name \"%s\", evaluate script \"%s\"\n",
1216  _context, _globalObj, name, str);
1217  #endif
1218 
1219 #if defined(JS_THREADSAFE)
1220  JS_BeginRequest(_context);
1221 #endif
1222  if (!JS_EvaluateScript(_context, _globalObj, str, (int) strlen(str), FNAME_STUB, LINENO_STUB, &_rval)) {
1223  ConsoleMessage ("JSaddGlobalAssignProperty - JS_EvaluateScript failed for %s", str);
1224 #if defined(JS_THREADSAFE)
1225  JS_EndRequest(_context);
1226 #endif
1227  return JS_FALSE;
1228 #if defined(JS_THREADSAFE)
1229  } else {
1230  JS_EndRequest(_context);
1231 #endif
1232  }
1233 #if defined(JS_THREADSAFE)
1234  JS_BeginRequest(_context);
1235 #endif
1236  if (!JS_DefineProperty(_context, _globalObj, name, _rval, getAssignProperty, setAssignProperty, 0 | JSPROP_PERMANENT)) {
1237  printf("JS_DefineProperty failed for \"%s\" in addGlobalAssignProperty.\n", name);
1238 #if defined(JS_THREADSAFE)
1239  JS_EndRequest(_context);
1240 #endif
1241  return JS_FALSE;
1242 #if defined(JS_THREADSAFE)
1243  } else {
1244  JS_EndRequest(_context);
1245 #endif
1246  }
1247  return JS_TRUE;
1248 }
1249 
1250 /* defines for getting touched flags and exact Javascript pointers */
1251 
1252 /* ... make a #define to handle JS requests that can easily be substituted into these other #defines */
1253 #if defined(JS_THREADSAFE)
1254 # define JSBEGINREQUEST_SUBSTITUTION(mycx) JS_BeginRequest(mycx);
1255 # define JSENDREQUEST_SUBSTITUTION(mycx) JS_EndRequest(mycx);
1256 #else
1257 # define JSBEGINREQUEST_SUBSTITUTION(mycx) /* */
1258 # define JSENDREQUEST_SUBSTITUTION(mycx) /* */
1259 #endif
1260 
1261 /****************************** ECMA types ******************************************/
1262 /* where we have a Native structure to go along with it */
1263 #define GETJSPTR_TYPE_A(thistype) \
1264  case FIELDTYPE_##thistype: { \
1265  thistype##Native *ptr; \
1266  /* printf ("getting private data in GETJSPTR for %p \n",JSglobal_return_val); */ \
1267  if ((ptr = (thistype##Native *)JS_GetPrivate(cx, JSVAL_TO_OBJECT(*(jsval *)(tg->JScript.JSglobal_return_val)))) == NULL) { \
1268  printf( "JS_GetPrivate failed in get_valueChanged_flag\n"); \
1269  JSENDREQUEST_SUBSTITUTION(cx) \
1270  return JS_FALSE; \
1271  } \
1272  /* if (ptr->valueChanged > 0) printf ("private is %d valueChanged %d\n",ptr,ptr->valueChanged); */ \
1273  tg->CRoutes.JSSFpointer = (void *)ptr; /* save this for quick extraction of values */ \
1274  touched = ptr->valueChanged; \
1275  break; \
1276  }
1277 
1278 #define RESET_TOUCHED_TYPE_A(thistype) \
1279  case FIELDTYPE_##thistype: { \
1280  ((thistype##Native *)tg->CRoutes.JSSFpointer)->valueChanged = 0; \
1281  break; \
1282  }
1283 
1284 #define GETJSPTR_TYPE_MF_A(thisMFtype,thisSFtype) \
1285  case FIELDTYPE_##thisMFtype: { \
1286  thisSFtype##Native *ptr; \
1287  jsval mainElement; \
1288  int len; \
1289  int i; \
1290  if (!JS_GetProperty(cx, JSVAL_TO_OBJECT(*(jsval *)(tg->JScript.JSglobal_return_val)), "length", &mainElement)) { \
1291  printf ("JS_GetProperty failed for \"length\" in get_valueChanged_flag\n"); \
1292  JSENDREQUEST_SUBSTITUTION(cx) \
1293  return FALSE; \
1294  } \
1295  len = JSVAL_TO_INT(mainElement); \
1296  /* go through each element of the main array. */ \
1297  for (i = 0; i < len; i++) { \
1298  if (!JS_GetElement(cx, JSVAL_TO_OBJECT(*(jsval*)(tg->JScript.JSglobal_return_val)), i, &mainElement)) { \
1299  printf ("JS_GetElement failed for %d in get_valueChanged_flag\n",i); \
1300  JSENDREQUEST_SUBSTITUTION(cx) \
1301  return FALSE; \
1302  } \
1303  if ((ptr = (thisSFtype##Native *)JS_GetPrivate(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) { \
1304  printf( "JS_GetPrivate failed for obj in setField_javascriptEventOut.\n"); \
1305  JSENDREQUEST_SUBSTITUTION(cx) \
1306  return FALSE; \
1307  } \
1308  if (ptr->valueChanged > 0) touched = TRUE; /* did this element change? */ \
1309  /* printf ("touched flag for element %d is %d\n",i,ptr->touched); */ \
1310  } \
1311  break; \
1312  }
1313 
1314 #define RESET_TOUCHED_TYPE_MF_A(thisMFtype,thisSFtype) \
1315  case FIELDTYPE_##thisMFtype: { \
1316  thisSFtype##Native *ptr; \
1317  jsval mainElement; \
1318  int len; \
1319  int i; \
1320  JSContext *cx; \
1321  cx = scriptcontrol->cx; \
1322  JSBEGINREQUEST_SUBSTITUTION(cx) \
1323  if (!JS_GetProperty(cx, JSVAL_TO_OBJECT(*(jsval*)(tg->JScript.JSglobal_return_val)), "length", &mainElement)) { \
1324  printf ("JS_GetProperty failed for \"length\" in get_valueChanged_flag\n"); \
1325  JSENDREQUEST_SUBSTITUTION(cx) \
1326  break; \
1327  } \
1328  len = JSVAL_TO_INT(mainElement); \
1329  /* go through each element of the main array. */ \
1330  for (i = 0; i < len; i++) { \
1331  if (!JS_GetElement(cx, JSVAL_TO_OBJECT(*(jsval*)(tg->JScript.JSglobal_return_val)), i, &mainElement)) { \
1332  printf ("JS_GetElement failed for %d in get_valueChanged_flag\n",i); \
1333  JSENDREQUEST_SUBSTITUTION(cx) \
1334  break; \
1335  } \
1336  if ((ptr = (thisSFtype##Native *)JS_GetPrivate(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) { \
1337  printf( "JS_GetPrivate failed for obj in setField_javascriptEventOut.\n"); \
1338  JSENDREQUEST_SUBSTITUTION(cx) \
1339  break; \
1340  } \
1341  ptr->valueChanged = 0; \
1342  } \
1343  JSENDREQUEST_SUBSTITUTION(cx) \
1344  break; \
1345  }
1346 
1347 /****************************** ECMA types ******************************************/
1348 
1349 #ifdef OLDCODE
1350 OLDCODE /* "Bool" might be already declared - we DO NOT want it to be declared as an "int" */
1351 OLDCODE #define savedBool Bool
1352 OLDCODE #ifdef Bool
1353 OLDCODE #undef Bool
1354 OLDCODE #endif
1355 #endif //OLDCODE
1356 
1357 /* NOTE - BeginRequest is already called prior to any GET_* defines */
1358 
1359 #define GET_ECMA_TOUCHED(thistype) \
1360  case FIELDTYPE_SF##thistype: { \
1361  touched = findNameInECMATable( scriptcontrol->cx,fullname);\
1362  break;\
1363  }
1364 
1365 #define GET_ECMA_MF_TOUCHED(thistype) \
1366  case FIELDTYPE_MF##thistype: {\
1367  jsval mainElement; \
1368  /* printf ("GET_ECMA_MF_TOUCHED called on %d\n",JSglobal_return_val); */ \
1369  if (!JS_GetProperty(cx, JSVAL_TO_OBJECT(*(jsval*)(tg->JScript.JSglobal_return_val)), "MF_ECMA_has_changed", &mainElement)) { \
1370  printf ("JS_GetProperty failed for \"MF_ECMA_HAS_changed\" in get_valueChanged_flag\n"); \
1371  } /* else printf ("GET_ECMA_MF_TOUCHED MF_ECMA_has_changed is %d for %d %d\n",JSVAL_TO_INT(mainElement),cx,JSglobal_return_val); */ \
1372  touched = JSVAL_TO_INT(mainElement);\
1373  break; \
1374  }
1375 
1376 #define RESET_ECMA_MF_TOUCHED(thistype) \
1377  case FIELDTYPE_##thistype: {\
1378  jsval myv = INT_TO_JSVAL(0); \
1379  /* printf ("RESET_ECMA_MF_TOUCHED called on %d ",JSglobal_return_val); */ \
1380  JSBEGINREQUEST_SUBSTITUTION(scriptcontrol->cx) \
1381  if (!JS_SetProperty(scriptcontrol->cx, JSVAL_TO_OBJECT(*(jsval*)(tg->JScript.JSglobal_return_val)), "MF_ECMA_has_changed", &myv)) { \
1382  printf( "JS_SetProperty failed for \"MF_ECMA_has_changed\" in RESET_ECMA_MF_TOUCHED.\n"); \
1383  }\
1384  /* if (!JS_GetProperty( p->ScriptControl[actualscript].cx, JSVAL_TO_OBJECT(JSglobal_return_val), "MF_ECMA_has_changed", &mainElement)) { \
1385  printf ("JS_GetProperty failed for \"MF_ECMA_HAS_changed\" in get_valueChanged_flag\n"); \
1386  } \
1387  printf ("and MF_ECMA_has_changed is %d\n",JSVAL_TO_INT(mainElement)); */\
1388  JSENDREQUEST_SUBSTITUTION(scriptcontrol->cx) \
1389  break; \
1390  }
1391 
1392 #define RESET_TOUCHED_TYPE_ECMA(thistype) \
1393  case FIELDTYPE_##thistype: { \
1394  JSBEGINREQUEST_SUBSTITUTION(scriptcontrol->cx) \
1395  resetNameInECMATable( scriptcontrol->cx,JSparamnames[fptr].name); \
1396  JSENDREQUEST_SUBSTITUTION(scriptcontrol->cx) \
1397  break; \
1398  }
1399 
1400 #ifdef OLDCODE
1401 OLDCODE /* in case Bool was defined above, restore the value */
1402 OLDCODE #define Bool savedBool
1403 #endif //OLDCODE
1404 
1405 
1406 
1407 
1408 /********************************************************************************/
1409 /* */
1410 /* get_valueChanged_flag - see if this variable (can be a sub-field; see tests */
1411 /* 8.wrl for the DEF PI PositionInterpolator). return true if variable is */
1412 /* touched, and pointer to touched value is in global variable */
1413 /* JSglobal_return_val, AND possibly: */
1414 /* void *JSSFpointer for SF non-ECMA nodes. */
1415 /* */
1416 /* the way touched, and, the actual values work is as follows: */
1417 /* */
1418 /* keep track of the name in a table, and set valueChanged flag. */
1419 /* look around the function setECMANative to see how this is done. */
1420 /* FIELDTYPE_SFInt32 */
1421 /* FIELDTYPE_SFBool */
1422 /* FIELDTYPE_SFFloat */
1423 /* FIELDTYPE_SFTime */
1424 /* FIELDTYPE_SFDouble */
1425 /* FIELDTYPE_SFString */
1426 /* */
1427 /* check the "touched" flag for non-zero in the private area: */
1428 /* FIELDTYPE_SFRotation */
1429 /* FIELDTYPE_SFNode */
1430 /* FIELDTYPE_SFVec2f */
1431 /* FIELDTYPE_SFVec3f */
1432 /* FIELDTYPE_SFImage */
1433 /* FIELDTYPE_SFColor */
1434 /* FIELDTYPE_SFColorRGBA */
1435 /* */
1436 /* go through all elements, and find if at least one SF has been touched: */
1437 /* FIELDTYPE_MFRotation */
1438 /* FIELDTYPE_MFNode */
1439 /* FIELDTYPE_MFVec2f */
1440 /* FIELDTYPE_MFVec3f */
1441 /* FIELDTYPE_MFColor */
1442 /* FIELDTYPE_MFColorRGBA */
1443 
1444 
1445 /* has a flag called "MF_ECMA_has_changed" that is used here */
1446 /* FIELDTYPE_MFFloat */
1447 /* FIELDTYPE_MFBool */
1448 /* FIELDTYPE_MFInt32 */
1449 /* FIELDTYPE_MFTime */
1450 /* FIELDTYPE_MFString */
1451 /* */
1452 /****************************************************************************/
1453 
1454 int get_valueChanged_flag (int fptr, int actualscript) {
1455 
1456 
1457  struct CRscriptStruct *scriptcontrol;
1458  JSContext *cx;
1459  JSObject *interpobj;
1460  char *fullname;
1461  int touched;
1462  //ppJScript p;
1463  ttglobal tg = gglobal();
1464  struct CRjsnameStruct *JSparamnames = getJSparamnames();
1465  //p = (ppJScript)tg->JScript.prv;
1466 
1467  touched = FALSE;
1468  scriptcontrol = getScriptControlIndex(actualscript);
1469  interpobj = (JSObject*)scriptcontrol->glob;
1470  cx = (JSContext*)scriptcontrol->cx;
1471  fullname = JSparamnames[fptr].name;
1472 
1473 #if defined(JS_THREADSAFE)
1474  JS_BeginRequest(cx);
1475 #endif
1476  #ifdef CRVERBOSE
1477  printf ("\ngetting property for fullname %s, cx %p, interpobj %d script %d, fptr %d (%s:%s)\n",
1478  fullname,cx,interpobj,actualscript, fptr,
1479  JSparamnames[fptr].name, FIELDTYPES[JSparamnames[fptr].type]);
1480  #endif
1481 
1482  if (!JS_GetProperty(cx, interpobj ,fullname,tg->JScript.JSglobal_return_val)) {
1483  printf ("cant get property for %s\n",fullname);
1484 #if defined(JS_THREADSAFE)
1485  JS_EndRequest(cx);
1486 #endif
1487  return FALSE;
1488  } else {
1489  #ifdef CRVERBOSE
1490  printf ("so, property is %d (%p)\n",*(jsval*)tg->JScript.JSglobal_return_val,*(jsval *)tg->JScript.JSglobal_return_val);
1491  printf("get_valueChanged_flag: node type: %s name %s\n",FIELDTYPES[JSparamnames[fptr].type],JSparamnames[fptr].name);
1492  #endif
1493 
1494  switch (JSparamnames[fptr].type) {
1495  GETJSPTR_TYPE_A(SFRotation)
1496  GETJSPTR_TYPE_A(SFNode)
1497  GETJSPTR_TYPE_A(SFVec2f)
1498  /* GETJSPTR_TYPE_A(SFVec2d) */
1499  GETJSPTR_TYPE_A(SFVec3f)
1500  GETJSPTR_TYPE_A(SFVec3d)
1501  GETJSPTR_TYPE_A(SFVec4f)
1502  GETJSPTR_TYPE_A(SFVec4d)
1503  GETJSPTR_TYPE_A(SFImage)
1504  GETJSPTR_TYPE_A(SFColor)
1505  GETJSPTR_TYPE_A(SFColorRGBA)
1506 
1507  GETJSPTR_TYPE_MF_A(MFRotation,SFRotation)
1508  GETJSPTR_TYPE_MF_A(MFNode,SFNode)
1509  GETJSPTR_TYPE_MF_A(MFVec2f,SFVec2f)
1510  GETJSPTR_TYPE_MF_A(MFVec3f,SFVec3f)
1511  GETJSPTR_TYPE_MF_A(MFVec4f,SFVec4f)
1512  GETJSPTR_TYPE_MF_A(MFVec4d,SFVec4d)
1513  /* GETJSPTR_TYPE_MF_A(MFImage,SFImage) */
1514  GETJSPTR_TYPE_MF_A(MFColor,SFColor)
1515  GETJSPTR_TYPE_MF_A(MFColorRGBA,SFColorRGBA)
1516 
1517  GET_ECMA_MF_TOUCHED(Int32)
1518  GET_ECMA_MF_TOUCHED(Bool)
1519  GET_ECMA_MF_TOUCHED(Time)
1520  GET_ECMA_MF_TOUCHED(Double)
1521  GET_ECMA_MF_TOUCHED(Float)
1522  GET_ECMA_MF_TOUCHED(String)
1523 
1524  GET_ECMA_TOUCHED(Int32)
1525  GET_ECMA_TOUCHED(Bool)
1526  GET_ECMA_TOUCHED(Float)
1527  GET_ECMA_TOUCHED(Time)
1528  GET_ECMA_TOUCHED(Double)
1529  GET_ECMA_TOUCHED(String)
1530 
1531  default: {printf ("not handled yet in get_valueChanged_flag %s\n",FIELDTYPES[JSparamnames[fptr].type]);
1532  }
1533  }
1534 #if defined(JS_THREADSAFE)
1535  JS_EndRequest(cx);
1536 #endif
1537  }
1538 
1539 #ifdef CHECKER
1540  if (JSparamnames[fptr].type == FIELDTYPE_MFString) {
1541  int len; int i;
1542  jsval mainElement;
1543  int len;
1544 
1545  unsigned CRCCheck = 0;
1546  cx = p->ScriptControl[actualscript].cx;
1547 #if defined(JS_THREADSAFE)
1548  JS_BeginRequest(cx);
1549 #endif
1550  if (!JS_GetProperty(cx, JSglobal_return_val, "length", &mainElement)) {
1551  printf ("JS_GetProperty failed for length_flag\n");
1552  }
1553  len = JSVAL_TO_INT(mainElement);
1554  /* go through each element of the main array. */
1555  for (i = 0; i < len; i++) {
1556  if (!JS_GetElement(cx, JSglobal_return_val, i, &mainElement)) {
1557  printf ("JS_GetElement failed for %d in get_valueChanged_flag\n",i);
1558  break;
1559  }
1560  CRCCheck += (unsigned) mainElement;
1561 
1562 /*
1563  if (JSVAL_IS_OBJECT(mainElement)) printf ("sc, element %d is an OBJECT\n",i);
1564  if (JSVAL_IS_STRING(mainElement)) printf ("sc, element %d is an STRING\n",i);
1565  if (JSVAL_IS_NUMBER(mainElement)) printf ("sc, element %d is an NUMBER\n",i);
1566  if (JSVAL_IS_DOUBLE(mainElement)) printf ("sc, element %d is an DOUBLE\n",i);
1567  if (JSVAL_IS_INT(mainElement)) printf ("sc, element %d is an INT\n",i);
1568 */
1569 
1570  }
1571  printf ("CRCcheck %u\n",CRCCheck);
1572 #if defined(JS_THREADSAFE)
1573  JS_EndRequest(cx);
1574 #endif
1575  }
1576 #endif
1577 
1578 
1579 
1580  return touched;
1581 
1582 }
1583 
1584 
1585 /* this script value has been looked at, set the touched flag in it to FALSE. */
1586 void resetScriptTouchedFlag(int actualscript, int fptr) {
1587 
1588  struct CRscriptStruct *scriptcontrol;
1589  ttglobal tg = gglobal();
1590  struct CRjsnameStruct *JSparamnames = getJSparamnames();
1591  //ppJScript p = (ppJScript)tg->JScript.prv;
1592  #ifdef CRVERBOSE
1593  printf ("resetScriptTouchedFlag, name %s type %s script %d, fptr %d\n",JSparamnames[fptr].name, stringFieldtypeType(JSparamnames[fptr].type), actualscript, fptr);
1594  #endif
1595  scriptcontrol = getScriptControlIndex(actualscript);
1596  switch (JSparamnames[fptr].type) {
1597  RESET_TOUCHED_TYPE_A(SFRotation)
1598  RESET_TOUCHED_TYPE_A(SFNode)
1599  RESET_TOUCHED_TYPE_A(SFVec2f)
1600  RESET_TOUCHED_TYPE_A(SFVec3f)
1601  RESET_TOUCHED_TYPE_A(SFVec4f)
1602  /* RESET_TOUCHED_TYPE_A(SFVec2d) */
1603  RESET_TOUCHED_TYPE_A(SFVec3d)
1604  RESET_TOUCHED_TYPE_A(SFVec4d)
1605  RESET_TOUCHED_TYPE_A(SFImage)
1606  RESET_TOUCHED_TYPE_A(SFColor)
1607  RESET_TOUCHED_TYPE_A(SFColorRGBA)
1608  RESET_TOUCHED_TYPE_MF_A(MFRotation,SFRotation)
1609  RESET_TOUCHED_TYPE_MF_A(MFNode,SFNode)
1610  RESET_TOUCHED_TYPE_MF_A(MFVec2f,SFVec2f)
1611  RESET_TOUCHED_TYPE_MF_A(MFVec3f,SFVec3f)
1612  RESET_TOUCHED_TYPE_MF_A(MFVec4f,SFVec4f)
1613  RESET_TOUCHED_TYPE_MF_A(MFVec4d,SFVec4d)
1614  /* RESET_TOUCHED_TYPE_MF_A(MFImage,SFImage) */
1615  RESET_TOUCHED_TYPE_MF_A(MFColor,SFColor)
1616  RESET_TOUCHED_TYPE_MF_A(MFColorRGBA,SFColorRGBA)
1617 
1618  RESET_TOUCHED_TYPE_ECMA (SFInt32)
1619  RESET_TOUCHED_TYPE_ECMA (SFBool)
1620  RESET_TOUCHED_TYPE_ECMA (SFFloat)
1621  RESET_TOUCHED_TYPE_ECMA (SFTime)
1622  RESET_TOUCHED_TYPE_ECMA (SFDouble)
1623  RESET_TOUCHED_TYPE_ECMA (SFString)
1624  RESET_ECMA_MF_TOUCHED(MFInt32)
1625  RESET_ECMA_MF_TOUCHED(MFBool)
1626  RESET_ECMA_MF_TOUCHED(MFFloat)
1627  RESET_ECMA_MF_TOUCHED(MFTime)
1628  RESET_ECMA_MF_TOUCHED(MFString)
1629 
1630 
1631  default: {printf ("can not reset touched_flag for %s\n",stringFieldtypeType(JSparamnames[fptr].type));
1632  }
1633  }
1634 
1635 }
1636 
1637 
1638 int jsActualrunScript(int num, char *script);
1639 void JSInitializeScriptAndFields (int num) {
1640 #ifdef OLDWAY33
1641  struct ScriptParamList *thisEntry;
1642  struct ScriptParamList *nextEntry;
1643 #endif
1644  //jsval rval;
1645  //ppCRoutes p = (ppCRoutes)gglobal()->CRoutes.prv;
1646  struct CRscriptStruct *ScriptControl; // = getScriptControl();
1647 
1648  /* printf ("JSInitializeScriptAndFields script %d, thread %u\n",num,pthread_self()); */
1649  /* run through paramList, and run the script */
1650  /* printf ("JSInitializeScriptAndFields, running through params and main script\n"); */
1651  //if (num >= p->JSMaxScript) {
1652  // ConsoleMessage ("JSInitializeScriptAndFields: warning, script %d initialization out of order",num);
1653  // return;
1654  //}
1655  /* run through fields in order of entry in the X3D file */
1656 
1657 
1658 
1659 
1660 
1661 #ifdef OLDWAY33
1662  thisEntry = ScriptControl[num].paramList;
1663  while (thisEntry != NULL) {
1664  /* printf ("script field is %s\n",thisEntry->field); */
1665  InitScriptField(num, thisEntry->kind, thisEntry->type, thisEntry->field, thisEntry->value);
1666 
1667  /* get the next block; free the current name, current block, and make current = next */
1668  nextEntry = thisEntry->next;
1669  FREE_IF_NZ (thisEntry->field);
1670  FREE_IF_NZ (thisEntry);
1671  thisEntry = nextEntry;
1672  }
1673 
1674  /* we have freed each element, set list to NULL in case anyone else comes along */
1675  ScriptControl[num].paramList = NULL;
1676 #else
1677  int i,nfields,kind,itype;
1678  const char *fieldname;
1679  struct Shader_Script *script;
1680  struct ScriptFieldDecl *field;
1681 
1682  ScriptControl = getScriptControlIndex(num);
1683  script = ScriptControl->script;
1684  //printf("adding fields from script %x\n",script);
1685  nfields = Shader_Script_getScriptFieldCount(script);
1686  for(i=0;i<nfields;i++){
1687  field = Shader_Script_getScriptField(script,i);
1688  fieldname = ScriptFieldDecl_getName(field);
1689  kind = ScriptFieldDecl_getMode(field);
1690  itype = ScriptFieldDecl_getType(field);
1691  InitScriptField(num, kind, itype, fieldname, field->value);
1692  }
1693 #endif
1694 
1695  if (!jsActualrunScript(num, ScriptControl->scriptText)) {
1696  ConsoleMessage ("JSInitializeScriptAndFields, script failure\n");
1697  ScriptControl->scriptOK = FALSE;
1698  ScriptControl->_initialized = TRUE;
1699  return;
1700  }
1701  FREE_IF_NZ(ScriptControl->scriptText);
1702  ScriptControl->_initialized = TRUE;
1703  ScriptControl->scriptOK = TRUE;
1704 
1705 }
1706 
1707 
1708 
1709 /* save this field from the parser; initialize it when the fwl_RenderSceneUpdateScene wants to initialize it */
1710 void SaveScriptField (int num, indexT kind, indexT type, const char* field, union anyVrml value) {
1711 #ifdef OLDWAY33
1712  struct ScriptParamList **nextInsert;
1713  struct ScriptParamList *newEntry;
1714  struct CRscriptStruct *ScriptControl = getScriptControl();
1715  //ppCRoutes p = (ppCRoutes)gglobal()->CRoutes.prv;
1716 
1717  //if (num >= p->JSMaxScript) {
1718  // ConsoleMessage ("JSSaveScriptText: warning, script %d initialization out of order",num);
1719  // return;
1720  //}
1721 
1722  /* generate a new ScriptParamList entry */
1723  /* note that this is a linked list, and we put things on at the end. The END MUST
1724  have NULL termination */
1725  nextInsert = &(ScriptControl[num].paramList);
1726  while (*nextInsert != NULL) {
1727  nextInsert = &(*nextInsert)->next;
1728  }
1729 
1730  /* create a new entry and link it in */
1731  newEntry = MALLOC (struct ScriptParamList *, sizeof (struct ScriptParamList));
1732  *nextInsert = newEntry;
1733 
1734  /* initialize the new entry */
1735  newEntry->next = NULL;
1736  newEntry->kind = kind;
1737  newEntry->type = type;
1738  newEntry->field = STRDUP(field);
1739  newEntry->value = value;
1740 #endif
1741 }
1742 
1743 
1744 
1745 
1746 /****************************************************************/
1747 /* a Jscript is returning a Multi-number type; copy this from */
1748 /* the Jscript return string to the data structure within the */
1749 /* freewrl C side of things. */
1750 /* */
1751 /* note - this cheats in that the code assumes that it is */
1752 /* a series of Multi_Vec3f's while in reality the structure */
1753 /* of the multi structures is the same - so we "fudge" things */
1754 /* to make this multi-purpose. */
1755 /****************************************************************/
1756 void getJSMultiNumType (JSContext *cx, struct Multi_Vec3f *tn, int eletype) {
1757  float *fl;
1758  int *il;
1759  double *dl;
1760  struct X3D_Node * *nl;
1761 
1762  double dtmp;
1763  jsval mainElement;
1764  int len;
1765  int i;
1766  char *strp;
1767 #if JS_VERSION >= 185
1768  char *strpp; /* we need this to reliably free the results of JS_EncodeString() */
1769 #endif
1770  int elesize;
1771  SFVec2fNative *sfvec2f;
1772  SFVec3fNative *sfvec3f;
1773  SFRotationNative *sfrotation;
1774  struct Uni_String * *ms;
1775  jsval *myJSVal;
1776  ttglobal tg = gglobal();
1777 
1778  /* get size of each element, used for MALLOCing memory - eg, this will
1779  be sizeof(float) * 3 for a SFColor */
1780  elesize = returnElementLength(eletype) * returnElementRowSize(eletype);
1781 
1782  /* rough check of return value */
1783  /* where did this come from? Was it from a script execution, or from an assignment from within a script?? */
1784  #ifdef SETFIELDVERBOSE
1785  printf ("getJSMultiNumType, JSCreate_global_return_val %u, JSglobal_return_val %u\n",
1786  (unsigned int) JSVAL_TO_INT(*(jsval *)tg->jsVRMLBrowser.JSCreate_global_return_val),
1787  (unsigned int) JSVAL_TO_INT(*(jsval *)tg->JScript.JSglobal_return_val));
1788  #endif
1789 
1790  if (JSVAL_TO_INT(*(jsval*)(tg->jsVRMLBrowser.JSCreate_global_return_val)) != 0) {
1791  myJSVal = (jsval *)tg->jsVRMLBrowser.JSCreate_global_return_val;
1792  *(jsval *)(tg->jsVRMLBrowser.JSCreate_global_return_val) = INT_TO_JSVAL(0);
1793 
1794  #ifdef SETFIELDVERBOSE
1795  printf ("getJSMultiNumType: using JSCreate_global_return_val\n");
1796  #endif
1797  } else {
1798  #ifdef SETFIELDVERBOSE
1799  printf ("getJSMultiNumType: using JSglobal_return_val\n");
1800  #endif
1801 
1802  myJSVal = tg->JScript.JSglobal_return_val;
1803  }
1804 
1805  if (!JSVAL_IS_OBJECT(*myJSVal)) {
1806  printf ("getJSMultiNumType - did not get an object\n");
1807  return;
1808  }
1809 
1810  #ifdef SETFIELDVERBOSE
1811  printf ("getJSMultiNumType, tn %p dest has %s size %d\n",tn,stringFieldtypeType(eletype), elesize);
1812 
1813  printf("getJSMulitNumType, node type of myJSVal is :");
1814  printJSNodeType (cx,myJSVal);
1815  #endif
1816 
1817  if (!JS_GetProperty(cx, JSVAL_TO_OBJECT(*myJSVal), MF_LENGTH_FIELD, &mainElement)) {
1818  printf ("JS_GetProperty failed for \"%s\" in getJSMultiNumType\n", MF_LENGTH_FIELD);
1819  return;
1820  }
1821  len = JSVAL_TO_INT(mainElement);
1822  #ifdef SETFIELDVERBOSE
1823  printf ("getmuiltie length of grv is %d old len is %d\n",len,tn->n);
1824  #endif
1825 
1826  /* do we have to realloc memory? */
1827  if (len != tn->n) {
1828 
1829  tn->n = 0;
1830  /* yep... */
1831  /* printf ("old pointer %d\n",tn->p); */
1832  FREE_IF_NZ (tn->p);
1833  tn->p = MALLOC (struct SFVec3f *, (unsigned)(elesize*len));
1834 
1835  #ifdef SETFIELDVERBOSE
1836  printf ("MALLOCing memory for elesize %d len %d new pointer now is %p\n",elesize,len,tn->p);
1837  #endif
1838 
1839  /* if this is an MFString, we should set each element to a null string */
1840  if (eletype == FIELDTYPE_SFString) {
1841  #ifdef SETFIELDVERBOSE
1842  printf ("getJSMultiNumType, this is a MFString, so making tiny strings for now\n");
1843  #endif
1844 
1845  ms = (struct Uni_String * *) tn->p;
1846  for (i=0; i<len; i++) {
1847  *ms = newASCIIString ("(getJSMultiNumType null)");
1848  ms ++;
1849  }
1850  }
1851  }
1852 
1853  /* set these three up, but we only use one of them */
1854  fl = (float *) tn->p;
1855  il = (int *) tn->p;
1856  dl = (double *) tn->p;
1857  nl = (struct X3D_Node * *) tn->p;
1858  ms = (struct Uni_String * *) tn->p;
1859 
1860  /* go through each element of the main array. */
1861  for (i = 0; i < len; i++) {
1862  if (!JS_GetElement(cx, JSVAL_TO_OBJECT(*myJSVal), i, &mainElement)) {
1863  printf ("WARNING: JS_GetElement failed for %d in getJSMultiNumType\n",i);
1864  switch (eletype) {
1865  case FIELDTYPE_SFNode:
1866  *nl = 0; nl++; break;
1867  case FIELDTYPE_SFInt32:
1868  *il=0; il++; break;
1869  case FIELDTYPE_SFDouble:
1870  case FIELDTYPE_SFTime:
1871  *dl=0.0; dl++; break;
1872  case FIELDTYPE_SFFloat:
1873  *fl = (float) 0.0; fl++; break;
1874  case FIELDTYPE_SFVec2f:
1875  *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; break;
1876  case FIELDTYPE_SFVec3f:
1877  case FIELDTYPE_SFColor:
1878  *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; break;
1879  case FIELDTYPE_SFRotation:
1880  *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++; break;
1881  case FIELDTYPE_SFString:
1882  verify_Uni_String (*ms,"(empty value)"); ms++; break;
1883 
1884  default : {printf ("getJSMultiNumType unhandled eletype: %d\n",
1885  eletype);
1886  return;
1887  }
1888  }
1889  } else {
1890  #ifdef SETFIELDVERBOSE
1891  JSString *_tmpStr;
1892 
1893  _tmpStr = JS_ValueToString(cx, mainElement);
1894 #if JS_VERSION < 185
1895  strp = JS_GetStringBytes(_tmpStr);
1896 #else
1897  strp = strpp = JS_EncodeString(cx,_tmpStr);
1898 #endif
1899  printf ("sub element %d is \"%s\" \n",i,strp);
1900 #if JS_VERSION >= 185
1901  JS_free(cx,strpp);
1902 #endif
1903 
1904  if (JSVAL_IS_OBJECT(mainElement)) printf ("sub element %d is an OBJECT\n",i);
1905  if (JSVAL_IS_PRIMITIVE(mainElement)) printf ("sub element %d is an PRIMITIVE\n",i);
1906  #endif
1907 
1908  /* code is pretty much same as SF* values in setField_javascriptEventOut */
1909  switch (eletype) {
1910  case FIELDTYPE_SFNode: {
1911 
1912  if (JS_InstanceOf (cx, JSVAL_TO_OBJECT(mainElement), &SFNodeClass, NULL)) {
1913  SFNodeNative *_vec;
1914 
1915  /* printf ("yep, this is an SFNode class\n"); */
1916  if ((_vec = (SFNodeNative *)JS_GetPrivate(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) {
1917  printf ("error getting native\n");
1918  *nl = NULL;
1919  } else {
1920  /* printf ("have native, handle %p\n",_vec->handle);
1921  printf ("and it is a :%s:\n",stringNodeType(_vec->handle->_nodeType)); */
1922  *nl = _vec->handle;
1923  }
1924  } else {
1925  printf ("hmm - not an SFNode class\n");
1926  *nl = NULL;
1927  }
1928 
1929  nl++;
1930  break;
1931  }
1932  case FIELDTYPE_SFInt32: {
1933  if (!JS_ValueToInt32(cx, mainElement ,il)) {
1934  printf ("error\n");
1935  *il=0;
1936  }
1937  il++;
1938  break;
1939  }
1940  case FIELDTYPE_SFDouble:
1941  case FIELDTYPE_SFTime: {
1942  if (!JS_ValueToNumber(cx, mainElement ,dl)) *dl=0.0;
1943  dl++;
1944  break;
1945  }
1946  case FIELDTYPE_SFFloat: {
1947  if (!JS_ValueToNumber(cx, mainElement, &dtmp)) dtmp=0.0;
1948  /* convert double precision to single, for X3D */
1949  *fl = (float) dtmp;
1950  fl++;
1951  break;
1952  }
1953  case FIELDTYPE_SFVec2f: {
1954  if (JSVAL_IS_OBJECT(mainElement)) {
1955  if ((sfvec2f = (SFVec2fNative *)JS_GetPrivate(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) {
1956  printf( "JS_GetPrivate failed for obj in setField_javascriptEventOut.\n");
1957  return;
1958  }
1959  memcpy ((void *)fl, (void *)&(sfvec2f->v),2*sizeof(float));
1960  fl += 2;
1961  } else {
1962  /* we are working in a value that kind of exists, but is undefined */
1963  *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++;
1964  }
1965  break;
1966  }
1967  case FIELDTYPE_SFVec3f:
1968  case FIELDTYPE_SFColor: { /* SFColor */
1969  if (JSVAL_IS_OBJECT(mainElement)) {
1970  if ((sfvec3f = (SFVec3fNative *)JS_GetPrivate(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) {
1971  printf( "JS_GetPrivate failed for obj in setField_javascriptEventOut.\n");
1972  return;
1973  }
1974  memcpy ((void *)fl, (void *)&(sfvec3f->v),3*sizeof(float));
1975  fl += 3;
1976  } else {
1977  /* we are working in a value that kind of exists, but is undefined */
1978  *fl = (float) 0.0; fl++;
1979  *fl = (float) 0.0; fl++;
1980  *fl = (float) 0.0; fl++;
1981  }
1982  break;
1983  }
1984  case FIELDTYPE_SFRotation: {
1985  if (JSVAL_IS_OBJECT(mainElement)) {
1986  if ((sfrotation = (SFRotationNative *)JS_GetPrivate(cx, JSVAL_TO_OBJECT(mainElement))) == NULL) {
1987  printf( "JS_GetPrivate failed for obj in setField_javascriptEventOut.\n");
1988  return;
1989  }
1990  memcpy ((void *)fl, (void *)&(sfrotation->v),4*sizeof(float));
1991  fl += 4;
1992  } else {
1993  /* we are working in a value that kind of exists, but is undefined */
1994  *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++;
1995  *fl = (float) 0.0; fl++; *fl = (float) 0.0; fl++;
1996  }
1997  break;
1998  }
1999 
2000  case FIELDTYPE_SFString: {
2001  JSString *strval;
2002 
2003  strval = JS_ValueToString(cx, mainElement);
2004 #if JS_VERSION < 185
2005  strp = JS_GetStringBytes(strval);
2006 #else
2007  strp = strpp = JS_EncodeString(cx,strval);
2008 #endif
2009 
2010 
2011  #ifdef SETFIELDVERBOSE
2012  printf ("getJSMultiNumType, got string %s\n",strp);
2013  #endif
2014 
2015  /* copy the string over, delete the old one, if need be */
2016  verify_Uni_String (*ms,strp);
2017  ms++;
2018 #if JS_VERSION >= 185
2019  JS_free(cx,strpp);
2020 #endif
2021  break;
2022  }
2023 
2024  default : {printf ("getJSMultiNumType unhandled eletype: %d\n",
2025  eletype);
2026  return;
2027  }
2028  }
2029  }
2030 
2031  }
2032  #ifdef SETFIELDVERBOSE
2033  printf ("getJSMultiNumType, setting old length %d to length %d\n",tn->n, len);
2034  #endif
2035 
2036  tn->n = len;
2037 }
2038 
2039 /****************************************************************/
2040 /* a script is returning a MFString type; add this to the C */
2041 /* children field */
2042 /****************************************************************/
2043 void getMFStringtype (JSContext *cx, jsval *from, struct Multi_String *to) {
2044  int oldlen, newlen;
2045  jsval _v;
2046  JSObject *obj;
2047  int i;
2048  char *valStr, *OldvalStr;
2049  struct Uni_String **svptr;
2050  struct Uni_String **newp, **oldp;
2051  int count;
2052 
2053  JSString *strval; /* strings */
2054 
2055  oldlen = to->n;
2056  svptr = to->p;
2057  newlen=0;
2058 
2059  if (!JS_ValueToObject(cx, *from, &obj))
2060  printf ("JS_ValueToObject failed in getMFStringtype\n");
2061 
2062  if (!JS_GetProperty(cx, obj, MF_LENGTH_FIELD, &_v)) {
2063  printf ("JS_GetProperty failed for \"%s\" in getMFStringtype.\n", MF_LENGTH_FIELD);
2064  }
2065 
2066  newlen = JSVAL_TO_INT(_v);
2067 
2068  /* printf ("getMFStringType, newlen %d oldlen %d\n",newlen,oldlen); */
2069 
2070 
2071  /* if we have to expand size of SV... */
2072  if (newlen > oldlen) {
2073  oldp = to->p; /* same as svptr, assigned above */
2074  to->n = newlen;
2075  to->p = MALLOC(struct Uni_String **, newlen * sizeof(to->p));
2076  newp = to->p;
2077 
2078  /* copy old values over */
2079  for (count = 0; count <oldlen; count ++) {
2080  /*printf ("copying over element %d\n",count); */
2081  *newp = *oldp;
2082  newp++;
2083  oldp++;
2084  }
2085 
2086  /* zero new entries */
2087  for (count = oldlen; count < newlen; count ++) {
2088  /* make the new SV */
2089  *newp = MALLOC (struct Uni_String *, sizeof (struct Uni_String));
2090 
2091 
2092  /* now, make it point to a blank string */
2093  *newp = newASCIIString("");
2094  newp ++;
2095  }
2096  FREE_IF_NZ (svptr);
2097  svptr = to->p;
2098  } else {
2099  /* possibly truncate this, but leave the memory alone. */
2100  to->n = newlen;
2101  }
2102 
2103  /* printf ("verifying structure here\n");
2104  for (i=0; i<(to->n); i++) {
2105  printf ("indx %d flag %x string :%s: len1 %d len2 %d\n",i,
2106  (svptr[i])->sv_flags,
2107  }
2108  printf ("done\n");
2109  */
2110 
2111 
2112  for (i = 0; i < newlen; i++) {
2113  /* get the old string pointer */
2114  OldvalStr = svptr[i]->strptr;
2115  /* printf ("old string at %d is %s len %d\n",i,OldvalStr,strlen(OldvalStr)); */
2116 
2117  /* get the new string pointer */
2118  if (!JS_GetElement(cx, obj, i, &_v)) {
2119  fprintf(stderr,
2120  "JS_GetElement failed for %d in getMFStringtype\n",i);
2121  return;
2122  }
2123  strval = JS_ValueToString(cx, _v);
2124 #if JS_VERSION < 185
2125  valStr = JS_GetStringBytes(strval);
2126 #else
2127  valStr = JS_EncodeString(cx,strval);
2128 #endif
2129 
2130  /* printf ("new string %d is %s\n",i,valStr); */
2131 
2132  /* if the strings are different... */
2133  if (strcmp(valStr,OldvalStr) != 0) {
2134  /* MALLOC a new string, of correct len for terminator */
2135  svptr[i] = newASCIIString(valStr);
2136  }
2137 #if JS_VERSION >= 185
2138  JS_free(cx,valStr);
2139 #endif
2140  }
2141  /*
2142  printf ("\n new structure: %d %d\n",svptr,newlen);
2143  for (i=0; i<newlen; i++) {
2144  printf ("indx %d string :%s: len1 %d len2 %d\n",i,
2145  mypv->xpv_pv, mypv->xpv_cur,mypv->xpv_len);
2146  }
2147  */
2148 
2149 }
2150 
2151 
2152 
2153 
2154 void setField_javascriptEventOut(struct X3D_Node *tn,unsigned int tptr, int fieldType, unsigned len, int extraData, JSContext *scriptContext) {
2155  int ival;
2156  double tval;
2157  float fl[4];
2158  char *memptr;
2159  JSString *strval; /* strings */
2160  char *strp;
2161 #if JS_VERSION >= 185
2162  char *strpp; /* strp is modified, so we cannot use it to free JS_EncodeString results */
2163 #endif
2164  ttglobal tg = gglobal();
2165 
2166  /* NOTE - parent calls BeginRequest so we don't have to */
2167 
2168  /* set up a pointer to where to put this stuff */
2169  memptr = offsetPointer_deref(char *, tn, tptr);
2170 
2171  #ifdef SETFIELDVERBOSE
2172  strval = JS_ValueToString(scriptContext, *(jsval *)tg->JScript.JSglobal_return_val);
2173 #if JS_VERSION < 185
2174  strp = JS_GetStringBytes(strval);
2175 #else
2176  strp = strpp = JS_EncodeString(scriptContext,strval);
2177 #endif
2178  printf ("start of setField_javascriptEventOut, to %ld:%d = %p, fieldtype %d string %s\n",(long)tn, tptr, memptr, fieldType, strp);
2179 #if JS_VERSION >= 185
2180  JS_free(scriptContext,strpp);
2181 #endif
2182  #endif
2183 
2184 #define GETJSVAL_TYPE_A(thistype,field) \
2185  case FIELDTYPE_##thistype: { \
2186  /* printf ("doing TYPEA memcpy to %u, from %u, len %d\n",(void *)memptr, (void *) &(((thistype##Native *)JSSFpointer)->field),len); */ \
2187  memcpy ((void *)memptr, (void *) &(((thistype##Native *)tg->CRoutes.JSSFpointer)->field),len); \
2188  break; \
2189  }
2190 
2191 #define GETJSVAL_TYPE_MF_A(MFtype,SFtype) \
2192  case FIELDTYPE_##MFtype: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_##SFtype); break;}
2193 
2194  switch (fieldType) {
2195  GETJSVAL_TYPE_A(SFRotation,v)
2196  /* GETJSVAL_TYPE_A(SFNode,handle) */
2197  /* not implemented yet? GETJSVAL_TYPE_A(SFVec2d,v) */
2198  GETJSVAL_TYPE_A(SFVec3d,v)
2199  GETJSVAL_TYPE_A(SFVec4d,v)
2200  GETJSVAL_TYPE_A(SFVec2f,v)
2201  GETJSVAL_TYPE_A(SFVec3f,v)
2202  GETJSVAL_TYPE_A(SFVec4f,v)
2203  GETJSVAL_TYPE_A(SFColor,v)
2204  GETJSVAL_TYPE_A(SFColorRGBA,v)
2205 
2206  GETJSVAL_TYPE_MF_A(MFRotation,SFRotation)
2207  GETJSVAL_TYPE_MF_A(MFVec2d,SFVec2d)
2208  GETJSVAL_TYPE_MF_A(MFVec3d,SFVec3d)
2209  GETJSVAL_TYPE_MF_A(MFVec4d,SFVec4d)
2210  GETJSVAL_TYPE_MF_A(MFVec2f,SFVec2f)
2211  GETJSVAL_TYPE_MF_A(MFVec3f,SFVec3f)
2212  GETJSVAL_TYPE_MF_A(MFVec4f,SFVec4f)
2213  GETJSVAL_TYPE_MF_A(MFColor,SFColor)
2214  GETJSVAL_TYPE_MF_A(MFColorRGBA,SFColorRGBA)
2215 
2216 
2217  case FIELDTYPE_SFInt32:
2218  case FIELDTYPE_SFBool: { /* SFBool */
2219  if (!JS_ValueToInt32(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&ival)) {
2220  printf ("error\n");
2221  ival=0;
2222  }
2223  memcpy ((void *)memptr, (void *)&ival,len);
2224  break;
2225  }
2226 
2227  case FIELDTYPE_SFDouble:
2228  case FIELDTYPE_SFTime: {
2229  if (!JS_ValueToNumber(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&tval)) tval=0.0;
2230  memcpy ((void *)memptr, (void *)&tval,len);
2231  break;
2232  }
2233 
2234  case FIELDTYPE_SFFloat: {
2235  if (!JS_ValueToNumber(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&tval)) tval=0.0;
2236  /* convert double precision to single, for X3D */
2237  fl[0] = (float) tval;
2238  memcpy ((void *)memptr, (void *)fl,len);
2239  break;
2240  }
2241 
2242  case FIELDTYPE_SFImage: {
2243  /* the string should be saved as an SFImage */
2244  strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2245 #if JS_VERSION < 185
2246  strp = JS_GetStringBytes(strval);
2247 #else
2248  strp = strpp = JS_EncodeString(scriptContext,strval);
2249 #endif
2250 
2251  Parser_scanStringValueToMem(tn, tptr, FIELDTYPE_SFImage, strp, FALSE);
2252 #if JS_VERSION >= 185
2253  JS_free(scriptContext,strpp);
2254 #endif
2255  break;
2256  }
2257 
2258  case FIELDTYPE_SFString: {
2259  struct Uni_String *ms;
2260  intptr_t *newptr;
2261 
2262  strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2263 #if JS_VERSION < 185
2264  strp = JS_GetStringBytes(strval);
2265 #else
2266  strp = strpp = JS_EncodeString(scriptContext,strval);
2267 #endif
2268 
2269  /* copy the string over, delete the old one, if need be */
2270  /* printf ("fieldSet SFString, tn %d tptr %d offset from struct %d\n",
2271  tn, tptr, offsetof (struct X3D_TextureCoordinateGenerator, mode)); */
2272  newptr = (intptr_t *)memptr;
2273  ms = (struct Uni_String*) *newptr;
2274  verify_Uni_String (ms,strp);
2275 #if JS_VERSION >= 185
2276  JS_free(scriptContext,strpp);
2277 #endif
2278  break;
2279  }
2280 
2281 
2282  /* a series of Floats... */
2283  case FIELDTYPE_MFFloat: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFFloat); break;}
2284  case FIELDTYPE_MFInt32: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFInt32); break;}
2285  case FIELDTYPE_MFTime: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFTime); break;}
2286  case FIELDTYPE_MFDouble: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFDouble); break;}
2287  case FIELDTYPE_MFNode: {
2288  struct X3D_Node *mynode;
2289 
2290  strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2291 #if JS_VERSION < 185
2292  strp = JS_GetStringBytes(strval);
2293 #else
2294  strp = strpp = JS_EncodeString(scriptContext,strval);
2295 #endif
2296 
2297  /* we will have at least one node here, in an ascii string */
2298  while ((*strp > '\0') && (*strp <= ' ')) strp ++;
2299  /* are we at a bracket? */
2300  if (*strp == '[') strp ++;
2301  while ((*strp > '\0') && (*strp <= ' ')) strp ++;
2302 
2303  /* printf ("convertingthe following string to a pointer :%s:\n",strp); */
2304 
2305  mynode = X3D_NODE(atol(strp));
2306 #if JS_VERSION >= 185
2307  JS_free(scriptContext,strpp);
2308 #endif
2309 
2310  /* printf ("mynode is %p %d, \n",mynode,mynode);
2311  printf ("mynode is %p %d, type %d\n",mynode,mynode,mynode->_nodeType);
2312  printf ("calling getMFNodeType now\n"); */
2313 
2314 
2315  getMFNodetype (mynode,(struct Multi_Node *)memptr,X3D_NODE(tn),extraData); break;
2316  }
2317  case FIELDTYPE_MFString: {
2318  getMFStringtype (
2319  scriptContext,
2320  (jsval *)tg->JScript.JSglobal_return_val,
2321  (struct Multi_String *)memptr);
2322  break;
2323  }
2324 
2325  case FIELDTYPE_SFNode: {
2326  //unsigned int valuecopied;
2327  //unsigned int *ptr2value;
2328  /* printf ("doing TYPEA memcpy to %u, from %u, len %d\n",(void *)memptr, (void *) &(((SFNodeNative *)JSSFpointer)->handle),returnElementLength(FIELDTYPE_SFNode));*/
2329  memcpy ((void *)memptr, (void *) &(((SFNodeNative *)tg->CRoutes.JSSFpointer)->handle),returnElementLength(FIELDTYPE_SFNode));
2330  //ptr2value = (unsigned int*)memptr;
2331  //valuecopied = *ptr2value;
2332  //printf("value of memptr %u after memcpy in script route= %u\n",(void*)memptr,valuecopied);
2333  break;
2334  }
2335 
2336 
2337  default: { printf("WARNING: unhandled from type %s\n", stringFieldtypeType(fieldType));
2338  }
2339  }
2340 
2341  #ifdef SETFIELDVERBOSE
2342  printf ("done setField_javascriptEventOut\n");
2343  if (fieldType == FIELDTYPE_MFInt32) {
2344  printf ("setField_javascriptEventOut, checking the pointers...\n");
2345  printf ("node type is %s\n",stringNodeType(X3D_NODE(tn)->_nodeType));
2346  }
2347  if (fieldType == FIELDTYPE_SFNode) {
2348  printf ("setField_javascriptEventOut, checking the pointers...\n");
2349  printf ("node type is %s\n",stringNodeType(X3D_NODE(tn)->_nodeType));
2350  }
2351 
2352  #endif
2353 }
2354 
2355 void Parser_scanStringValueToMem_B(union anyVrml* any, indexT ctype, const char *value, int isXML);
2356 
2357 void setField_javascriptEventOut_B(union anyVrml* any,
2358  int fieldType, unsigned len, int extraData, JSContext *scriptContext)
2359 {
2360  //dug9 Feb 2013 for new propagate_events - like setField_javascriptEventout except:
2361  // writes to *anyVrml instead of (toNode,toOffset) combo (which doesn't work for Proto fields)
2362  // and doesn't update parents for SFNode,MFNode - that's done later.
2363  int ival;
2364  double tval;
2365  float fl[4];
2366  char *memptr;
2367  JSString *strval; /* strings */
2368  char *strp;
2369 #if JS_VERSION >= 185
2370  char *strpp; /* strp is modified, so we cannot use it to free JS_EncodeString results */
2371 #endif
2372  ttglobal tg = gglobal();
2373 
2374  /* NOTE - parent calls BeginRequest so we don't have to */
2375 
2376  /* set up a pointer to where to put this stuff */
2377  memptr = (char *)any; //offsetPointer_deref(char *, tn, tptr);
2378 
2379  #ifdef SETFIELDVERBOSE
2380  strval = JS_ValueToString(scriptContext, *(jsval *)tg->JScript.JSglobal_return_val);
2381 #if JS_VERSION < 185
2382  strp = JS_GetStringBytes(strval);
2383 #else
2384  strp = strpp = JS_EncodeString(scriptContext,strval);
2385 #endif
2386  printf ("start of setField_javascriptEventOut, to %ld:%d = %p, fieldtype %d string %s\n",(long)any, fieldType, memptr, fieldType, strp);
2387 #if JS_VERSION >= 185
2388  JS_free(scriptContext,strpp);
2389 #endif
2390  #endif
2391 
2392 #define GETJSVAL_TYPE_A(thistype,field) \
2393  case FIELDTYPE_##thistype: { \
2394  /* printf ("doing TYPEA memcpy to %u, from %u, len %d\n",(void *)memptr, (void *) &(((thistype##Native *)JSSFpointer)->field),len); */ \
2395  memcpy ((void *)memptr, (void *) &(((thistype##Native *)tg->CRoutes.JSSFpointer)->field),len); \
2396  break; \
2397  }
2398 
2399 #define GETJSVAL_TYPE_MF_A(MFtype,SFtype) \
2400  case FIELDTYPE_##MFtype: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_##SFtype); break;}
2401 
2402  switch (fieldType) {
2403  GETJSVAL_TYPE_A(SFRotation,v)
2404  /* GETJSVAL_TYPE_A(SFNode,handle) */
2405  /* not implemented yet? GETJSVAL_TYPE_A(SFVec2d,v) */
2406  GETJSVAL_TYPE_A(SFVec3d,v)
2407  GETJSVAL_TYPE_A(SFVec4d,v)
2408  GETJSVAL_TYPE_A(SFVec2f,v)
2409  GETJSVAL_TYPE_A(SFVec3f,v)
2410  GETJSVAL_TYPE_A(SFVec4f,v)
2411  GETJSVAL_TYPE_A(SFColor,v)
2412  GETJSVAL_TYPE_A(SFColorRGBA,v)
2413 
2414  GETJSVAL_TYPE_MF_A(MFRotation,SFRotation)
2415  GETJSVAL_TYPE_MF_A(MFVec2d,SFVec2d)
2416  GETJSVAL_TYPE_MF_A(MFVec3d,SFVec3d)
2417  GETJSVAL_TYPE_MF_A(MFVec4d,SFVec4d)
2418  GETJSVAL_TYPE_MF_A(MFVec2f,SFVec2f)
2419  GETJSVAL_TYPE_MF_A(MFVec3f,SFVec3f)
2420  GETJSVAL_TYPE_MF_A(MFVec4f,SFVec4f)
2421  GETJSVAL_TYPE_MF_A(MFColor,SFColor)
2422  GETJSVAL_TYPE_MF_A(MFColorRGBA,SFColorRGBA)
2423 
2424 
2425  case FIELDTYPE_SFInt32:
2426  case FIELDTYPE_SFBool: { /* SFBool */
2427  if (!JS_ValueToInt32(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&ival)) {
2428  printf ("error\n");
2429  ival=0;
2430  }
2431  memcpy ((void *)memptr, (void *)&ival,len);
2432  break;
2433  }
2434 
2435  case FIELDTYPE_SFDouble:
2436  case FIELDTYPE_SFTime: {
2437  if (!JS_ValueToNumber(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&tval)) tval=0.0;
2438  memcpy ((void *)memptr, (void *)&tval,len);
2439  break;
2440  }
2441 
2442  case FIELDTYPE_SFFloat: {
2443  if (!JS_ValueToNumber(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val),&tval)) tval=0.0;
2444  /* convert double precision to single, for X3D */
2445  fl[0] = (float) tval;
2446  memcpy ((void *)memptr, (void *)fl,len);
2447  break;
2448  }
2449 
2450  case FIELDTYPE_SFImage: {
2451  /* the string should be saved as an SFImage */
2452  strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2453 #if JS_VERSION < 185
2454  strp = JS_GetStringBytes(strval);
2455 #else
2456  strp = strpp = JS_EncodeString(scriptContext,strval);
2457 #endif
2458 
2459  Parser_scanStringValueToMem_B(any, FIELDTYPE_SFImage, strp, FALSE);
2460 #if JS_VERSION >= 185
2461  JS_free(scriptContext,strpp);
2462 #endif
2463  break;
2464  }
2465 
2466  case FIELDTYPE_SFString: {
2467  struct Uni_String *ms;
2468  intptr_t *newptr;
2469 
2470  strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2471 #if JS_VERSION < 185
2472  strp = JS_GetStringBytes(strval);
2473 #else
2474  strp = strpp = JS_EncodeString(scriptContext,strval);
2475 #endif
2476 
2477  /* copy the string over, delete the old one, if need be */
2478  /* printf ("fieldSet SFString, tn %d tptr %d offset from struct %d\n",
2479  tn, tptr, offsetof (struct X3D_TextureCoordinateGenerator, mode)); */
2480  newptr = (intptr_t *)memptr;
2481  ms = (struct Uni_String*) *newptr;
2482  verify_Uni_String (ms,strp);
2483 #if JS_VERSION >= 185
2484  JS_free(scriptContext,strpp);
2485 #endif
2486  break;
2487  }
2488 
2489 
2490  /* a series of Floats... */
2491  case FIELDTYPE_MFFloat: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFFloat); break;}
2492  case FIELDTYPE_MFInt32: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFInt32); break;}
2493  case FIELDTYPE_MFTime: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFTime); break;}
2494  case FIELDTYPE_MFDouble: {getJSMultiNumType (scriptContext, (struct Multi_Vec3f *)memptr,FIELDTYPE_SFDouble); break;}
2495  case FIELDTYPE_MFNode: {
2496  struct X3D_Node *mynode;
2497 
2498  strval = JS_ValueToString(scriptContext, *(jsval*)(tg->JScript.JSglobal_return_val));
2499 #if JS_VERSION < 185
2500  strp = JS_GetStringBytes(strval);
2501 #else
2502  strp = strpp = JS_EncodeString(scriptContext,strval);
2503 #endif
2504 
2505  /* we will have at least one node here, in an ascii string */
2506  while ((*strp > '\0') && (*strp <= ' ')) strp ++;
2507  /* are we at a bracket? */
2508  if (*strp == '[') strp ++;
2509  while ((*strp > '\0') && (*strp <= ' ')) strp ++;
2510 
2511  /* printf ("convertingthe following string to a pointer :%s:\n",strp); */
2512 
2513  mynode = X3D_NODE(atol(strp));
2514 #if JS_VERSION >= 185
2515  JS_free(scriptContext,strpp);
2516 #endif
2517 
2518  /* printf ("mynode is %p %d, \n",mynode,mynode);
2519  printf ("mynode is %p %d, type %d\n",mynode,mynode,mynode->_nodeType);
2520  printf ("calling getMFNodeType now\n"); */
2521 
2522 
2523  //getMFNodetype (mynode,(struct Multi_Node *)memptr,X3D_NODE(tn),extraData);
2524  any->mfnode.n = 1;
2525  any->mfnode.p = MALLOC(struct X3D_Node **, sizeof(struct X3D_Node *));
2526  any->mfnode.p[0] = mynode;
2527  //Q. can we do add/remove children outside?
2528  break;
2529  }
2530  case FIELDTYPE_MFString: {
2531  getMFStringtype (
2532  scriptContext,
2533  (jsval *)tg->JScript.JSglobal_return_val,
2534  (struct Multi_String *)memptr);
2535  break;
2536  }
2537 
2538  case FIELDTYPE_SFNode: {
2539  //unsigned int valuecopied;
2540  //unsigned int *ptr2value;
2541  /* printf ("doing TYPEA memcpy to %u, from %u, len %d\n",(void *)memptr, (void *) &(((SFNodeNative *)JSSFpointer)->handle),returnElementLength(FIELDTYPE_SFNode));*/
2542  memcpy ((void *)memptr, (void *) &(((SFNodeNative *)tg->CRoutes.JSSFpointer)->handle),returnElementLength(FIELDTYPE_SFNode));
2543  //ptr2value = (unsigned int*)memptr;
2544  //valuecopied = *ptr2value;
2545  //printf("value of memptr %u after memcpy in script route= %u\n",(void*)memptr,valuecopied);
2546  break;
2547  }
2548 
2549 
2550  default: { printf("WARNING: unhandled from type %s\n", stringFieldtypeType(fieldType));
2551  }
2552  }
2553 
2554  #ifdef SETFIELDVERBOSE
2555  printf ("done setField_javascriptEventOut\n");
2556  if (fieldType == FIELDTYPE_MFInt32) {
2557  printf ("setField_javascriptEventOut, checking the pointers...\n");
2558  printf ("node type is %s\n",stringNodeType(X3D_NODE(any)->_nodeType));
2559  }
2560  if (fieldType == FIELDTYPE_SFNode) {
2561  printf ("setField_javascriptEventOut, checking the pointers...\n");
2562  printf ("node type is %s\n",stringNodeType(X3D_NODE(any)->_nodeType));
2563  }
2564 
2565  #endif
2566 }
2567 
2568 void js_setField_javascriptEventOut(struct X3D_Node *tn,unsigned int tptr, int fieldType, unsigned len, int extraData, int actualscript) {
2569  struct CRscriptStruct *scriptcontrol;
2570 
2571  scriptcontrol = getScriptControlIndex(actualscript);
2572 #if defined(JS_THREADSAFE)
2573  JS_BeginRequest(scriptcontrol->cx);
2574 #endif
2575  setField_javascriptEventOut(tn,tptr,fieldType, len, extraData, scriptcontrol->cx);
2576 #if defined(JS_THREADSAFE)
2577  JS_EndRequest(scriptcontrol->cx);
2578 #endif
2579 }
2580 
2581 void js_setField_javascriptEventOut_B(union anyVrml* any, int fieldType, unsigned len, int extraData, int actualscript){
2582  struct CRscriptStruct *scriptcontrol;
2583 
2584  scriptcontrol = getScriptControlIndex(actualscript);
2585 #if defined(JS_THREADSAFE)
2586  JS_BeginRequest(scriptcontrol->cx);
2587 #endif
2588  setField_javascriptEventOut_B(any,fieldType, len, extraData, scriptcontrol->cx);
2589 
2590 #if defined(JS_THREADSAFE)
2591  JS_EndRequest(scriptcontrol->cx);
2592 #endif
2593 }
2594 
2595 
2596 /******************************************************************************/
2597 
2598 void set_one_ECMAtype (int tonode, int toname, int dataType, void *Data, int datalen) {
2599  char scriptline[100];
2600  jsval newval;
2601  JSContext *cx;
2602  JSObject *obj;
2603  struct CRscriptStruct *ScriptControl; // = getScriptControl();
2604  struct CRjsnameStruct *JSparamnames = getJSparamnames();
2605 
2606  #ifdef SETFIELDVERBOSE
2607  printf ("set_one_ECMAtype, to %d namepointer %d, fieldname %s, datatype %d length %d\n",
2608  tonode,toname,JSparamnames[toname].name,dataType,datalen);
2609  #endif
2610  ScriptControl = getScriptControlIndex(tonode);
2611  /* get context and global object for this script */
2612  cx = (JSContext*)ScriptControl->cx;
2613  obj = (JSObject*)ScriptControl->glob;
2614 
2615 #if defined(JS_THREADSAFE)
2616  JS_BeginRequest(cx);
2617 #endif
2618  /* set the time for this script */
2619  SET_JS_TICKTIME
2620 
2621  X3D_ECMA_TO_JS(cx, Data, datalen, dataType, &newval);
2622 
2623  /* get the variable name to hold the incoming value */
2624  sprintf (scriptline,"__eventIn_Value_%s", JSparamnames[toname].name);
2625 
2626  #ifdef SETFIELDVERBOSE
2627  printf ("set_one_ECMAtype, calling JS_DefineProperty on name %s obj %u, setting setECMANative, 0 \n",scriptline,obj);
2628  #endif
2629 
2630  if (!JS_DefineProperty(cx,obj, scriptline, newval, JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_PERMANENT)) {
2631  printf( "JS_DefineProperty failed for \"ECMA in\" at %s:%d.\n",__FILE__,__LINE__);
2632 #if defined(JS_THREADSAFE)
2633  JS_EndRequest(cx);
2634 #endif
2635  return;
2636  }
2637 
2638  /* is the function compiled yet? */
2639  COMPILE_FUNCTION_IF_NEEDED(toname)
2640 
2641  /* and run the function */
2642  RUN_FUNCTION (toname)
2643 
2644 #if defined(JS_THREADSAFE)
2645  JS_EndRequest(cx);
2646 #endif
2647 }
2648 
2649 /* setScriptECMAtype called by getField_ToJavascript for
2650  case FIELDTYPE_SFBool:
2651  case FIELDTYPE_SFFloat:
2652  case FIELDTYPE_SFTime:
2653  case FIELDTYPE_SFDouble:
2654  case FIELDTYPE_SFInt32:
2655  case FIELDTYPE_SFString:
2656 */
2657 
2658 void setScriptECMAtype (int num) {
2659  void *fn;
2660  int tptr;
2661  int len;
2662  int to_counter;
2663  CRnodeStruct *to_ptr = NULL;
2664  struct CRStruct *CRoutes = getCRoutes();
2665  struct CRjsnameStruct *JSparamnames = getJSparamnames();
2666 
2667  fn = offsetPointer_deref(void *, CRoutes[num].routeFromNode, CRoutes[num].fnptr);
2668  len = CRoutes[num].len;
2669 
2670  for (to_counter = 0; to_counter < CRoutes[num].tonode_count; to_counter++) {
2671  struct Shader_Script *myObj;
2672 
2673  to_ptr = &(CRoutes[num].tonodes[to_counter]);
2674  myObj = X3D_SCRIPT(to_ptr->routeToNode)->__scriptObj;
2675  /* printf ("setScriptECMAtype, myScriptNumber is %d\n",myObj->num); */
2676  tptr = to_ptr->foffset;
2677  set_one_ECMAtype (myObj->num, tptr, JSparamnames[tptr].type, fn,len);
2678  }
2679 }
2680 
2681 
2682 /* use Javascript to send in one element of an MF. datalen is in number of elements in type. */
2683 void set_one_MFElementType(int tonode, int toname, int dataType, void *Data, int datalen) {
2684  JSContext *cx;
2685  JSObject *obj;
2686  int elementlen;
2687  int x;
2688  char scriptline[20000];
2689 
2690  /* for PixelTextures we have: */
2691  //struct X3D_PixelTexture *mePix;
2692  //struct Multi_Int32 image;
2693 
2694  /* for MFStrings we have: */
2695  char *chptr;
2696  struct Uni_String **uniptr;
2697  struct CRscriptStruct *ScriptControl; // = getScriptControl();
2698  struct CRjsnameStruct *JSparamnames = getJSparamnames();
2699 
2700  /* get context and global object for this script */
2701  ScriptControl = getScriptControlIndex(tonode);
2702  cx = (JSContext*)ScriptControl->cx;
2703  obj = (JSObject*)ScriptControl->glob;
2704 
2705 #if defined(JS_THREADSAFE)
2706  JS_BeginRequest(cx);
2707 #endif
2708  /* set the TickTime (possibly again) for this context */
2709  SET_JS_TICKTIME
2710 
2711  /* make up the name */
2712  switch (dataType) {
2713  case FIELDTYPE_MFRotation: {
2714  JSObject *newMFObject;
2715  JSObject *newSFObject;
2716  SFRotationNative *SFRPptr;
2717  float *fp, *fp_in=(float *)Data;
2718 
2719  /* create a new MFRotation object... */
2720  newMFObject = JS_ConstructObject(cx, &MFRotationClass, NULL ,JS_GetParent(cx, obj));
2721  ADD_ROOT (cx, newMFObject)
2722 
2723  /* define the "length" property for this object */
2724  DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
2725 
2726  /* fill in private pointer area */
2727  elementlen = (int) sizeof (float);
2728  for (x=0; x<datalen; x++) {
2729  /* create a new SFRotation object */
2730  newSFObject = JS_ConstructObject(cx,&SFRotationClass,NULL, newMFObject);
2731  if ((SFRPptr = (SFRotationNative *)JS_GetPrivate(cx, newSFObject)) == NULL) {
2732  ConsoleMessage ("failure in getting SF class at %s:%d\n",__FILE__,__LINE__);
2733 #if defined(JS_THREADSAFE)
2734  JS_EndRequest(cx);
2735 #endif
2736  return;
2737  }
2738 
2739  /* fill the private pointer area */
2740  fp = (float *)fp_in; SFRPptr->v.c[0] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2741  fp = (float *)fp_in; SFRPptr->v.c[1] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2742  fp = (float *)fp_in; SFRPptr->v.c[2] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2743  fp = (float *)fp_in; SFRPptr->v.c[3] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2744 
2745  /* put this object into the MF class */
2746  if (!JS_DefineElement(cx, newMFObject, (jsint) x, OBJECT_TO_JSVAL(newSFObject),
2747  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
2748  printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
2749  }
2750  }
2751 
2752  /* set the length of this MF */
2753  SET_LENGTH (cx,newMFObject,datalen)
2754 
2755  /* set the global variable with this new MF object */
2756  SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
2757 
2758  /* run the function */
2759  COMPILE_FUNCTION_IF_NEEDED(toname)
2760  RUN_FUNCTION(toname)
2761  break;
2762  }
2763 
2764  case FIELDTYPE_MFVec3f: {
2765  JSObject *newMFObject;
2766  JSObject *newSFObject;
2767  SFVec3fNative *SFRPptr;
2768  float *fp, *fp_in=(float *)Data;
2769 
2770  /* create a new MFVec3f object... */
2771  newMFObject = JS_ConstructObject(cx, &MFVec3fClass, NULL ,JS_GetParent(cx, obj));
2772  ADD_ROOT (cx, newMFObject)
2773 
2774  /* define the "length" property for this object */
2775  DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
2776 
2777  /* fill in private pointer area */
2778  elementlen = (int) sizeof (float);
2779  for (x=0; x<datalen; x++) {
2780  /* create a new SFVec3f object */
2781  newSFObject = JS_ConstructObject(cx,&SFVec3fClass,NULL, newMFObject);
2782  if ((SFRPptr = (SFVec3fNative *)JS_GetPrivate(cx, newSFObject)) == NULL) {
2783  ConsoleMessage ("failure in getting SF class at %s:%d\n",__FILE__,__LINE__);
2784 #if defined(JS_THREADSAFE)
2785  JS_EndRequest(cx);
2786 #endif
2787  return;
2788  }
2789 
2790  /* fill the private pointer area */
2791  fp = (float *)fp_in; SFRPptr->v.c[0] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2792  fp = (float *)fp_in; SFRPptr->v.c[1] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2793  fp = (float *)fp_in; SFRPptr->v.c[2] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2794 
2795  /* put this object into the MF class */
2796  if (!JS_DefineElement(cx, newMFObject, (jsint) x, OBJECT_TO_JSVAL(newSFObject),
2797  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
2798  printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
2799  }
2800  }
2801 
2802  /* set the length of this MF */
2803  SET_LENGTH (cx,newMFObject,datalen)
2804 
2805  /* set the global variable with this new MF object */
2806  SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
2807 
2808  /* run the function */
2809  COMPILE_FUNCTION_IF_NEEDED(toname)
2810  RUN_FUNCTION(toname)
2811  break;
2812  }
2813 
2814  case FIELDTYPE_MFColor: {
2815  JSObject *newMFObject;
2816  JSObject *newSFObject;
2817  SFColorNative *SFRPptr;
2818  float *fp, *fp_in=(float *)Data;
2819 
2820  /* create a new MFColor object... */
2821  newMFObject = JS_ConstructObject(cx, &MFColorClass, NULL ,JS_GetParent(cx, obj));
2822  ADD_ROOT (cx, newMFObject)
2823 
2824  /* define the "length" property for this object */
2825  DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
2826 
2827  /* fill in private pointer area */
2828  elementlen = (int) sizeof (float);
2829  for (x=0; x<datalen; x++) {
2830  /* create a new SFColor object */
2831  newSFObject = JS_ConstructObject(cx,&SFColorClass,NULL, newMFObject);
2832  if ((SFRPptr = (SFColorNative *)JS_GetPrivate(cx, newSFObject)) == NULL) {
2833  ConsoleMessage ("failure in getting SF class at %s:%d\n",__FILE__,__LINE__);
2834 #if defined(JS_THREADSAFE)
2835  JS_EndRequest(cx);
2836 #endif
2837  return;
2838  }
2839 
2840  /* fill the private pointer area */
2841  fp = (float *)fp_in; SFRPptr->v.c[0] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2842  fp = (float *)fp_in; SFRPptr->v.c[1] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2843  fp = (float *)fp_in; SFRPptr->v.c[2] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2844 
2845  /* put this object into the MF class */
2846  if (!JS_DefineElement(cx, newMFObject, (jsint) x, OBJECT_TO_JSVAL(newSFObject),
2847  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
2848  printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
2849  }
2850  }
2851 
2852  /* set the length of this MF */
2853  SET_LENGTH (cx,newMFObject,datalen)
2854 
2855  /* set the global variable with this new MF object */
2856  SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
2857 
2858  /* run the function */
2859  COMPILE_FUNCTION_IF_NEEDED(toname)
2860  RUN_FUNCTION(toname)
2861  break;
2862  }
2863 
2864  case FIELDTYPE_MFVec2f: {
2865  JSObject *newMFObject;
2866  JSObject *newSFObject;
2867  SFVec2fNative *SFRPptr;
2868  float *fp, *fp_in=(float *)Data;
2869 
2870  /* create a new MFVec2f object... */
2871  newMFObject = JS_ConstructObject(cx, &MFVec2fClass, NULL ,JS_GetParent(cx, obj));
2872  ADD_ROOT (cx, newMFObject)
2873 
2874  /* define the "length" property for this object */
2875  DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
2876 
2877  /* fill in private pointer area */
2878  elementlen = (int) sizeof (float);
2879  for (x=0; x<datalen; x++) {
2880  /* create a new SFVec2f object */
2881  newSFObject = JS_ConstructObject(cx,&SFVec2fClass,NULL, newMFObject);
2882  if ((SFRPptr = (SFVec2fNative *)JS_GetPrivate(cx, newSFObject)) == NULL) {
2883  ConsoleMessage ("failure in getting SF class at %s:%d\n",__FILE__,__LINE__);
2884 #if defined(JS_THREADSAFE)
2885  JS_EndRequest(cx);
2886 #endif
2887  return;
2888  }
2889 
2890  /* fill the private pointer area */
2891  fp = (float *)fp_in; SFRPptr->v.c[0] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2892  fp = (float *)fp_in; SFRPptr->v.c[1] = *fp; fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2893 
2894  /* put this object into the MF class */
2895  if (!JS_DefineElement(cx, newMFObject, (jsint) x, OBJECT_TO_JSVAL(newSFObject),
2896  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
2897  ConsoleMessage("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
2898  }
2899  }
2900 
2901  /* set the length of this MF */
2902  SET_LENGTH (cx,newMFObject,datalen)
2903 
2904  /* set the global variable with this new MF object */
2905  SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
2906 
2907  /* run the function */
2908  COMPILE_FUNCTION_IF_NEEDED(toname)
2909  RUN_FUNCTION(toname)
2910  break;
2911  }
2912 
2913 
2914  case FIELDTYPE_MFFloat: {
2915  JSObject *newMFObject;
2916  jsval newjsval;
2917  float *fp, *fp_in=(float *)Data;
2918  /* create a new MFFloat object... */
2919  newMFObject = JS_ConstructObject(cx, &MFFloatClass, NULL ,JS_GetParent(cx, obj));
2920  ADD_ROOT (cx, newMFObject)
2921 
2922  /* define the "length" property for this object */
2923  DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
2924 
2925  /* fill in private pointer area */
2926  elementlen = (int) sizeof (float);
2927  for (x=0; x<datalen; x++) {
2928  /* create a new SFFloat object */
2929 
2930  fp = (float *)fp_in;
2931  JS_NewNumberValue(cx,(double)*fp,&newjsval);
2932  fp_in = offsetPointer_deref(float *,fp_in,elementlen);
2933 
2934  /* put this object into the MF class */
2935  if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
2936  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
2937  printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
2938  }
2939  }
2940 
2941  /* set the length of this MF */
2942  SET_LENGTH (cx,newMFObject,datalen)
2943 
2944  /* set the global variable with this new MF object */
2945  SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
2946 
2947  /* run the function */
2948  COMPILE_FUNCTION_IF_NEEDED(toname)
2949  RUN_FUNCTION(toname)
2950  break;
2951  }
2952  case FIELDTYPE_MFTime: {
2953  JSObject *newMFObject;
2954  jsval newjsval;
2955  double *dp, *dp_in=(double *)Data;
2956 
2957  /* create a new MFTime object... */
2958  newMFObject = JS_ConstructObject(cx, &MFTimeClass, NULL ,JS_GetParent(cx, obj));
2959  ADD_ROOT (cx, newMFObject)
2960 
2961  /* define the "length" property for this object */
2962  DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
2963 
2964  /* fill in private pointer area */
2965  elementlen = (int) sizeof (double);
2966  for (x=0; x<datalen; x++) {
2967  /* create a new SFTime object */
2968 
2969  dp = (double *)dp_in;
2970  JS_NewNumberValue(cx,(double)*dp,&newjsval);
2971  dp_in = offsetPointer_deref(double *,dp_in,elementlen);
2972 
2973  /* put this object into the MF class */
2974  if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
2975  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
2976  printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
2977  }
2978  }
2979 
2980  /* set the length of this MF */
2981  SET_LENGTH (cx,newMFObject,datalen)
2982 
2983  /* set the global variable with this new MF object */
2984  SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
2985 
2986  /* run the function */
2987  COMPILE_FUNCTION_IF_NEEDED(toname)
2988  RUN_FUNCTION(toname)
2989  break;
2990  }
2991  case FIELDTYPE_MFInt32: {
2992  JSObject *newMFObject;
2993  jsval newjsval;
2994  int *ip, *ip_in=(int *)Data;
2995 
2996  /* create a new MFInt32 object... */
2997  newMFObject = JS_ConstructObject(cx, &MFInt32Class, NULL ,JS_GetParent(cx, obj));
2998  ADD_ROOT (cx, newMFObject)
2999 
3000  /* define the "length" property for this object */
3001  DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3002 
3003  /* fill in private pointer area */
3004  elementlen = (int) sizeof (float);
3005  for (x=0; x<datalen; x++) {
3006  /* create a new SFInt32 object */
3007 
3008  ip = (int *)ip_in;
3009  newjsval = INT_TO_JSVAL((int)ip); /* NOTE--this is assigning the pointer itself as an int, not its content */
3010  ip_in = offsetPointer_deref(int *,ip_in,elementlen);
3011 
3012  /* put this object into the MF class */
3013  if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
3014  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3015  printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3016  }
3017  }
3018 
3019  /* set the length of this MF */
3020  SET_LENGTH (cx,newMFObject,datalen)
3021 
3022  /* set the global variable with this new MF object */
3023  SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3024 
3025  /* run the function */
3026  COMPILE_FUNCTION_IF_NEEDED(toname)
3027  RUN_FUNCTION(toname)
3028  break;
3029  }
3030  case FIELDTYPE_MFString: {
3031  JSObject *newMFObject;
3032  jsval newjsval;
3033  struct Uni_String * *ip_in=(struct Uni_String **)Data;
3034 
3035  /* create a new MFString object... */
3036  newMFObject = JS_ConstructObject(cx, &MFStringClass, NULL ,JS_GetParent(cx, obj));
3037  ADD_ROOT (cx, newMFObject)
3038 
3039  /* Data points to a Uni_String */
3040  uniptr = (struct Uni_String **) ip_in;
3041 
3042  /* define the "length" property for this object */
3043  DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3044 
3045  /* fill in private pointer area */
3046  for (x=0; x<datalen; x++) {
3047  /* create a new SFString object */
3048 
3049  chptr = uniptr[x]->strptr;
3050  newjsval = STRING_TO_JSVAL( JS_NewStringCopyZ(cx,chptr));
3051 
3052  /* put this object into the MF class */
3053  if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
3054  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3055  printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3056  }
3057  }
3058 
3059  /* set the length of this MF */
3060  SET_LENGTH (cx,newMFObject,datalen)
3061 
3062  /* set the global variable with this new MF object */
3063  SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3064 
3065  /* run the function */
3066  COMPILE_FUNCTION_IF_NEEDED(toname)
3067  RUN_FUNCTION(toname)
3068  break;
3069  }
3070  case FIELDTYPE_MFNode: {
3071  JSObject *newMFObject;
3072  jsval newjsval;
3073  double *ip, *ip_in=(double *)Data;
3074  /* create a new MFNode object... */
3075  newMFObject = JS_ConstructObject(cx, &MFNodeClass, NULL ,JS_GetParent(cx, obj));
3076  ADD_ROOT (cx, newMFObject)
3077 
3078  /* define the "length" property for this object */
3079  DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3080 
3081  /* fill in private pointer area */
3082  elementlen = (int) sizeof (void *);
3083  for (x=0; x<datalen; x++) {
3084  ip = ip_in;
3085  newjsval = INT_TO_JSVAL((int)ip); /* NOTE--assigning pointer itself as int, not its content */
3086  ip_in = offsetPointer_deref(double *,ip_in,elementlen);
3087 
3088  /* put this object into the MF class */
3089  if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
3090  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3091  printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3092  }
3093  }
3094 
3095  /* set the length of this MF */
3096  SET_LENGTH (cx,newMFObject,datalen)
3097 
3098  /* set the global variable with this new MF object */
3099  SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3100 
3101  /* run the function */
3102  COMPILE_FUNCTION_IF_NEEDED(toname)
3103  RUN_FUNCTION(toname)
3104  break;
3105  }
3106 
3107  case FIELDTYPE_SFImage: {
3108  JSObject *newMFObject;
3109  jsval newjsval;
3110  int *ip_in=(int *)Data;
3111 
3112  /* create a new MFNode object... */
3113  newMFObject = JS_ConstructObject(cx, &SFImageClass, NULL ,JS_GetParent(cx, obj));
3114  ADD_ROOT (cx, newMFObject)
3115 
3116  /* define the "length" property for this object */
3117  DEFINE_LENGTH_NORV(cx,newMFObject,datalen)
3118 
3119  /* fill in private pointer area */
3120  for (x=0; x<datalen; x++) {
3121  newjsval = INT_TO_JSVAL(ip_in[x]);
3122  /* put this object into the MF class */
3123  if (!JS_DefineElement(cx, newMFObject, (jsint) x, newjsval,
3124  JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB3, JSPROP_ENUMERATE)) {
3125  printf("failure in inserting SF class at %s:%d\n",__FILE__,__LINE__);
3126  }
3127  }
3128 
3129  /* set the length of this MF */
3130  SET_LENGTH (cx,newMFObject,datalen)
3131 
3132  /* set the global variable with this new MF object */
3133  SET_EVENTIN_VALUE (cx,obj,toname,newMFObject)
3134 
3135  /* run the function */
3136  COMPILE_FUNCTION_IF_NEEDED(toname)
3137  RUN_FUNCTION(toname)
3138 
3139  break;
3140  }
3141 
3142  default: {
3143  printf ("setMFElement, SHOULD NOT DISPLAY THIS\n");
3144  strcat (scriptline,"(");
3145  }
3146  }
3147 #if defined(JS_THREADSAFE)
3148  JS_EndRequest(cx);
3149 #endif
3150 }
3151 
3152 /****************************************************************/
3153 /* sets a SFVec3f and SFColor and SFVec3d */
3154 /* and SFRotation and SFVec2fin a script */
3155 /* */
3156 /* all *Native types have the same structure of the struct - */
3157 /* we are just looking for the pointer, thus we can handle */
3158 /* multi types here */
3159 /* sets a SFVec3f and SFColor in a script */
3160 /****************************************************************/
3161 
3162 /* get a pointer to the internal data for this object, or return NULL on error */
3163 void **getInternalDataPointerForJavascriptObject(JSContext *cx, JSObject *obj, int tnfield) {
3164  char scriptline[100];
3165  void *_privPtr;
3166  JSObject *sfObj;
3167  jsval retval;
3168  struct CRjsnameStruct *JSparamnames = getJSparamnames();
3169 
3170  /* NOTE -- this is only called once, and the caller has already defined a JS_BeginRequest() */
3171 
3172  /* get the variable name to hold the incoming value */
3173  sprintf (scriptline,"__eventIn_Value_%s", JSparamnames[tnfield].name);
3174  #ifdef SETFIELDVERBOSE
3175  printf ("getInternalDataPointerForJavascriptObject: line %s\n",scriptline);
3176  #endif
3177 
3178  if (!JS_GetProperty(cx,obj,scriptline,&retval))
3179  printf ("JS_GetProperty failed in set_one_MultiElementType.\n");
3180 
3181  if (!JSVAL_IS_OBJECT(retval))
3182  printf ("set_one_MultiElementType - not an object\n");
3183 
3184  sfObj = JSVAL_TO_OBJECT(retval);
3185 
3186  if ((_privPtr = JS_GetPrivate(cx, sfObj)) == NULL)
3187  printf("JS_GetPrivate failed set_one_MultiElementType.\n");
3188 
3189  if (_privPtr == NULL) return NULL;
3190 
3191  /* what kind of class of object is this? */
3192 
3193  /* we look at EVERY kind of native class found in "jsNative.h" even
3194  if it may not be ever used here */
3195 
3196  if (JS_InstanceOf(cx, sfObj, &SFVec3fClass, NULL)) {
3197  SFVec3fNative *me = (SFVec3fNative *)_privPtr;
3198  return (void **) &me->v;
3199 
3200  } else if (JS_InstanceOf(cx, sfObj, &SFVec3dClass, NULL)) {
3201  SFVec3dNative *me = (SFVec3dNative *)_privPtr;
3202  return (void **) &me->v;
3203 
3204  } else if (JS_InstanceOf(cx, sfObj, &SFRotationClass, NULL)) {
3205  SFRotationNative *me = (SFRotationNative *)_privPtr;
3206  return (void **) &me->v;
3207 
3208  } else if (JS_InstanceOf(cx, sfObj, &SFVec2fClass, NULL)) {
3209  SFVec2fNative *me = (SFVec2fNative *)_privPtr;
3210  return (void **) &me->v;
3211 
3212  } else if (JS_InstanceOf(cx, sfObj, &SFColorClass, NULL)) {
3213  SFColorNative *me = (SFColorNative *)_privPtr;
3214  return (void **) &me->v;
3215 
3216  } else if (JS_InstanceOf(cx, sfObj, &SFColorRGBAClass, NULL)) {
3217  SFColorRGBANative *me = (SFColorRGBANative *)_privPtr;
3218  return (void **) &me->v;
3219 
3220  } else if (JS_InstanceOf(cx, sfObj, &SFVec4fClass, NULL)) {
3221  SFVec4fNative *me = (SFVec4fNative *)_privPtr;
3222  return (void **) &me->v;
3223 
3224  } else if (JS_InstanceOf(cx, sfObj, &SFVec4dClass, NULL)) {
3225  SFVec4dNative *me = (SFVec4dNative *)_privPtr;
3226  return (void **) &me->v;
3227 
3228  } else if (JS_InstanceOf(cx, sfObj, &SFNodeClass, NULL)) {
3229  SFNodeNative *me = (SFNodeNative *)_privPtr;
3230  return (void **) &me->handle;;
3231  //JAS return (void **) &me->v;
3232 
3233  } else if (JS_InstanceOf(cx, sfObj, &SFImageClass, NULL)) {
3234  //SFImageNative *me = (SFImageNative *)_privPtr;
3235  //JAS return (void **) &me->v;
3236 
3237  }
3238 
3239  ConsoleMessage ("getInternalDataPointerForJavascriptObject malfunction");
3240 
3241  return NULL;
3242 }
3243 
3244 
3245 
3246 /* really do the individual set; used by script routing and EAI sending to a script */
3247 void set_one_MultiElementType (int tonode, int tnfield, void *Data, int dataLen ) {
3248  char scriptline[100];
3249  JSContext *cx;
3250  JSObject *obj;
3251  void **pp;
3252  struct CRscriptStruct *ScriptControl; // = getScriptControl();
3253  struct CRjsnameStruct *JSparamnames = getJSparamnames();
3254 
3255  /* get context and global object for this script */
3256  ScriptControl = getScriptControlIndex(tonode);
3257  cx = (JSContext*)ScriptControl->cx;
3258  obj = (JSObject*)ScriptControl->glob;
3259 
3260 #if defined(JS_THREADSAFE)
3261  JS_BeginRequest(cx);
3262 #endif
3263  /* set the time for this script */
3264  SET_JS_TICKTIME
3265 
3266  /* copy over the data from the VRML side into the script variable. */
3267  pp = getInternalDataPointerForJavascriptObject(cx,obj,tnfield);
3268 
3269  if (pp != NULL) {
3270  memcpy (pp,Data, dataLen);
3271  /* printf ("set_one_MultiElementType, dataLen %d, sizeof(double) %d\n",dataLen, sizeof(double));
3272  printf ("and, sending the data to pointer %p\n",pp); */
3273  }
3274 
3275  /* is the function compiled yet? */
3276  COMPILE_FUNCTION_IF_NEEDED(tnfield)
3277 
3278  /* and run the function */
3279  #ifdef SETFIELDVERBOSE
3280  printf ("set_one_MultiElementType: running script %s\n",scriptline);
3281  #endif
3282 
3283  RUN_FUNCTION (tnfield)
3284 
3285 #if defined(JS_THREADSAFE)
3286  JS_EndRequest(cx);
3287 #endif
3288 }
3289 
3290 int runQueuedDirectOutputs(){
3291  //stub for SM and STUBS (DUK has it)
3292  return FALSE;
3293 }
3294 
3295 
3296 
3297 #endif /* !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK) */