diff options
Diffstat (limited to 'gnu/java')
-rw-r--r-- | gnu/java/awt/peer/gtk/AsyncImage.java | 283 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/BufferedImageGraphics.java | 48 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/CairoGraphics2D.java | 2 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/ComponentGraphics.java | 1 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/FreetypeGlyphVector.java | 17 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/GtkToolkit.java | 23 | ||||
-rw-r--r-- | gnu/java/lang/management/BeanImpl.java | 7 | ||||
-rw-r--r-- | gnu/java/net/protocol/http/HTTPConnection.java | 50 | ||||
-rw-r--r-- | gnu/java/net/protocol/http/HTTPURLConnection.java | 40 |
9 files changed, 407 insertions, 64 deletions
diff --git a/gnu/java/awt/peer/gtk/AsyncImage.java b/gnu/java/awt/peer/gtk/AsyncImage.java new file mode 100644 index 000000000..5238bfe74 --- /dev/null +++ b/gnu/java/awt/peer/gtk/AsyncImage.java @@ -0,0 +1,283 @@ +/* AsyncImage.java -- Loads images asynchronously + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.gtk; + +import java.awt.Graphics; +import java.awt.Image; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; + +/** + * Supports asynchronous loading of images. + */ +public class AsyncImage + extends Image +{ + + /** + * Returned as source as long as the image is not complete. + */ + private class NullImageSource + implements ImageProducer + { + private ArrayList consumers; + + NullImageSource() + { + consumers = new ArrayList(); + } + + public void addConsumer(ImageConsumer ic) + { + consumers.add(ic); + } + + public boolean isConsumer(ImageConsumer ic) + { + return consumers.contains(ic); + } + + public void removeConsumer(ImageConsumer ic) + { + consumers.remove(ic); + } + + public void requestTopDownLeftRightResend(ImageConsumer ic) + { + startProduction(ic); + } + + public void startProduction(ImageConsumer ic) + { + consumers.add(ic); + for (int i = consumers.size() - 1; i >= 0; i--) + { + ImageConsumer c = (ImageConsumer) consumers.get(i); + c.setDimensions(1, 1); + ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE); + } + } + + } + + /** + * Loads the image asynchronously. + */ + private class Loader + implements Runnable + { + private URL url; + Loader(URL u) + { + url = u; + } + + public void run() + { + Image image; + try + { + GtkImage gtkImage = new GtkImage(url); + image = CairoSurface.getBufferedImage(gtkImage); + } + catch (IllegalArgumentException iae) + { + image = null; + } + realImage = GtkToolkit.imageOrError(image); + synchronized (AsyncImage.this) + { + notifyObservers(ImageObserver.ALLBITS | ImageObserver.HEIGHT + | ImageObserver.WIDTH | ImageObserver.PROPERTIES); + observers = null; // Not needed anymore. + } + } + } + + /** + * The real image. This is null as long as the image is not complete. + */ + Image realImage; + + /** + * The image observers. + * + * This is package private to avoid accessor methods. + */ + HashSet observers; + + /** + * Creates a new AsyncImage that loads from the specified URL. + */ + AsyncImage(URL url) + { + observers = new HashSet(); + Loader l = new Loader(url); + Thread t = new Thread(l); + t.start(); + } + + public void flush() + { + // Nothing to do here. + } + + public Graphics getGraphics() + { + Image r = realImage; + Graphics g = null; + if (r != null) + g = r.getGraphics(); // Should we return some dummy graphics instead? + return g; + } + + public int getHeight(ImageObserver observer) + { + addObserver(observer); + int height = 0; + Image r = realImage; + if (r != null) + height = r.getHeight(observer); + return height; + } + + public Object getProperty(String name, ImageObserver observer) + { + addObserver(observer); + Image r = realImage; + Object prop = null; + if (r != null) + prop = r.getProperty(name, observer); + return prop; + } + + public ImageProducer getSource() + { + Image r = realImage; + ImageProducer source; + if (r == null) + source = new NullImageSource(); + else + source = r.getSource(); + return source; + } + + public int getWidth(ImageObserver observer) + { + addObserver(observer); + int width = 0; + Image r = realImage; + if (r != null) + width = r.getWidth(observer); + return width; + } + + void addObserver(ImageObserver obs) + { + if (obs != null) + { + synchronized (this) + { + // This field gets null when image loading is complete and we don't + // need to store any more observers. + HashSet observs = observers; + if (observs != null) + { + observs.add(obs); + } + else + { + // When the image is complete, notify the observer. Dunno if + // that's really needed, but to be sure. + obs.imageUpdate(this, ImageObserver.WIDTH + | ImageObserver.HEIGHT + |ImageObserver.ALLBITS + | ImageObserver.PROPERTIES, 0, 0, + realImage.getWidth(null), + realImage.getHeight(null)); + } + } + } + } + + static Image realImage(Image img, ImageObserver obs) + { + if (img instanceof AsyncImage) + { + ((AsyncImage) img).addObserver(obs); + Image r = ((AsyncImage) img).realImage; + if (r != null) + img = r; + } + return img; + } + + void notifyObservers(int status) + { + assert Thread.holdsLock(this); + // This field gets null when image loading is complete. + HashSet observs = observers; + if (observs != null) + { + Image r = realImage; + Iterator i = observs.iterator(); + while (i.hasNext()) + { + ImageObserver obs = (ImageObserver) i.next(); + obs.imageUpdate(this, status, 0, 0, r.getWidth(null), + r.getHeight(null)); + } + } + } + + int checkImage(ImageObserver obs) + { + addObserver(obs); + int flags = 0; + if (realImage != null) + flags = ImageObserver.ALLBITS | ImageObserver.WIDTH + | ImageObserver.HEIGHT | ImageObserver.PROPERTIES; + return flags; + } +} diff --git a/gnu/java/awt/peer/gtk/BufferedImageGraphics.java b/gnu/java/awt/peer/gtk/BufferedImageGraphics.java index 37ae498ad..c792645d3 100644 --- a/gnu/java/awt/peer/gtk/BufferedImageGraphics.java +++ b/gnu/java/awt/peer/gtk/BufferedImageGraphics.java @@ -137,27 +137,45 @@ public class BufferedImageGraphics extends CairoGraphics2D cairo_t = surface.newCairoContext(); + // Get pixels out of buffered image and set in cairo surface Raster raster = bi.getRaster(); int[] pixels; - // get pixels - if(raster instanceof CairoSurface) - pixels = ((CairoSurface)raster).getPixels(imageWidth * imageHeight); + if (hasFastCM) + { + SinglePixelPackedSampleModel sm = (SinglePixelPackedSampleModel)image.getSampleModel(); + int minX = image.getRaster().getSampleModelTranslateX(); + int minY = image.getRaster().getSampleModelTranslateY(); + + // Pull pixels directly out of data buffer + if(raster instanceof CairoSurface) + pixels = ((CairoSurface)raster).getPixels(raster.getWidth() * raster.getHeight()); + else + pixels = ((DataBufferInt)raster.getDataBuffer()).getData(); + + // Discard pixels that fall outside of the image's bounds + // (ie, this image is actually a subimage of a different image) + if (!(sm.getScanlineStride() == imageWidth && minX == 0 && minY == 0)) + { + int[] pixels2 = new int[imageWidth * imageHeight]; + int scanline = sm.getScanlineStride(); + + for (int i = 0; i < imageHeight; i++) + System.arraycopy(pixels, (i - minY) * scanline - minX, pixels2, i * imageWidth, imageWidth); + + pixels = pixels2; + } + + // Fill the alpha channel as opaque if image does not have alpha + if( !hasAlpha ) + for(int i = 0; i < pixels.length; i++) + pixels[i] &= 0xFFFFFFFF; + } else { - if( hasFastCM ) - { - pixels = ((DataBufferInt)raster.getDataBuffer()).getData(); - if( !hasAlpha ) - for(int i = 0; i < pixels.length; i++) - pixels[i] &= 0xFFFFFFFF; - } - else - { - pixels = CairoGraphics2D.findSimpleIntegerArray - (image.getColorModel(),image.getData()); - } + pixels = CairoGraphics2D.findSimpleIntegerArray(image.getColorModel(),image.getData()); } + surface.setPixels( pixels ); setup( cairo_t ); diff --git a/gnu/java/awt/peer/gtk/CairoGraphics2D.java b/gnu/java/awt/peer/gtk/CairoGraphics2D.java index ec9890524..348801800 100644 --- a/gnu/java/awt/peer/gtk/CairoGraphics2D.java +++ b/gnu/java/awt/peer/gtk/CairoGraphics2D.java @@ -1463,7 +1463,7 @@ public abstract class CairoGraphics2D extends Graphics2D // Note - this can get us in trouble when the gdk lock is re-acquired. // for example by VolatileImage. See ComponentGraphics for how we work // around this. - + img = AsyncImage.realImage(img, obs); if( !(img instanceof BufferedImage) ) { ImageProducer source = img.getSource(); diff --git a/gnu/java/awt/peer/gtk/ComponentGraphics.java b/gnu/java/awt/peer/gtk/ComponentGraphics.java index 612efd628..763ad7dfd 100644 --- a/gnu/java/awt/peer/gtk/ComponentGraphics.java +++ b/gnu/java/awt/peer/gtk/ComponentGraphics.java @@ -468,6 +468,7 @@ public class ComponentGraphics extends CairoGraphics2D } BufferedImage bimg; + img = AsyncImage.realImage(img, observer); if (img instanceof BufferedImage) bimg = (BufferedImage) img; else diff --git a/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java b/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java index 4ad87a84b..131a96448 100644 --- a/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java +++ b/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java @@ -101,13 +101,7 @@ public class FreetypeGlyphVector extends GlyphVector public FreetypeGlyphVector(Font f, char[] chars, int start, int len, FontRenderContext frc, int flags) { - // We need to filter out control characters (and possibly other - // non-renderable characters here). - StringBuilder b = new StringBuilder(chars.length); - for (int i = start; i < start + len; i++) - if (!Character.isISOControl(chars[i])) - b.append(chars[i]); - this.s = b.toString(); + this.s = new String(chars, start, len); this.font = f; this.frc = frc; @@ -187,10 +181,17 @@ public class FreetypeGlyphVector extends GlyphVector for(int i = 0; i < nGlyphs; i++) { codePoints[i] = s.codePointAt( stringIndex ); - // UTF32 surrogate handling + // UTF32 surrogate handling if( codePoints[i] != (int)s.charAt( stringIndex ) ) stringIndex ++; stringIndex ++; + + if (Character.isISOControl(codePoints[i])) + { + // Replace with 'hair space'. Should better be 'zero-width space' + // but that doesn't seem to be supported by default font. + codePoints[i] = 8202; + } } glyphCodes = getGlyphs( codePoints ); diff --git a/gnu/java/awt/peer/gtk/GtkToolkit.java b/gnu/java/awt/peer/gtk/GtkToolkit.java index 26724206d..f746a4747 100644 --- a/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -176,6 +176,9 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit if (image instanceof GtkImage) return ((GtkImage) image).checkImage (observer); + if (image instanceof AsyncImage) + return ((AsyncImage) image).checkImage(observer); + if (observer != null) observer.imageUpdate (image, status, -1, -1, @@ -189,7 +192,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit * Helper to return either a Image -- the argument -- or a * GtkImage with the errorLoading flag set if the argument is null. */ - private Image imageOrError(Image b) + static Image imageOrError(Image b) { if (b == null) return GtkImage.getErrorImage(); @@ -216,16 +219,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit public Image createImage (URL url) { - Image image; - try - { - image = CairoSurface.getBufferedImage( new GtkImage( url ) ); - } - catch (IllegalArgumentException iae) - { - image = null; - } - return imageOrError(image); + return new AsyncImage(url); } public Image createImage (ImageProducer producer) @@ -391,6 +385,13 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit return ((((GtkImage)image).checkImage (observer) & ImageObserver.ALLBITS) != 0); + if (image instanceof AsyncImage) + { + AsyncImage aImg = (AsyncImage) image; + aImg.addObserver(observer); + return aImg.realImage != null; + } + /* Assume anything else is too */ return true; } diff --git a/gnu/java/lang/management/BeanImpl.java b/gnu/java/lang/management/BeanImpl.java index 529ee5896..10ae420b3 100644 --- a/gnu/java/lang/management/BeanImpl.java +++ b/gnu/java/lang/management/BeanImpl.java @@ -500,11 +500,8 @@ public class BeanImpl { OpenType e = SimpleType.VOID; TypeVariable[] vars = c.getTypeParameters(); - for (int a = 0; a < vars.length; ++a) - { - if (vars[a].getName().equals("E")) - e = getTypeFromClass((Class) vars[a].getGenericDeclaration()); - } + if (vars.length > 0) + e = getTypeFromClass((Class) vars[0].getGenericDeclaration()); return new OpenMBeanParameterInfoSupport("TransParam", "Translated parameter", new ArrayType(1, e) diff --git a/gnu/java/net/protocol/http/HTTPConnection.java b/gnu/java/net/protocol/http/HTTPConnection.java index f5e831c6a..3956d2aba 100644 --- a/gnu/java/net/protocol/http/HTTPConnection.java +++ b/gnu/java/net/protocol/http/HTTPConnection.java @@ -48,6 +48,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; +import java.net.SocketException; import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.HashMap; @@ -227,10 +228,16 @@ public class HTTPConnection * @param secure whether to use a secure connection * @param connectionTimeout the connection timeout * @param timeout the socket read timeout + * + * @throws IllegalArgumentException if either connectionTimeout or + * timeout less than zero. */ public HTTPConnection(String hostname, int port, boolean secure, int connectionTimeout, int timeout) { + if (connectionTimeout < 0 || timeout < 0) + throw new IllegalArgumentException(); + this.hostname = hostname; this.port = port; this.secure = secure; @@ -471,14 +478,32 @@ public class HTTPConnection { String ttl = SystemProperties.getProperty("classpath.net.http.keepAliveTTL"); - connectionTTL = (ttl != null && ttl.length() > 0) ? - 1000 * Math.max(1, Integer.parseInt(ttl)) : 10000; + connectionTTL = 10000; + if (ttl != null && ttl.length() > 0) + try + { + int v = 1000 * Integer.parseInt(ttl); + if (v >= 0) + connectionTTL = v; + } + catch (NumberFormatException _) + { + // Ignore. + } String mc = SystemProperties.getProperty("http.maxConnections"); - maxConnections = (mc != null && mc.length() > 0) ? - Math.max(Integer.parseInt(mc), 1) : 5; - if (maxConnections < 1) - maxConnections = 1; + maxConnections = 5; + if (mc != null && mc.length() > 0) + try + { + int v = Integer.parseInt(mc); + if (v > 0) + maxConnections = v; + } + catch (NumberFormatException _) + { + // Ignore. + } HTTPConnection c = null; @@ -490,12 +515,23 @@ public class HTTPConnection { c = cc; it.remove(); + // Update the timeout. + if (c.socket != null) + try + { + c.socket.setSoTimeout(timeout); + } + catch (SocketException _) + { + // Ignore. + } break; } } if (c == null) { - c = new HTTPConnection(host, port, secure, connectionTimeout, timeout); + c = new HTTPConnection(host, port, secure, + connectionTimeout, timeout); c.setPool(this); } return c; diff --git a/gnu/java/net/protocol/http/HTTPURLConnection.java b/gnu/java/net/protocol/http/HTTPURLConnection.java index cc68a3bac..6c926b72f 100644 --- a/gnu/java/net/protocol/http/HTTPURLConnection.java +++ b/gnu/java/net/protocol/http/HTTPURLConnection.java @@ -75,7 +75,7 @@ public class HTTPURLConnection // These are package private for use in anonymous inner classes. String proxyHostname; - int proxyPort; + int proxyPort = -1; String agent; boolean keepAlive; @@ -99,18 +99,21 @@ public class HTTPURLConnection { super(url); requestHeaders = new Headers(); - proxyHostname = SystemProperties.getProperty("http.proxyHost"); - if (proxyHostname != null && proxyHostname.length() > 0) + String proxy = SystemProperties.getProperty("http.proxyHost"); + if (proxy != null && proxy.length() > 0) { String port = SystemProperties.getProperty("http.proxyPort"); if (port != null && port.length() > 0) { - proxyPort = Integer.parseInt(port); - } - else - { - proxyHostname = null; - proxyPort = -1; + try + { + proxyPort = Integer.parseInt(port); + proxyHostname = proxy; + } + catch (NumberFormatException _) + { + // Ignore. + } } } agent = SystemProperties.getProperty("http.agent"); @@ -354,11 +357,14 @@ public class HTTPURLConnection HTTPConnection connection; if (keepAlive) { - connection = HTTPConnection.Pool.instance.get(host, port, secure, getConnectTimeout(), 0); + connection = HTTPConnection.Pool.instance.get(host, port, secure, + getConnectTimeout(), + getReadTimeout()); } else { - connection = new HTTPConnection(host, port, secure, 0, getConnectTimeout()); + connection = new HTTPConnection(host, port, secure, + getConnectTimeout(), getReadTimeout()); } return connection; } @@ -662,23 +668,23 @@ public class HTTPURLConnection } /** - * Set the connection timeout speed, in milliseconds, or zero if the timeout + * Set the read timeout, in milliseconds, or zero if the timeout * is to be considered infinite. * * Overloaded. * */ - public void setConnectTimeout(int timeout) + public void setReadTimeout(int timeout) throws IllegalArgumentException { - super.setConnectTimeout( timeout ); - if( connection == null ) + super.setReadTimeout(timeout); + if (connection == null) return; try { - connection.getSocket().setSoTimeout( timeout ); + connection.getSocket().setSoTimeout(timeout); } - catch(IOException se) + catch (IOException se) { // Ignore socket exceptions. } |