FreeWRL/FreeX3D  3.0.0
fwMotifWindow.c
1 /*
2 
3  FreeWRL support library.
4  Create Motif window, widget, menu. Manage events.
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 #include <config.h>
28 #if !(defined(_ANDROID))
29 
30 #include <system.h>
31 #include <display.h>
32 #if KEEP_FV_INLIB
33 #include <internal.h>
34 
35 #include <libFreeWRL.h>
36 
37 #include <threads.h>
38 
39 #include "../main/MainLoop.h"
40 #include "../vrml_parser/Structs.h"
41 #include "../opengl/OpenGL_Utils.h"
42 #include "../scenegraph/Viewer.h"
43 #include "../ui/common.h"
44 
45 #include <Xm/MainW.h>
46 #include <Xm/RowColumn.h>
47 #include <Xm/PushB.h>
48 #include <Xm/ToggleB.h>
49 #include <Xm/CascadeB.h>
50 #include <Xm/TextF.h>
51 #include <Xm/Separator.h>
52 #include <Xm/PanedW.h>
53 #include <Xm/Text.h>
54 #include <Xm/ScrolledW.h>
55 #include <Xm/FileSB.h>
56 #include <Xm/SelectioB.h>
57 #include <Xm/MessageB.h>
58 #include <Xm/DrawingA.h> /* simple drawing area */
59 
60 #define ABOUT_FREEWRL "FreeWRL Version %s\n \
61 %s %s.\n \n \
62 FreeWRL is a VRML/X3D Browser for OS X and Unix.\n \n \
63 Thanks to the Open Source community for all the help received.\n \
64 http://freewrl.sf.net"
65 
66 #define DJ_KEEP_COMPILER_WARNING 0
67 
68 /* static String defaultResources[200]; */
69 static int MainWidgetRealized = FALSE;
70 
71 XtAppContext Xtcx;
72 
73 static Widget freewrlTopWidget, mainw, menubar;
74 static Widget frame, freewrlDrawArea;
75 static Widget about_widget;
76 static Widget newFileWidget;
77 
78 static Arg buttonArgs[10]; static int buttonArgc = 0;
79 
80 extern char myMenuStatus[];
81 
82 static void fv_createMenuBar(void);
83 static void fv_createDrawingFrame(void);
84 
85 
86 static void myXtManageChild (int c, Widget child)
87 {
88 #ifdef XTDEBUG
89  printf ("at %d, managing %d\n",c, child);
90 #endif
91  if (child != NULL) XtManageChild (child);
92 }
93 
94 
95 /* see if/when we become iconified - if so, dont bother doing OpenGL stuff */
96 static void StateWatcher (Widget w, XtPointer unused, XEvent *event, Boolean *cont)
97 {
98 #ifdef XEVENT_VERBOSE
99  // Used to track down TouchSensor loosing event with Motif (direct X11 is ok)
100  TRACE_MSG("freewrlTopWidget [StateWatch] went through (xm callback): widget %p event %p\n", (void*)w, (void*)event);
101 #endif
102  if (event->type == MapNotify) setDisplayed (TRUE);
103  else if (event->type == UnmapNotify) setDisplayed (FALSE);
104 }
105 
106 static void fv_DrawArea_events (Widget w, XtPointer unused, XEvent *event, Boolean *cont)
107 {
108 #ifdef XEVENT_VERBOSE
109  // Used to track down TouchSensor loosing event with Motif (direct X11 is ok)
110 
111  XWindowAttributes attr;
112  XSetWindowAttributes set_attr;
113 
114  TRACE_MSG("fv_DrawArea event went through (xm callback): widget %p event %p\n", (void*)w, (void*)event);
115 
116  memset(&attr, 0, sizeof(attr));
117  memset(&set_attr, 0, sizeof(set_attr));
118 
119  /* Get window attributes and examine the event mask */
120  XGetWindowAttributes(Xdpy, Xwin, &attr);
121  TRACE_MSG("DrawArea event mask: %lu\n", attr.your_event_mask);
122  if (!(attr.your_event_mask & PointerMotionMask)) {
123  TRACE_MSG("DrawArea window not configured to receive PointerMotionMask...\n");
124  }
125  /* Set event mask to catch mouse motion events */
126  set_attr.event_mask = attr.your_event_mask | PointerMotionMask;
127  XChangeWindowAttributes(Xdpy, Xwin, CWEventMask, &set_attr);
128 
129 #endif
130 
131  /* This event should be passed to FreeWRL (MainLoop) control */
132  DEBUG_XEV("EVENT through MOTIF\n");
133  handle_Xevents(*event);
134 }
135 
139 int fv_create_main_window(freewrl_params_t * params) //int argc, char *argv[])
140 {
141  int argc_out = 0;
142  char *argv_out[1] = { NULL };
143  Dimension width, height;
144  Arg initArgs[10]; int initArgc = 0;
145 
146  /* XtVaAppInitialize ??? */
147  XtSetArg(initArgs[initArgc], XmNlabelString, XmStringCreate(getWindowTitle(), XmSTRING_DEFAULT_CHARSET)); initArgc++;
148  XtSetArg(initArgs[initArgc], XmNheight, params->height); initArgc++;
149  XtSetArg(initArgs[initArgc], XmNwidth, params->width); initArgc++;
150  XtSetArg(initArgs[initArgc], XmNmappedWhenManaged, False); initArgc++;
151 
156  XtToolkitInitialize();
157  Xtcx = XtCreateApplicationContext();
158 
159  XtDisplayInitialize(Xtcx, Xdpy, "FreeWRL", "FreeWRL_class", NULL, 0, &argc_out, argv_out);
160 
161  freewrlTopWidget = XtAppCreateShell("FreeWRL", "FreeWRL_class", applicationShellWidgetClass, Xdpy, initArgs, initArgc);
162 
163  if (!freewrlTopWidget) {
164  ERROR_MSG("Can't initialize Motif\n");
165  return FALSE;
166  }
167 
168  /* Inform Motif that we have our visual and colormap already ... (before top level is realized) */
169  XtVaSetValues(freewrlTopWidget,
170  XmNdepth, Xvi->depth,
171  XmNvisual, Xvi->visual,
172  XmNcolormap, colormap,
173  NULL);
174 
175  mainw = XmCreateMainWindow(freewrlTopWidget, getWindowTitle(), NULL, 0);
176  if (!mainw)
177  return FALSE;
178 
179  myXtManageChild(29, mainw);
180 
181  /* Create a menu bar. */
182  fv_createMenuBar();
183 
184  /* Create a framed drawing area for OpenGL rendering. */
185  fv_createDrawingFrame();
186 
187  /* Set up the application's window layout. */
188  XtVaSetValues(mainw,
189  XmNworkWindow, frame,
190  XmNcommandWindow, NULL,
191  XmNmenuBar, menubar,
192  NULL);
193 
194 
195  XtRealizeWidget (freewrlTopWidget);
196 
197  /* FIXME: see fwBareWindow.c */
198  /* Roberto Gerson */
199  /* If -d is setted, so reparent the window */
200  if (params->winToEmbedInto != INT_ID_UNDEFINED){
201  printf("fwMotifWindow::Trying to reparent window: %ld, to new parent: %ld\n",
202  XtWindow(freewrlTopWidget),
203  params->winToEmbedInto);
204 
205  XReparentWindow(XtDisplay(freewrlTopWidget),
206  XtWindow(freewrlTopWidget),
207  (Window) params->winToEmbedInto, 0, 0);
208 
209  XMapWindow(XtDisplay(freewrlTopWidget), XtWindow(freewrlTopWidget));
210  }
211 
212  XFlush(XtDisplay(freewrlTopWidget));
213 
214  MainWidgetRealized = XtIsRealized(freewrlTopWidget); /*TRUE;*/
215  TRACE_MSG("fv_create_main_window: top widget realized: %s\n", BOOL_STR(MainWidgetRealized));
216 
217  Xwin = XtWindow(freewrlTopWidget);
218  GLwin = XtWindow(freewrlDrawArea);
219 
220  /* now, lets tell the OpenGL window what its dimensions are */
221 
222  XtVaGetValues(freewrlDrawArea, XmNwidth, &width, XmNheight, &height, NULL);
223  /* printf("%s,%d fv_create_main_window %d, %d\n",__FILE__,__LINE__,width,height); */
224  fv_setScreenDim(width,height);
225 
226  /* lets see when this goes iconic */
227  XtAddEventHandler(freewrlTopWidget, StructureNotifyMask, FALSE, StateWatcher, NULL);
228  /* all events for DrawArea should be passed to FreeWRL (MainLoop) control */
229  XtAddEventHandler(freewrlDrawArea, event_mask, False, fv_DrawArea_events, NULL);
230 
231  return TRUE;
232 }
233 
234 /************************************************************************
235 
236 Callbacks to handle button presses, etc.
237 
238 ************************************************************************/
239 
240 /* Label strings are "broken" on some Motifs. See:
241  * http://www.faqs.org/faqs/motif-faq/part5/
242  */
243 /* both of these fail on Ubuntu 6.06 */
244 /* diastring = XmStringCreateLtoR(ns,XmFONTLIST_DEFAULT_TAG); */
245 /*diastring = XmStringCreateLocalized(ns); */
246 
247 static XmString xec_NewString(char *s)
248 {
249  XmString xms1;
250  XmString xms2;
251  XmString line;
252  XmString separator;
253  char *p;
254  char *t = XtNewString(s); /* Make a copy for strtok not to */
255  /* damage the original string */
256 
257  separator = XmStringSeparatorCreate();
258  p = strtok(t,"\n");
259  xms1 = XmStringCreateLocalized(p);
260 
261  /* FIXME: ???? why NULL here */
262  while ((p = strtok(NULL,"\n")))
263  {
264  line = XmStringCreateLocalized(p);
265  xms2 = XmStringConcat(xms1,separator);
266  XmStringFree(xms1);
267  xms1 = XmStringConcat(xms2,line);
268  XmStringFree(xms2);
269  XmStringFree(line);
270  }
271 
272  XmStringFree(separator);
273  XtFree(t);
274  return xms1;
275 }
276 
277 /* Callbacks */
278 static void fv_aboutFreeWRLpopUp (Widget w, XtPointer data, XtPointer callData)
279 {
280 
281  int ac;
282  Arg args[10];
283  const char *ver;
284  char *msg, *rdr, *vendor;
285  XmString diastring;
286  ac = 0;
287 
288  ver = libFreeWRL_get_version();
289 
290  rdr = (char *)glGetString(GL_RENDERER); // JAS - was gglobal()->display.rdr_caps.renderer;
291  vendor = (char *)glGetString(GL_VENDOR); // JAS - was gglobal()->display.rdr_caps.vendor;
292 
293  msg = MALLOC(void *, strlen(ABOUT_FREEWRL) + strlen(ver)
294  + strlen(rdr) + strlen(vendor));
295  sprintf(msg, ABOUT_FREEWRL, ver, rdr, vendor);
296 
297  diastring = xec_NewString(msg);
298  XtSetArg(args[ac], XmNmessageString, diastring); ac++;
299  XtSetValues(about_widget, args, ac);
300  XmStringFree(diastring);
301  FREE(msg);
302 
303  myXtManageChild(2,about_widget);
304 }
305 
306 /* quit selected */
307 static void fv_quitMenuBar (Widget w, XtPointer data, XtPointer callData)
308 {
309  fwl_doQuit(__FILE__,__LINE__);
310 }
311 
312 static void fv_reloadFile (Widget w, XtPointer data, XtPointer callData)
313 {
314  ConsoleMessage ("reloading %s", BrowserFullPath);
315  /* FIXME: implement reload function */
316 }
317 
318 /* file selection dialog box, ok button pressed */
319 static void fv_fileSelectPressed (Widget w, XtPointer data, XmFileSelectionBoxCallbackStruct *callData)
320 {
321  char *newfile;
322 
323  /* get the filename */
324  XmStringGetLtoR(callData->value,
325  XmSTRING_DEFAULT_CHARSET, &newfile);
326 
327  if (!Anchor_ReplaceWorld(newfile)) {
328  /* error message */
329  }
330  XtUnmanageChild(w);
331 }
332 
333 /* file selection dialog box cancel button - just get rid of widget */
334 static void fv_unManageMe (Widget widget, XtPointer client_data,
335  XmFileSelectionBoxCallbackStruct *selection)
336 {
337  XtUnmanageChild(widget);
338 }
339 
340 /* new file popup - user wants to load a new file */
341 static void fv_newFilePopup(Widget cascade_button, char *text, XmPushButtonCallbackStruct *cbs)
342 {
343  myXtManageChild(4,newFileWidget);
344  XtPopup(XtParent(newFileWidget), XtGrabNone);
345 }
346 
347 #ifdef DOESNOTGETICONICSTATE
348 /* resize, configure events */
349 static void fv_GLAreaexpose (Widget w, XtPointer data, XtPointer callData)
350 {
351  XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData;
352  switch (cd->reason) {
353  case XmCR_EXPOSE: printf ("got expose event \n");
354  default: printf ("not known event, %d\n",cd->reason);
355  }
356 }
357 #endif
358 
359 /* resize, configure events */
360 static void fv_GLArearesize (Widget w, XtPointer data, XtPointer callData)
361 {
362 /* XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData; */
363  Dimension width, height;
364 
365  XtVaGetValues (w, XmNwidth, &width, XmNheight, &height, NULL);
366  /* printf("%s,%d GLArearesize %d, %d\n",__FILE__,__LINE__,width,height); */
367  fv_setScreenDim (width,height);
368 }
369 
370 /* remove this button from this SelectionBox widget */
371 static void fv_removeWidgetFromSelect (Widget parent,
372 #if NeedWidePrototypes
373  unsigned int
374 #else
375  unsigned char
376 #endif
377  button) {
378 
379  Widget tmp;
380 
381  tmp = XmSelectionBoxGetChild(parent, button);
382  if (tmp == NULL) {
383  printf ("hmmm - button does not exist\n");
384  } else {
385  XtUnmanageChild(tmp);
386  }
387 }
388 
389 /* start up the browser, and point it to www.crc.ca/FreeWRL */
390 static void fv_freewrlHomePopup (Widget w, XtPointer data, XtPointer callData)
391 {
392 #if DJ_KEEP_COMPILER_WARNING
393  #define MAXLINE 2000
394 #endif
395  const char *browser;
396  char *sysline;
397  const char pattern[] = "%s http://freewrl.sourceforge.net &";
398 
399  browser = freewrl_get_browser_program();
400  if (!browser) {
401  browser = BROWSER;
402  }
403  sysline = MALLOC(char *, strlen(browser)+strlen(pattern));
404  sprintf(sysline, pattern, browser);
405 
406  freewrlSystem(sysline);
407 
408  FREE(sysline);
409 }
410 
411 #ifdef XTDEBUG
412 /* for debugging... */
413 printEvent (XEvent event)
414 {
415  switch (event.type) {
416  case KeyPress: printf ("KeyPress"); break;
417  case KeyRelease: printf ("KeyRelease"); break;
418  case ButtonPress: printf ("ButtonPress"); break;
419  case ButtonRelease: printf ("ButtonRelease"); break;
420  case MotionNotify: printf ("MotionNotify"); break;
421  case EnterNotify: printf ("EnterNotify"); break;
422  case LeaveNotify: printf ("LeaveNotify"); break;
423  case FocusIn: printf ("FocusIn"); break;
424  case FocusOut: printf ("FocusOut"); break;
425  case KeymapNotify: printf ("KeymapNotify"); break;
426  case Expose: printf ("Expose"); break;
427  case GraphicsExpose: printf ("GraphicsExpose"); break;
428  case NoExpose: printf ("NoExpose"); break;
429  case VisibilityNotify: printf ("VisibilityNotify"); break;
430  case CreateNotify: printf ("CreateNotify"); break;
431  case DestroyNotify: printf ("DestroyNotify"); break;
432  case UnmapNotify: printf ("UnmapNotify"); break;
433  case MapNotify: printf ("MapNotify"); break;
434  case MapRequest: printf ("MapRequest"); break;
435  case ReparentNotify: printf ("ReparentNotify"); break;
436  case ConfigureNotify: printf ("ConfigureNotify"); break;
437  case ConfigureRequest: printf ("ConfigureRequest"); break;
438  case GravityNotify: printf ("GravityNotify"); break;
439  case ResizeRequest: printf ("ResizeRequest"); break;
440  case CirculateNotify: printf ("CirculateNotify"); break;
441  case CirculateRequest: printf ("CirculateRequest"); break;
442  case PropertyNotify: printf ("PropertyNotify"); break;
443  case SelectionClear: printf ("SelectionClear"); break;
444  case SelectionRequest: printf ("SelectionRequest"); break;
445  case SelectionNotify: printf ("SelectionNotify"); break;
446  case ColormapNotify: printf ("ColormapNotify"); break;
447  case ClientMessage: printf ("ClientMessage"); break;
448  case MappingNotify: printf ("MappingNotify"); break;
449  default :printf ("Event out of range - %d",event.type);
450  }
451  printf ("\n");
452 }
453 #endif
454 
455 /* File pulldown menu */
456 static void fv_createFilePulldown()
457 {
458  Widget menupane, btn, cascade;
459 
460  XmString mask;
461  int ac;
462  Arg args[10];
463 
464  /* Create the FileSelectionDialog */
465  memset(args, 0, sizeof(args));
466  ac = 0;
467  mask = XmStringCreateLocalized("*.x3d");
468  XtSetArg(args[ac], XmNdirMask, mask); ac++;
469 
470  /* newFileWidget = XmCreateFileSelectionDialog(menubar, "select", args, 1); */
471  newFileWidget = XmCreateFileSelectionDialog(mainw, "select", args, 1);
472 
473  XtAddCallback(newFileWidget, XmNokCallback, (XtCallbackProc)fv_fileSelectPressed, NULL);
474  XtAddCallback(newFileWidget, XmNcancelCallback, (XtCallbackProc)fv_unManageMe, NULL);
475  /* delete buttons not wanted */
476  fv_removeWidgetFromSelect(newFileWidget,XmDIALOG_HELP_BUTTON);
477  XtUnmanageChild(newFileWidget);
478 
479 
480  menupane = XmCreatePulldownMenu (menubar, "menupane", NULL, 0);
481  btn = XmCreatePushButton (menupane, "Reload", NULL, 0);
482  XtAddCallback (btn, XmNactivateCallback, (XtCallbackProc)fv_reloadFile, NULL);
483  myXtManageChild (5,btn);
484  btn = XmCreatePushButton (menupane, "New...", NULL, 0);
485  XtAddCallback (btn, XmNactivateCallback, (XtCallbackProc)fv_newFilePopup, NULL);
486  myXtManageChild (6,btn);
487 
488  btn = XmCreatePushButton (menupane, "Quit", NULL, 0);
489  XtAddCallback (btn, XmNactivateCallback, (XtCallbackProc)fv_quitMenuBar, NULL);
490  myXtManageChild (7,btn);
491  XtSetArg (args[0], XmNsubMenuId, menupane);
492  cascade = XmCreateCascadeButton (menubar, "File", args, 1);
493  myXtManageChild (8,cascade);
494 }
495 
496 static void fv_createHelpPulldown()
497 {
498  Widget btn, menupane, cascade;
499  int ac;
500  Arg args[10];
501 
502 
503  menupane = XmCreatePulldownMenu (menubar, "menupane", NULL, 0);
504 
505  /* Helpity stuff */
506  ac = 0;
507  /*
508  sprintf (ns,ABOUT_FREEWRL,getLibVersion(),"","");
509  diastring = xec_NewString(ns);
510 
511  XtSetArg(args[ac], XmNmessageString, diastring); ac++;
512  */
513  XtSetArg(args[ac], XmNmessageAlignment,XmALIGNMENT_CENTER); ac++;
514  about_widget = XmCreateInformationDialog(menubar, "about", args, ac);
515  XtAddCallback(about_widget, XmNokCallback, (XtCallbackProc)fv_unManageMe, NULL);
516  fv_removeWidgetFromSelect (about_widget, XmDIALOG_CANCEL_BUTTON);
517  /*
518  causes segfault on Core3 fv_removeWidgetFromSelect (about_widget, XmDIALOG_HELP_BUTTON);
519  */
520 
521 
522  btn = XmCreatePushButton (menupane, "About FreeWRL...", NULL, 0);
523  XtAddCallback (btn, XmNactivateCallback, (XtCallbackProc)fv_aboutFreeWRLpopUp, NULL);
524  myXtManageChild (23,btn);
525  btn = XmCreatePushButton (menupane, "FreeWRL Homepage...", NULL, 0);
526  XtAddCallback (btn, XmNactivateCallback, (XtCallbackProc)fv_freewrlHomePopup, NULL);
527  myXtManageChild (24,btn);
528 
529  XtSetArg (args[0], XmNsubMenuId, menupane);
530  cascade = XmCreateCascadeButton (menubar, "Help", args, 1);
531  myXtManageChild (25,cascade);
532 }
533 
534 /**********************************/
535 static void fv_createMenuBar(void)
536 {
537  Arg menuArgs[10]; int menuArgc = 0;
538 
539  /* create the menu bar */
540  memset(menuArgs, 0, sizeof(menuArgs));
541  menuArgc = 0;
542 
543  /* the following XtSetArg is not required; it only "pretties" up the display
544  in some circumstances. It came out in Motif 2.0, and is not always found */
545 #ifdef XmNscrolledWindowChildType
546  XtSetArg(menuArgs[menuArgc], XmNscrolledWindowChildType, XmMENU_BAR); menuArgc++;
547 #endif
548 
549  menubar = XmCreateMenuBar (mainw, "menubar", menuArgs, menuArgc);
550  myXtManageChild (26,menubar);
551 
552  /* generic toggle button resources */
553  XtSetArg(buttonArgs[buttonArgc], XmCVisibleWhenOff, TRUE); buttonArgc++;
554  XtSetArg(buttonArgs[buttonArgc],XmNindicatorType,XmN_OF_MANY); buttonArgc++;
555 
556  if (!RUNNINGASPLUGIN) fv_createFilePulldown();
557  fv_createHelpPulldown();
558 
559 }
560 
561 /**********************************************************************************/
562 /*
563  create a frame for FreeWRL, and for messages
564 */
565 static void fv_createDrawingFrame(void)
566 {
567  /* frame holds everything here */
568  frame = XtVaCreateManagedWidget("form", xmPanedWindowWidgetClass, mainw, NULL);
569 
570  /* create the FreeWRL OpenGL drawing area, and map it. */
571 
572 #if 0 /* MB: do not create a glwDrawingArea but a simple widget
573  we have our own initialization of OpenGL ...
574  in the near future we could remove completely the GLwDrawA files...
575  */
576  freewrlDrawArea = XtVaCreateManagedWidget ("freewrlDrawArea", glwDrawingAreaWidgetClass,
577  frame, "visualInfo", Xvi,
578  XmNtopAttachment, XmATTACH_WIDGET,
579  XmNbottomAttachment, XmATTACH_FORM,
580  XmNleftAttachment, XmATTACH_FORM,
581  XmNrightAttachment, XmATTACH_FORM,
582  NULL);
583 #endif
584 
585  freewrlDrawArea = XmCreateDrawingArea (frame, "drawing_a", NULL, 0);
586 
587 #ifdef DOESNOTGETICONICSTATE
588  XtAddCallback (freewrlDrawArea, XmNexposeCallback, fv_GLAreaexpose, NULL);
589 #endif
590 
591  XtAddCallback (freewrlDrawArea, XmNresizeCallback, fv_GLArearesize, NULL);
592 
593  myXtManageChild(27,freewrlDrawArea);
594 }
595 
596 void setConsoleMessage (char *str)
597 {
598 // we do not do this anymore, Doug Sanden's HUD code does lots now
599 }
600 
601 
602 
603 // this does nothing anymore, Doug Sanden's HUD code replaces this.
604 void frontendUpdateButtons()
605 {
606 }
607 
608 #endif /* IPHONE */
609 #endif /* KEEP_FV_INLIB */
Initialization.
Definition: libFreeWRL.h:71