2003/02/22 03:55:06
[org.ibex.core.git] / src / org / xwt / Main.java
1 // Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL]
2 package org.xwt;
3
4 import org.xwt.util.*;
5 import java.lang.reflect.*;
6 import java.applet.*;
7 import java.net.*;
8 import java.util.*;
9 import java.io.*;
10 import java.awt.*;
11 import org.mozilla.javascript.*;
12 import org.bouncycastle.util.encoders.Base64;
13
14 /** Entry point for the XWT Engine; handles splash screen, initial xwar loading, and argument processing */
15 public class Main extends Applet {
16
17     /**
18      *  Used for security checks. If this is null, it means that only
19      *  scripts originating from the local filesystem are loaded in
20      *  the engine (maximum permissions). If scripts have been loaded
21      *  from multiple locations, this will be 0.0.0.0 (the invalid
22      *  IP).
23      */
24     public static java.net.InetAddress originAddr = null;
25
26     /** the URL where the initial xwar came from. */
27     public static String origin = null;
28
29     /** true iff the user asked for rendered regions to be shown with a red rectangle */
30     public static boolean showRenders = false;
31
32     public Main() { }
33     public void paint(Graphics g) { }    // do-nothing method to avoid repaints
34     public void update(Graphics g) { }   // do-nothing method, to avoid repaints
35
36     public static Applet applet = null;
37
38     /** don't check if all surfaces are gone (and quit) until this is true */
39     public static boolean doneInitializing = false;
40
41     /** applet entry point */
42     public void init() {
43         if ("true".equals(getParameter("showRenders"))) showRenders = true;
44         if ("true".equals(getParameter("verbose"))) Log.verbose = true;
45         applet = this;
46         main(new String[] { getParameter("initial-xwar-url"), "main" });
47     }
48
49     /** common entry point */
50     public static void main(String[] args) {
51         try {
52             int startargs = 0;
53             while (true) {
54                 if (startargs > args.length - 1) {
55                     System.err.println("Usage: xwt [-s] [-v] [-l <port>/<url>] source-location [initial-template]");
56                     System.err.println("");
57                     System.err.println("Options:");
58                     System.err.println("    -s show rendering activity with red rectangles");
59                     System.err.println("    -v verbose logging");
60                     System.err.println("    -l serve logs via HTTP on 127.0.0.1:<port>/<url>");
61                     System.err.println("");
62                     System.err.println("Source-location is one of the following:");
63                     System.err.println("    - the path to an xwar file");
64                     System.err.println("    - the path to a directory to be used as an xwar");
65                     System.err.println("    - the http url of an xwar");
66                     System.err.println("");
67                     System.err.println("Initial-template is the resource name of the template to load; defaults to 'main'");
68                     Runtime.getRuntime().exit(-1);
69                 }
70                 else if (args[startargs].equals("-s")) showRenders = true;
71                 else if (args[startargs].equals("-v")) Log.verbose = true;
72                 else if (args[startargs].equals("-l")) Log.enableHTTP(args[++startargs]);
73                 else break;
74                 startargs++;
75             }
76             final String instancename = args.length > startargs + 1 ? args[startargs + 1] : "main";
77
78             Platform.forceLoad();
79             if (Log.on) for(int i=0; i<args.length; i++) Log.log(Main.class, "argument " + i + ": " + args[i]);
80
81             // we do this here instead of in a static initializer to avoid threading hazards
82             if (Log.on) Log.log(Main.class, "loading scar image");
83             PNG png = PNG.decode(new ByteArrayInputStream(Base64.decode(scarPicture_png_base64)), "bundled scar image");
84             Surface.scarPicture = Platform.createPicture(png.getData(), png.getWidth(), png.getHeight());
85
86             InputStream is = Main.class.getClassLoader().getResourceAsStream("org/xwt/builtin.xwar");
87             if (is == null) Platform.criticalAbort("unable to load builtin.xwar");
88             Resources.loadArchive(is);
89            
90             String initialTemplate = "main";
91
92             if (args.length > startargs) {
93                 if (args[startargs].startsWith("http://")) {
94                     if (Log.on) Log.log(Main.class, "downloading xwar");
95                     origin = args[startargs];
96                     initialTemplate = "org.xwt.builtin.splash";
97
98                 } else {
99                     if (Log.on) Log.log(Main.class, "loading xwar from local filesystem");
100
101                     // HACK because MSIE turns \'s into /'s in URLs... argh!!
102                     if (Platform.platform.getClass().getName().endsWith("Win32"))
103                         args[startargs] = args[startargs].replace('/', '\\');
104
105                     File f = new File(args[startargs]);
106                     origin = "file:" + f.getAbsolutePath();
107                     if (f.isDirectory()) {
108                         Resources.loadDirectory(f);
109                         Surface.scarAllSurfacesFromNowOn = true;
110                     } else {
111                         initialTemplate = "org.xwt.builtin.splash";
112                     }
113
114                     if (args.length > startargs + 1) initialTemplate = args[startargs + 1];
115                 }
116             }
117             
118             if (Log.on) Log.log(Main.class, "instantiating " + initialTemplate);
119             final String initialTemplate_f = initialTemplate;
120             ThreadMessage.newthread(new JSObject.JSFunction() {
121                     public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] arg) throws JavaScriptException {
122                         new Box(initialTemplate_f, null);
123             doneInitializing = true;
124             if (Surface.allSurfaces.size() == 0) {
125                 Log.log(this, "exiting because all surfaces are gone");
126                 Platform.exit();
127             }
128                         return null;
129                     }
130                 });
131            
132             // gcj-win32 exit()'s when the original thread dies, so we have to deadlock ourselves
133             if (Log.on) Log.log(Main.class, "main thread blocking on new semaphore");
134             new org.xwt.util.Semaphore().block();
135
136         } catch (Throwable e) {
137             e.printStackTrace();
138             Platform.criticalAbort("exception in Main.main(): " + e);
139         }
140     }
141
142     /** a base64-encoded png image of the scar */
143     public static final String scarPicture_png_base64 = 
144         "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAA" +
145         "CXBIWXMAAAsRAAALEQF/ZF+RAAAAB3RJTUUH0gIYAgsIkuS+AwAAA7lJREFUeJzF1l9MW1Uc" +
146         "wPHvvb3lz/oHOssd0hXo+NNONow102xDSXzoJGiyGBIyDNMlJvjn0USNL74ZY3wnxOgeWIxo" +
147         "9uAmZBrMiNkYYw5xRGBFQdiuzgtl/Gmht7S9PsBM162lGwN+yU3uPTf3nM895/c7OXwOfSKI" +
148         "23Z1yDJt0Ms2hQhwARa3CyHeudkuhJj4sB0IMblhqxH3ALYacV/AViJSArYKkRawFYh1AZuN" +
149         "yAiwmQgpzTsBMMzVv14V00PWQGDhJpd/UNugdwBebIOFRwFINwOGwJHXPH/d9BdYrbXZpaV1" +
150         "ZUPeZ8RuiHnhXAvYNxMghEEMaXO79rjqyLeV6c5iD01Nrz4bevnYwYFVxJkWsG4WQM+B+I6e" +
151         "7/q0SH98srXuYufpk2NGo8Tx5jcF6/unDwyA5oVzmwUAiBlhReg622eG6L7xDuWbjp+iJSVO" +
152         "Kisfl2Z8p8QLENxoYqatgjzQAeFy4QvOs0ZX5bGmeunvWxK//jaNQQpLsPHqSJkDgKT6GrxD" +
153         "xZ6DkimrzFffUFS020dX50B8efaPyeyuN5ZZBW4IkQogqb6Gp0b9IxZJcmKzubCYvfT0KAjx" +
154         "ES3r1LtTQDzxg4dFiA5V/UCRZUtio+p7xTtyfdgqiEXIBW5cew6xv/p5ap8zBVbi8ez5hg9d" +
155         "O8DA6kxtCCG2w8/JiPngrMUgObE/VoHDeYAn9taytBxDRw+/VH9YlHJFR7Dxo4o1xF3xoAiD" +
156         "AMI1mKwJhcYUWa63hkKRyXx7saZliU9WH8XjqSUciWHLs3HrX6x2e9a0212yqEXthWGPNzdy" +
157         "9cdZkpZjCiLvwNvfwxcZAQASEe6JMWXGUeCM6TaKiqoxm8xMB26zM9+OOq2b9lYVWsrLyoWJ" +
158         "G1FzvKo8L3r1/D/JHWeKuCsJE5ZDfPr3/l6BYX14tJvgUhBbfh7TgQDuCkvYarKg3BCIRu1E" +
159         "V3bFUnWeyXLcUwVriE8UWTYUn//2UjTi1/3+iwSDi+zft5NSV27O6EiUwaE/CS8NaMaTLaPp" +
160         "BlgPcd8ybIczDlX9VJFlg73zs0va8qA+PtGHxWTGfz3O4NA483O/aHrriStLEEkHWA/xfw4k" +
161         "xzUYrQmF5hVZPlw42D216CrdPXfbKMzMRliYv6LReqJ/CVZISsBUkSonBHGd7bgZjiqy/F6F" +
162         "qsZCjR87c0w2DF++Nbn25xkNnhg1YGmBQxkD1hDFiix/7VDVxQcdcD1ERkeydphyqOrx5B3z" +
163         "YSMxJzKagTvRDKWKLH/VqKqPwgHAf3HDlnr6flmoAAAAAElFTkSuQmCC";
164 }