2002/04/23 02:13:06
[org.ibex.core.git] / src / org / xwt / plat / Java2.java
1 // Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL]
2 package org.xwt.plat;
3
4 import java.awt.*;
5 import java.awt.event.*;
6 import java.awt.image.*;
7 import java.awt.datatransfer.*;
8 import java.net.*;
9 import java.io.*;
10 import java.util.*;
11 import org.xwt.util.*;
12 import org.xwt.*;
13
14 // FEATURE: Java 1.4 allows undecorated frames and can maximize windows
15
16 /** Platform class for most reasonable Java1.2+ JVMs */
17 public class Java2 extends AWT {
18
19     protected Socket __getSocket(String host, int port, boolean ssl) throws IOException { return super._getSocket(host, port, ssl); }
20     protected Socket _getSocket(final String host, final int port, final boolean ssl) throws IOException {
21         return (Socket)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {
22                 public Object run() {
23                     try {
24                         return __getSocket(host, port, ssl);
25                     } catch (Exception e) {
26                         if (Log.on) Log.log(Java2.class, "Error attempting to create socket");
27                         if (Log.on) Log.log(Java2.class, e);
28                         return null;
29                     }
30                 }
31             });
32     }
33     
34     protected DoubleBuffer _createDoubleBuffer(int w, int h, Surface owner) { return new Java2DoubleBuffer(w, h); }
35     protected Surface _createSurface(final Box root, final boolean framed) {
36         return (Surface)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {
37                 public Object run() { return new Java2Surface(root, framed); }
38             });
39     }
40
41     // Inner Classes //////////////////////////////////////////////////////////////////
42
43     protected static class Java2Surface extends AWTSurface {
44         
45         public Java2Surface(Box root, boolean framed) { super(root, framed); }
46         public void blit(DoubleBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2) {
47             if (ourGraphics == null) ourGraphics = window.getGraphics();
48             _doDrawImage(ourGraphics, ((AWTDoubleBuffer)s).i, dx + insets.left, dy + insets.top, dx2 + insets.left, dy2 + insets.top,
49                          sx, sy, sx + (dx2 - dx), sy + (dy2 - dy), null);
50         }
51
52         protected void _setMinimized(boolean b) {
53             if (frame == null) {
54                 if (Log.on) Log.log(this, "JDK 1.2 can only minimize frames, not windows");
55                 return;
56             }
57             if (b) frame.setState(java.awt.Frame.ICONIFIED);
58             else frame.setState(java.awt.Frame.NORMAL);
59         }
60     }
61
62     protected static class Java2DoubleBuffer extends AWTDoubleBuffer {
63         private static ColorModel cm = Toolkit.getDefaultToolkit().getColorModel();
64         private static Hashtable emptyHashtable = new Hashtable();
65         private static short[] sbank = null;
66         private static int[] ibank = null;
67         private static byte[] bbank = null;
68         private static int bank_start = 0;
69         
70         public void drawPicture(Picture source, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) {
71             _doDrawImage(g, ((AWTPicture)source).i, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
72         }
73         
74         public Java2DoubleBuffer(int w, int h) {
75             super(w, h);
76             SampleModel sm = cm.createCompatibleSampleModel(w, h);
77             DataBuffer buf = null;
78             if (sm.getDataType() == DataBuffer.TYPE_USHORT) {
79                 if (sbank == null || w * h > 512 * 512 / 3) {
80                     buf = new DataBufferUShort(w * h);
81                 } else {
82                     if (w * h > sbank.length - bank_start) {
83                         bank_start = 0;
84                         sbank = new short[512 * 512];
85                     }
86                     buf = new DataBufferUShort(sbank, w * h, bank_start);
87                     bank_start += w * h;
88                 }
89             } else if (sm.getDataType() == DataBuffer.TYPE_BYTE) {
90                 if (bbank == null || w * h > 512 * 512 / 3) {
91                     buf = new DataBufferByte(w * h);
92                 } else {
93                     if (w * h > bbank.length - bank_start) {
94                         bank_start = 0;
95                         bbank = new byte[512 * 512];
96                     }
97                     buf = new DataBufferByte(bbank, w * h, bank_start);
98                     bank_start += w * h;
99                 }
100             } else if (sm.getDataType() == DataBuffer.TYPE_INT) {
101                 if (ibank == null || w * h > 512 * 512 / 3) {
102                     buf = new DataBufferInt(w * h);
103                 } else {
104                     if (w * h > ibank.length - bank_start) {
105                         bank_start = 0;
106                         ibank = new int[512 * 512];
107                     }
108                     buf = new DataBufferInt(ibank, w * h, bank_start);
109                     bank_start += w * h;
110                 }
111             }
112             i = new BufferedImage(cm, Raster.createWritableRaster(sm, buf, null), false,  emptyHashtable);
113             g = i.getGraphics();
114         }
115     }
116
117     /** used to avoid garbage creation with getClipBounds() */
118     private static Rectangle clipBounds = new Rectangle();
119     
120     // FEATURE: performance hits here are a result of getSubimage() -- if we don't call it, Graphics2D will. It creates tons of int[]s, as well as
121     // BufferedImage instances which get stored in an array deep inside Graphics2D, which the JDK does a LINEAR SCAN through. Aarrgh.
122     // This is rumored to be fixed in JDK 1.4.
123     protected static void _doDrawImage(Graphics g, Image i, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver o) {
124         
125         if (dx1 == dx2 || dy1 == dy2) return;
126
127         if (dx2 - dx1 != sx2 - sx1 || dy2 - dy1 != sy2 - sy1)
128             g.drawImage(i, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, o);
129         else {
130             // fastpath for images that do not need to be scaled
131             if (i instanceof BufferedImage) {
132                 BufferedImage b = (BufferedImage)i;
133                 
134                 if (dx2 - dx1 != b.getWidth(null) || dy2 - dy1 != b.getHeight(null)) {
135                     b = b.getSubimage(sx1, sy1, sx2 - sx1, sy2 - sy1);
136                     sx2 = sx2 - sx1;
137                     sy2 = sy2 - sy1;
138                     sx1 = 0;
139                     sy1 = 0;
140                 }
141                 g.drawImage(b, dx1, dy1, o);
142                 
143             } else {
144
145                 // workaround for a wierd JDK bug
146                 boolean skip = false;
147                 try { g.getClipBounds(clipBounds); } catch (NullPointerException n) { skip = true; }
148
149                 g.clipRect(dx1, dy1, dx2 - dx1, dy2 - dy1);
150                 g.drawImage(i, dx1 - sx1, dy1 - sy1, o);
151
152                 if (!skip) g.setClip(clipBounds.x, clipBounds.y, clipBounds.x + clipBounds.width, clipBounds.y + clipBounds.height);
153             }
154         }
155     }
156
157     protected org.xwt.Weak _getWeak(Object o) { return new Java2Weak(o); }
158     private static class Java2Weak extends java.lang.ref.WeakReference implements org.xwt.Weak {
159         public Java2Weak(Object o) { super(o); }
160     }
161
162     private String __getClipBoard() { return super._getClipBoard(); }
163     protected String _getClipBoard() {
164         return (String)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {
165                 public Object run() { return __getClipBoard();  }
166             });
167     }
168
169     private void __setClipBoard(String s) { super._setClipBoard(s); }
170     protected void _setClipBoard(final String s) {
171         java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {
172                 public Object run() {
173                     __setClipBoard(s);
174                     return null;
175                 }
176             });
177     }
178
179     protected String getDescriptiveName() { return "Java 1.2+ JVM"; }
180 }