Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/vrspace/vrmlclient/VRSpace.java


1   package org.vrspace.vrmlclient;
2   
3   import java.applet.Applet;
4   import java.awt.*;
5   import java.awt.event.*;
6   import java.util.*;
7   import java.net.*;
8   
9   import vrml.external.*;
10  import vrml.external.field.*;
11  import vrml.external.exception.*;
12  
13  import org.vrspace.util.*;
14  
15  /**
16  VRSpace applet<br>
17  Parameters:<br>
18  host - hostname, default origin host<br>
19  port - port to connect to<br>
20  username - username to login with<br>
21  password - password to login with<br>
22  logInfo - true/false<br>
23  logDebug - true/false<br>
24  logError - true/false<br>
25  logWarning - true/false<br>
26  intro - class imlementing Intro intefrace, started after init. Default: org.vrspace.vrmlclient.VRSpaceIntro<br>
27  @see Intro
28  */
29  public class VRSpace
30               extends Applet
31               implements Observer, EventOutObserver, ActionListener, WindowListener
32  {
33    public Browser browser;
34  
35    private String host;
36    private int port = 8500;
37    public String login = null;
38    public String password = null;
39    //public String proxyURL = null;
40  
41    String myClass;
42    long myId;
43  
44    private boolean locked = false;
45    private boolean loginDisplayed = false;
46    private boolean readlogin = true;
47    private boolean nothingTyped = true;
48    
49    public Node console;
50    EventInMFString conText;
51    EventInSFVec2f conPos;
52    EventInSFBool conHide;
53    
54    public Node HUD;
55    public Node HUDLoader;
56    public EventInMFNode HUDLoad;
57    
58    private long lastWrite;
59    public Node busy;
60    
61    public EventInSFString serverMsg;
62    private EventOutSFString clientMsg;
63    private EventOutSFString userMsg;
64  
65    public Node scene;
66    public Node bg; // background
67    public EventOutMFNode sceneChildren;
68    public EventOutMFNode hudChildren;
69    public Node dispatcherScript;
70    public Node loadTarget;
71    public EventInMFNode loadChildren;
72    public EventInMFNode unloadChildren;
73    public Node unloadTarget;
74    public Node movement;
75    EventOutSFVec3f translation_changed;
76    EventOutSFRotation rotation_changed;
77    EventInSFBool movementEnabled;
78    public Node fog;
79    EventInSFFloat visibility;
80    public Node navigationInfo;
81    EventOutSFBool navigationBound;
82    boolean navigationOn = true;
83    EventInMFString navigation;
84    public Node viewpoint;
85    public EventInSFVec3f translation;
86    public EventInSFRotation rotation;
87    //public Node chat;
88    //public EventOutSFBool chatActive;
89    //public boolean chatEnabled=false;
90  
91    public Connection connection;
92    public ConnectionManager connMgr;
93    public URLLoader loader;
94    public Dispatcher dispatcher;
95    public SceneManager sceneMgr;
96    public MovementManager movementMgr;
97  
98    String errorMsg = "";
99    Logger logger;
100   boolean useJava = true;
101   String introClass = "org.vrspace.vrmlclient.VRSpaceIntro";
102   Intro intro;
103   
104   // UI stuff
105   private Keyboard keyboard;
106   private TextArea textArea;
107   private TextField textField;
108   private Frame logFrame;
109   private Button logButton;
110   
111   // Applet init
112   public void init() {
113 
114     logger = new Logger();
115 
116     setBackground( Color.black );
117     setForeground( Color.green );
118     textArea = new TextArea( "", 25, 132, TextArea.SCROLLBARS_BOTH );
119     textField = new TextField( 80 );
120 //    add( textArea );
121     logFrame = new Frame( "Session Log" );
122     logFrame.add( textArea );
123     logFrame.addWindowListener( this );
124     
125     add( textField );
126     
127     logButton = new Button( "?" );
128     logButton.setActionCommand( "logFrame" );
129     logButton.addActionListener(this);
130     add( logButton );
131     
132     keyboard = new Keyboard();
133     // Setup key/text listeners
134     //textArea.addKeyListener( keyboard );
135     textField.addKeyListener( keyboard );
136     textField.addTextListener( keyboard );
137     keyboard.addObserver( this );
138 
139     // get client parameters
140     host = getParameter( "host" );
141     if ( host == null ) {
142       host = getCodeBase().getHost();
143     }
144     String port = getParameter( "port" );
145     if ( port != null ) {
146       this.port = new Integer(port).intValue();
147     }
148     String login = getParameter( "username" );
149     if ( login != null ) {
150       this.login = login;
151     }
152     String password = getParameter( "password" );
153     if ( password != null ) {
154       this.password = password;
155     }
156 
157     // not used:
158     //proxyURL = getParameter( "proxyURL" );
159     String tmp = getParameter( "logDebug" );
160     if ( tmp != null && "true".equals(tmp) ) {
161       Logger.logDebug( true );
162     } else {
163       Logger.logDebug( false );
164     }
165     tmp = getParameter( "logInfo" );
166     if ( tmp != null && "true".equals(tmp) ) {
167       Logger.logInfo( true );
168     } else {
169       Logger.logInfo( false );
170     }
171     tmp = getParameter( "logWarning" );
172     if ( tmp != null && "false".equals(tmp) ) {
173       Logger.logWarning( false );
174     } else {
175       Logger.logWarning( true );
176     }
177     tmp = getParameter( "logError" );
178     if ( tmp != null && "false".equals(tmp) ) {
179       Logger.logWarning( false );
180     } else {
181       Logger.logWarning( true );
182     }
183     
184     // MS JVM Workaround: There is a race condition that can cause
185     // an applet to not appear (gray box).  The issue is that the size of 
186     // of the applet is never set.  This workaround ensures it is set directly
187     // after the size of its parent it set.  A manual workaround is to have 
188     // the user resize the screen.
189     final Component componentToResize = this;
190     getParent().addComponentListener(
191       new ComponentListener() {
192         private boolean _beenResized = false;
193 
194         public void componentResized( ComponentEvent e ) {
195           if (!_beenResized) {
196             componentToResize.setSize( e.getComponent().getSize() );
197             _beenResized = true;
198           }
199         }
200 
201         public void componentMoved ( ComponentEvent e )  {}
202         public void componentShown ( ComponentEvent e )  {}
203         public void componentHidden( ComponentEvent e ) {}
204       }
205     );
206     
207   }
208 
209   // Look for VRML browser
210   synchronized boolean findBrowser() {
211     browser = null;
212     for ( int i = 0; i < 20 && browser == null; i++ ) {
213       try {
214         browser = Browser.getBrowser( this );
215       } catch ( Throwable e ) {
216         Logger.logError(e);
217       }
218       try {
219         Thread.sleep( 1000 );
220       } catch ( Exception e ) {
221       }
222     }
223     return (browser != null );
224   }
225   
226   /**
227   Calls Browser.getNode(), but sets errormsg to node name
228   */
229   Node getNode( String name ) {
230     try {
231       return browser.getNode( name );
232     } catch ( Throwable t ) {
233       Logger.logError( "Couldn't find node "+name );
234       Logger.logError(t);
235       setForeground( Color.red );
236       textField.setText(t.toString()+" "+errorMsg);
237       return null;
238     }
239   }
240 
241   // Applet start
242   public void start() {
243     try {
244       if ( findBrowser() ) {
245         try {
246           busy = browser.getNode( "VRSpace_Busy" );
247         } catch ( Throwable t ) {
248           Logger.logDebug( "No busy indicator: "+t );
249         }
250 
251         // get nodes
252         dispatcherScript = getNode( "VRSpace_Dispatcher" );
253         scene = getNode("VRSpace_Scene");
254         //if ( browser.getName().indexOf( "Cortona" ) >= 0 ) {
255           loadTarget = getNode("VRSpace_Loader");
256           unloadTarget = getNode("VRSpace_Unloader");
257         //} else {
258         //  loadTarget = getNode("VRSpace_Scene");
259         //  unloadTarget = getNode("VRSpace_Scene");
260         //}
261         fog = getNode("VRSpace_Fog");
262         navigationInfo = getNode("VRSpace_NavigationInfo");
263         viewpoint = getNode("VRSpace_Viewpoint");
264         //chat = getNode("VRSpace_Chat");
265 
266         // create EventOutObservers
267         connMgr = new ConnectionManager( this );
268         if ( browser.getName().indexOf( "Cortona" ) >= 0 ) {
269           loader = new CortonaLoader(this);
270         } else {
271           loader = new URLLoader(this);
272         }
273         sceneMgr = new SceneManager( this, 1000 );
274         movementMgr = new MovementManager(this);
275         dispatcher = new Dispatcher( this, sceneMgr );
276 
277         // setup EventOutObservers
278         // network first
279         clientMsg = (EventOutSFString) dispatcherScript.getEventOut( "clientMsg" );
280         //clientMsg.advise( connMgr, "clientMsg" );
281         clientMsg.advise( this, "clientMsg" );
282         userMsg = (EventOutSFString) dispatcherScript.getEventOut( "userMsg" );
283         userMsg.advise( this, "userMsg" );
284 
285         // user movement
286         try {
287           movement = getNode("VRSpace_Movement");
288           translation_changed = (EventOutSFVec3f) movement.getEventOut("position_changed");
289           rotation_changed = (EventOutSFRotation) movement.getEventOut("orientation_changed");
290           translation_changed.advise( this, "translation" );
291           rotation_changed.advise( this, "rotation" );
292           // we track movement only if VRSpace_NavigationInfo is bound
293           navigationBound = (EventOutSFBool) navigationInfo.getEventOut( "isBound" );
294           navigationBound.advise( this, "NavigationBound" );
295           // movement measurment on/off (proximity sensor on/off)
296           movementEnabled = (EventInSFBool) movement.getEventIn("enabled");
297         } catch ( Throwable t ) {
298           Logger.logInfo( "Movement tracking disabled: "+t.toString() );
299         }
300         
301         // add the console
302         console = browser.getNode("VRSpace_Console");
303         conText = (EventInMFString) console.getEventIn( "set_string" );
304         conPos = (EventInSFVec2f) console.getEventIn( "set_cursor" );
305         try {
306           conHide = (EventInSFBool) console.getEventIn( "set_hide" );
307         } catch ( Throwable t ) {
308           Logger.logInfo( "Console cannot be hidden" );
309         }
310         // movement tracking should be checked before
311         if ( browser.getName().indexOf( "blaxxun" ) >= 0 || browser.getName().indexOf( "Contact" ) >= 0 ) {
312           useJava = false;
313         }
314         HUD = getNode("VRSpace_HUD");
315         HUDLoader = getNode("VRSpace_HUDLoader");
316         hudChildren = (EventOutMFNode) HUD.getEventOut("children_changed");
317         hudChildren.advise( this, "HUD" );
318         /*
319         if ( useJava ) {
320           // add console
321           String[] tmp = {"console.wrl"};
322           browser.createVrmlFromURL( tmp, HUDLoader, "children" );
323         } else {
324           // add javascript console
325           String[] tmp = {"console-js.wrl"};
326           browser.createVrmlFromURL( tmp, HUDLoader, "children" );
327         }
328         */
329 
330         // look for nodes
331         try {
332           bg = getNode( "VRSpace_Background" );
333         } catch ( Throwable t ) {
334           Logger.logDebug( "No VRSpace_Background node: "+t );
335         }
336         
337         // changes to the scene
338         sceneChildren = (EventOutMFNode) scene.getEventOut( "children_changed" );
339         //sceneChildren.advise( loader, "loadedTransform" );
340         sceneChildren.advise( this, "loadedTransform" );
341         
342         // chat on/off
343         //chatActive = (EventOutSFBool) chat.getEventOut("active");
344         //chatActive.advise( this, "chatActive" );
345         
346         // movement synchronization time (seconds)
347         movementMgr.setSync((long) (((EventOutSFFloat) dispatcherScript.getEventOut( "movement_sync" )).getValue() * 1000));
348         // EventIn to receive network events
349         serverMsg = (EventInSFString) dispatcherScript.getEventIn( "serverMsg" );
350         // EventIn for visibility range control
351         visibility = (EventInSFFloat) fog.getEventIn( "set_visibilityRange" );
352         // Navigation type control
353         navigation = (EventInMFString) navigationInfo.getEventIn( "set_type" );
354         // Viewpoint coordinates
355         translation = (EventInSFVec3f) viewpoint.getEventIn( "set_position" );
356         rotation = (EventInSFRotation) viewpoint.getEventIn( "set_orientation" );
357         // changes to the scene
358         //if ( browser.getName().indexOf("Cortona") > 0 ) {
359           loadChildren=(EventInMFNode) loadTarget.getEventIn( "children" );
360           unloadChildren=(EventInMFNode) unloadTarget.getEventIn( "children" );
361         //} else {
362         //  loadChildren=(EventInMFNode) loadTarget.getEventIn( "addChildren" );
363         //  unloadChildren=(EventInMFNode) loadTarget.getEventIn( "removeChildren" );
364         //}
365 
366         if ( HUDLoader != null ) {
367           HUDLoad = (EventInMFNode) loadTarget.getEventIn( "children" );
368         }
369         // Login...
370         // Other threads are closed before, and started after login
371         initiateLogin();
372         Logger.logDebug( "VRSpace started" );
373         /**
374         try {
375           Class c = Class.forName( "com.trapezium.chisel.Chisel" );
376           Class[] args = new Class[]{ (new String[]{}).getClass() };
377           Object[] arg = { new String[]{"-loadfromjar","-forcejfc","+http://localhost/portal/" }};
378           c.getMethod( "main", args ).invoke( null, arg );
379           Logger.logDebug( "Chisel started" );
380         } catch ( Throwable t ) {
381           Logger.logError(t);
382         }
383         */
384       } else {
385         Logger.logError("No VRML browser!");
386       }
387     } catch ( Throwable e ) {
388       setForeground( Color.red );
389       textField.setText(e.toString()+" "+errorMsg);
390       Logger.logError(e);
391       Logger.logError("Unable to start VRSpace client!");
392     }
393   }
394 
395   public void stop() {
396     try {
397       movementMgr.active=false;
398       loader.active=false;
399       if ( connection != null && connection.isActive() ) {
400         connection.close();
401       }
402     } catch (Throwable e) {
403       Logger.logError(e);
404     }
405     Logger.logDebug( "VRSpace stopped" );
406   }
407 
408   public void destroy() {
409     // logout? seems it crashes netscape
410     // connection.send( "quit" );
411     movementMgr.active=false;
412     logFrame.hide();
413     Logger.logDebug( "VRSpace unloaded" );
414   }
415 
416   // Login start
417   public void initiateLogin() {
418     try {
419       // this stops movementMgr Thread:
420       movementMgr.active=false;
421 
422       Logger.logDebug( "login" );
423       //((EventInSFBool) console.getEventIn("autoHide")).setValue(false);
424       clear();
425       //      writeat(0,0, "VRSpace");
426       if ( ( login == null ) || ( password == null ) ) {
427         displayLogin();
428       }
429       textField.setText("");
430       textField.requestFocus();
431       //((EventInSFString) console.getEventIn("set_xyzgo")).setValue("-.05 .03 -.20 1");
432       //(new Thread(new ConsoleThread())).start();
433       
434       // Intro frozen for release.
435       /*try {
436         Class intro = Class.forName(introClass);
437         this.intro = (Intro)intro.newInstance();
438         this.intro.start( this );
439       } catch (Throwable thr) {
440         Logger.logError(thr);
441       }
442       */
443       
444       textArea.setText("");
445   //    textArea.requestFocus();
446     } catch (Throwable t) {
447       t.printStackTrace();
448     }
449   }
450   public class ConsoleThread implements Runnable {
451     public void run() {
452       /*
453       while (!useJava && nothingTyped) {
454         displayLogin();
455         ((EventInSFString) console.getEventIn("set_xyzgo")).setValue("-.05 .03 -.20 1");
456         try {
457           Thread.sleep(1000);
458         } catch (InterruptedException e) {
459         }
460       }
461       */
462       while (true) {
463         try {
464           if ( connection != null && connection.isActive() && !movementMgr.moving && (lastWrite + 60000 > System.currentTimeMillis()) ) {
465             ((EventInSFString) console.getEventIn("set_xyzgo")).setValue("-.15 .03 -.20 1");
466           }
467           Thread.sleep(5000);
468         } catch (InterruptedException e) {
469         }
470       }
471     }
472   }
473   private void displayLogin() {
474     writeat(0,0, "VRSpace server "+host+":"+port);
475     writeat(2,0, "login   :");
476     writeat(3,0, "password:");
477     pos( 2, 10 );
478     
479     loginDisplayed = true;
480   }
481 
482   /**
483   Login & password input, connect to server,
484   start Connection and MovmementManager
485   */
486   private void readLogin( String arg ) {
487     if (login == null || password == null) {
488       if ( ! loginDisplayed ) {
489         displayLogin();
490       }
491       if ( arg == null ) {
492         // TextEvent
493         //write( textArea.getText().trim() );
494         String text = textField.getText().trim();
495         if ( readlogin ) {
496           //write( text );
497           writeat( 2, 10, text );
498         } else if (text.length() > 0 ){
499           StringBuffer s = new StringBuffer( text.length() );
500           for ( int i = 0; i<text.length(); i++) {
501             s.append('*');
502           }
503           //write( s.toString() );
504           writeat( 3, 10, s.toString() );
505         }
506         if ( text.length() > 0 ) {
507           nothingTyped = false;
508         }
509       } else if ( arg.equals( "Enter" ) ) {
510         // string typed
511         if ( readlogin ) {
512   //        login = textArea.getText().trim();
513           login = textField.getText().trim();
514           pos( 3, 10 );
515           readlogin = false;
516         } else {
517   //        password = textArea.getText().trim();
518           password = textField.getText().trim();
519           readlogin = true;
520           login();
521         }
522         //textArea.setText("");
523         textField.setText("");
524       }
525     } else {
526       login();
527     }
528   }
529 
530   private void login() {
531     try {
532       // connect
533       connection = new Connection( host, port, login, password );
534       // connected
535       connection.addObserver( connMgr );
536       if ( intro != null ) {
537         try {
538           intro.stop();
539         } catch ( Throwable t ) {
540           //who cares
541           //Logger.logDebug( t.toString() );
542           Logger.logError( t );
543         }
544       }
545       // start movement manager
546       movementMgr.active=true;
547       movementMgr.setMovement(false);
548       (new Thread(movementMgr)).start();
549       // start loader
550       loader.active = true;
551       loader.start();
552       // move console around (hide)
553       //((EventInSFBool) console.getEventIn("autoHide")).setValue(true);
554       //((EventInSFString) console.getEventIn("set_xyzgo")).setValue("-.15 .03 -.20 1");
555       clear();
556       /*
557       try {
558         consoleOpen = (EventOutSFTime) console.getEventOut("open");
559         consoleOpen.advise( this, "consoleOpen" );
560       } catch ( Exception e ) {
561         Logger.logError( "Cannot listen console.open - "+e );
562       }
563       */
564     } catch (ConnectionException e) {
565       String msg = e.getMessage();
566       if ( msg == null ) {
567         msg = e.toString();
568       }
569       writeat( 1,0,msg );
570       //if ( msg.length()>5 && "-login".equals( msg.substring(0,6) ) ) {
571         login = null;
572         password = null;
573       //}
574       pos( 2, 10 );
575     }
576   }
577   // Keyboard input handling
578   public void update( Observable o, Object argument ) {
579     String arg = (String) argument;
580     if ( o instanceof Keyboard ) {
581       if ( connection == null || !connection.isActive()) {
582         readLogin( arg );
583       } else {
584         //if ( arg == null && textField.getText().trim().length() > 0 ) {
585         if ( "Enter".equals(arg) ) {
586           // TextEvent
587           /*
588           if ( chatEnabled ) {
589             connection.send( myClass+" "+myId+" say "+textField.getText().trim() );
590           } else {
591             connection.send( textField.getText().trim() );
592           }
593           */
594           try {
595             if ( textField.getText().charAt(0) == '/' ) {
596               // commands begin with /
597               connection.send( textField.getText().substring(1).trim() );
598             } else {
599               // default command is say
600               connection.send( myClass+" "+myId+" say "+textField.getText().trim() );
601             }
602             writeln( "> "+textField.getText().trim() );
603           } catch (Throwable t) {
604             Logger.logError(t);
605           }
606           textField.setText("");
607         }
608       }
609     } else if ( o instanceof Connection ) {
610       // moved to new Observer - ConnectionManager
611       Logger.logError( "BEEP!" );
612     }
613   }
614 
615   int curRow = 9;
616   int curCol = 0;
617   String[] text = new String[10];
618   int maxLength = 60;
619   // Misc text output functions
620   public void clear() {
621     for (int i = 0; i < text.length; i++) {
622       text[i] = "";
623     }
624     pos( 0, 0 );
625     conText.setValue( text );
626     if ( conHide != null ) {
627       conHide.setValue( true );
628     }
629   }
630   public void writeat( int row, int col, String s ) {
631     //System.out.println( "writeat "+row+" "+col+" "+s );
632     try {
633       if ( col >= text[row].length() ) {
634         StringBuffer tmp = new StringBuffer( text[row] );
635         for ( int i = text[row].length(); i < col; i++ ) {
636           tmp.append(' ');
637         }
638         tmp.append( s );
639         text[row] = tmp.toString();
640       } else {
641         text[row] = text[row].substring( 0, col ) + s;
642       }
643       conText.setValue( text );
644       pos( row, text[row].length() );
645     } catch ( Exception e ) {
646       e.printStackTrace();
647       //System.out.println( row );
648       //System.out.println( col );
649       //System.out.println( conText );
650     }
651   }
652 
653   public void write( String s ) {
654     writeat( curRow, curCol, s );
655     //cursor( curRow, text[curRow].length()+1 );
656   }
657 
658   public void pos( int row, int col ) {
659     //System.out.println( "pos "+row+" "+col );
660     cursor( row, col+1 );
661     curCol = col;
662     curRow = row;
663   }
664   public void writeln( String s ) {
665     //System.out.println( "writeln "+s );
666     try {
667       addLine(s);
668       conText.setValue(text);
669       pos( curRow, 0 );
670       //curCol=0;
671       cursor(curRow,-2);
672 
673       textArea.append( s );
674       textArea.append( "\n" );
675       
676     } catch ( Exception e ) {
677       e.printStackTrace();
678     }
679   }
680   void addLine( String s ) {
681     if ( curRow < text.length-1 ) {
682       text[++curRow] = s;
683     } else {
684       for ( int i = 0; i < text.length-1; i++ ) {
685         text[i] = text[ i+1 ];
686       }
687       text[text.length-1]=s;
688     }
689   }
690   public void cursor(int row, int col) {
691     float[] tmp = { row, col };
692     conPos.setValue( tmp ); 
693   }
694 
695   public void say( NodeManager who, String what ) {
696     String name = who.getName();
697     if ( name == null ) {
698       name = who.className+' '+who.id;
699     }
700     textArea.append( name );
701     textArea.append( ": " );
702     textArea.append( what );
703     textArea.append( "\n" );
704     
705     StringTokenizer st = new StringTokenizer( what, " " );
706     StringBuffer output = new StringBuffer( name );
707     output.append(": ");
708     while (st.hasMoreTokens()) {
709       String token = st.nextToken();
710       if ( output.length() + token.length() > maxLength ) {
711         //writeln( output.toString() );
712         addLine( output.toString() );
713         output = new StringBuffer();
714         for ( int i = 0; i < name.length(); i++ ) {
715           output.append( ' ' );
716         }
717         output.append( ": " );
718       } 
719       output.append( token );
720       output.append( ' ' );
721     }
722     if ( output.length() > 0 ) {
723       addLine( output.toString() );
724       //writeln( output.toString() );
725     }
726     conText.setValue(text);
727     pos( curRow, 0 );
728     cursor(curRow,-2);
729   }
730 /*
731   public TextArea getOutput() {
732     return textArea;
733   }
734 */
735   public TextField getOutput() {
736     return textField;
737   }
738 
739   public Keyboard getInput() {
740     return keyboard;
741   }
742 
743   public void callback ( EventOut ev,
744                          double timestamp,
745                          Object userdata
746                        )
747   {
748     try {
749       if ( userdata.equals("translation")||userdata.equals("rotation") ) {
750         if (!locked && navigationOn) {
751           locked=true;
752           movementMgr.callback( ev, timestamp, userdata );
753           locked=false;
754         }
755       } else if ( userdata.equals("loadedTransform") ) {
756         loader.callback( ev, timestamp, userdata );
757         //unlock();
758       } else if ( userdata.equals("clientMsg") ) {
759         connMgr.callback( ev, timestamp, userdata );
760       } else if ( userdata.equals("userMsg") ) {
761         connMgr.callback( ev, timestamp, userdata );
762       } else if ( userdata instanceof Long ) {
763         Transform t=sceneMgr.getTransform( ((Long)userdata).longValue() );
764         if ( t != null ) {
765           t.callback( ev, timestamp, userdata );
766         }
767         //unlock();
768         /*
769       } else if ( userdata.equals("chatActive") ) {
770         chatEnabled = ((EventOutSFBool)ev).getValue();
771         if ( chatEnabled ) {
772           textField.requestFocus();
773         }
774         */
775       } else if ( userdata.equals("NavigationBound") ) {
776         navigationOn = ((EventOutSFBool)ev).getValue();
777         Logger.logDebug( "NavigationInfo bound: "+navigationOn);
778         /*
779       } else if ( userdata.equals( "HUD" ) ) {
780         // hud children changed - console added
781         Logger.logDebug( "Console added" );
782         Node[] hudChildren = ((EventOutMFNode)ev).getValue();
783         console = hudChildren[ hudChildren.length - 1 ];
784         if ( movement != null ) {
785           browser.addRoute( movement, "position_changed", console, "movement" );
786         }
787         ((EventInSFBool)console.getEventIn("VRObject_Online")).setValue(true);
788         */
789         /*
790       } else if ( userdata.equals("consoleOpen") ) {
791         String[] conText = ((EventOutMFString) console.getEventOut( "text_changed" )).getValue();
792         if ( consoleFrame == null ) {
793           consoleFrame = new Frame( "Console" );
794           consoleFrame.setLayout( new GridLayout( conText.length+1,1 ));
795           //consoleFrame.setSize( 300, 200 );
796           //consoleFrame.show();
797           consoleFrame.pack();
798         } else {
799           consoleFrame.removeAll();
800         }
801         for( int i = 0; i < conText.length; i++ ) {
802           consoleFrame.add( new Label( conText[i] ));
803         }
804         Button close = new Button( "Close" );
805         close.addActionListener( this );
806         consoleFrame.add( close );
807         //consoleFrame.validate();
808         consoleFrame.pack();
809         consoleFrame.show();
810         consoleFrame.requestFocus();
811         */
812       }
813     } catch (Throwable t) {
814       Logger.logError(t);
815     }
816   }
817   private synchronized void lock() {
818     locked=true;
819     movementEnabled.setValue(false);
820   }
821   public void unlock() {
822     if ( locked ) {
823       movementEnabled.setValue(true);
824       locked=false;
825     }
826   }
827   public synchronized boolean lock( long wait ) {
828     while (locked) {
829       try {
830         Thread.sleep( wait );
831       } catch ( InterruptedException e ) {
832       }
833     }
834     movementEnabled.setValue(false);
835     locked = true;
836     return locked;
837   }
838   public void actionPerformed( ActionEvent e ) {
839     if ( e.getActionCommand().equals("logFrame") ) {
840       // set focus to chat window
841       if ( ! logFrame.isVisible() ) {
842         logFrame.pack();
843       }
844       logFrame.show();
845       //logFrame.requestFocus();
846       textArea.requestFocus();
847     } else {
848       Logger.logError( "Invalid action event: "+e );
849     }
850       
851     //consoleFrame.hide();
852   }
853   public String getInfo() {
854     return browser.getName() + " V"+browser.getVersion() + " OS: " + 
855            System.getProperty("os.name") + " "+
856            System.getProperty("os.version") + " "+
857            System.getProperty("os.arch") ; //+" "+
858            //System.getProperty("user.name");
859   }
860   public void setBusy( boolean busy ) {
861     if ( this.busy != null ) {
862       if ( busy ) {
863         ((EventInSFTime)this.busy.getEventIn( "stop" )).setValue(System.currentTimeMillis()/1000);
864       } else {
865         ((EventInSFTime)this.busy.getEventIn( "start" )).setValue(System.currentTimeMillis()/1000);
866       }
867     }
868   }
869   public String rewriteURL( String url ) {
870     URL tmp = null;
871     String ret = url;
872     try {
873       tmp = new URL( ret );
874     } catch ( MalformedURLException e ) {
875       try {
876         if ( url.indexOf("/") == 0 ) {
877           //ret = getCodeBase().getProtocol()+"://"+getCodeBase().getHost()+url;
878           ret = getCodeBase().getProtocol()+"://"+getCodeBase().getHost()+":"+getCodeBase().getPort()+url;
879           tmp = new URL( ret );
880         } else {
881           String s = getDocumentBase().toString();
882           ret = s.substring( 0,s.lastIndexOf("/"))+"/"+url;
883           tmp = new URL( ret );
884         }
885       } catch ( MalformedURLException e1 ) {
886         Logger.logError(e1);
887       }
888     }
889     return ret;
890   }
891   
892   // WindowListener iface for chat window
893   public void windowActivated( WindowEvent e ) {
894   }
895   public void windowClosed( WindowEvent e ) {
896   }
897   public void windowClosing( WindowEvent e ) {
898     logFrame.hide();
899   }
900   public void windowDeactivated( WindowEvent e ) {
901   }
902   public void windowDeiconified( WindowEvent e ) {
903   }
904   public void windowIconified( WindowEvent e ) {
905   }
906   public void windowOpened( WindowEvent e ) {
907   }
908 }