diff options
Diffstat (limited to 'libjava/classpath/gnu/java/awt/peer')
50 files changed, 1742 insertions, 1882 deletions
diff --git a/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java b/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java index 60fde2557ac..e43e5f284ed 100644 --- a/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java @@ -644,7 +644,7 @@ public abstract class ClasspathFontPeer * be ignored. */ - public abstract boolean canDisplay (Font font, char c); + public abstract boolean canDisplay (Font font, int c); /** * Implementation of {@link Font#canDisplay(String)}, diff --git a/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java b/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java index f9a7bac8ee6..bf40bf379fa 100644 --- a/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java @@ -449,4 +449,13 @@ public class GLightweightPeer { // Nothing to do here for lightweights. } + + public boolean requestFocus(Component lightweightChild, boolean temporary, + boolean focusedWindowChangeAllowed, + long time, sun.awt.CausedFocusEvent.Cause cause) + { + // Always grant focus request. + return true; + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java index 3a386075a69..db8acd1cda0 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java @@ -1726,7 +1726,8 @@ public abstract class CairoGraphics2D extends Graphics2D .equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)); ignoreAA = true; - if (gv instanceof FreetypeGlyphVector && alpha == 1.0) + if (gv instanceof FreetypeGlyphVector && alpha == 1.0 + && !((FreetypeGlyphVector)gv).hasTransforms()) { int n = gv.getNumGlyphs (); int[] codes = gv.getGlyphCodes (0, n, null); @@ -2164,4 +2165,4 @@ public abstract class CairoGraphics2D extends Graphics2D return new Rectangle2D.Double(minX, minY, (maxX - minX), (maxY - minY)); } -} +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java index e54320697d8..4ce20a30d32 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java @@ -938,4 +938,4 @@ public class ComponentGraphics extends CairoGraphics2D unlock(); } } -} +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java b/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java index 280f3e6fbcd..8d6d01ae317 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java @@ -43,6 +43,8 @@ import java.awt.font.FontRenderContext; import java.awt.font.GlyphJustificationInfo; import java.awt.font.GlyphMetrics; import java.awt.font.GlyphVector; +import java.awt.font.TextAttribute; +import java.awt.font.TransformAttribute; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; @@ -86,7 +88,10 @@ public class FreetypeGlyphVector extends GlyphVector private long[] fontSet = null; /** - * Glyph transforms. (de facto only the translation is used) + * Glyph transforms. Supports all transform operations. + * + * The identity transform should not be stored in this array; use a null + * instead (will result in performance improvements). */ private AffineTransform[] glyphTransforms; @@ -185,9 +190,12 @@ public class FreetypeGlyphVector extends GlyphVector fontSet = new long[nGlyphs]; glyphPositions = new float[(nGlyphs + 1) * 2]; glyphTransforms = new AffineTransform[ nGlyphs ]; + Arrays.fill(glyphTransforms, null); + for(int i = 0; i < nGlyphs; i++ ) { - glyphTransforms[ i ] = new AffineTransform( gv.glyphTransforms[ i ] ); + if (gv.glyphTransforms[i] != null) + glyphTransforms[ i ] = new AffineTransform(gv.glyphTransforms[i]); glyphCodes[i] = gv.glyphCodes[ i ]; } System.arraycopy(gv.glyphPositions, 0, glyphPositions, 0, @@ -313,6 +321,25 @@ public class FreetypeGlyphVector extends GlyphVector } glyphPositions[nGlyphs * 2] = x; glyphPositions[nGlyphs * 2 + 1] = y; + + // Apply any transform that may be in the font's attributes + TransformAttribute ta; + ta = (TransformAttribute)font.getAttributes().get(TextAttribute.TRANSFORM); + if (ta != null) + { + AffineTransform tx = ta.getTransform(); + + // Transform glyph positions + tx.transform(glyphPositions, 0, glyphPositions, 0, + glyphPositions.length / 2); + + // Also store per-glyph scale/shear/rotate (but not translation) + double[] matrix = new double[4]; + tx.getMatrix(matrix); + AffineTransform deltaTx = new AffineTransform(matrix); + if (!deltaTx.isIdentity()) + Arrays.fill(glyphTransforms, deltaTx); + } } /** @@ -375,7 +402,7 @@ public class FreetypeGlyphVector extends GlyphVector p.getY() + r.getY() + r.getHeight()}; if (glyphTransforms[glyphIndex] != null) - glyphTransforms[glyphIndex].transform(bounds, 0, bounds, 0, 4); + glyphTransforms[glyphIndex].transform(bounds, 0, bounds, 0, 2); return new Rectangle2D.Double(bounds[0], bounds[1], bounds[2] - bounds[0], bounds[3] - bounds[1]); @@ -473,7 +500,19 @@ public class FreetypeGlyphVector extends GlyphVector { return glyphTransforms[glyphIndex]; } - + + /** + * Checks whether any transform has been set on any glyphs. + */ + protected boolean hasTransforms() + { + for (int i = 0; i < glyphTransforms.length; i++) + if (glyphTransforms[i] != null) + return true; + + return false; + } + /** * Returns the visual bounds of a glyph * May be off by a pixel or two due to hinting/rasterization. @@ -570,6 +609,19 @@ public class FreetypeGlyphVector extends GlyphVector */ public void setGlyphTransform(int glyphIndex, AffineTransform newTX) { + // The identity transform should never be in the glyphTransforms array; + // using and checking for nulls can be much faster. + if (newTX != null && newTX.isIdentity()) + newTX = null; + + // If the old and new transforms are identical, bail + if (glyphTransforms[glyphIndex] == null && newTX == null) + return; + + if (newTX != null && newTX.equals(glyphTransforms[glyphIndex])) + return; + + // Invalidate bounds cache and set new transform logicalBounds = null; glyphTransforms[glyphIndex] = newTX; } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java index c3c94d8a935..95a806ac7ee 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java @@ -38,6 +38,8 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; +import gnu.classpath.Pointer; + import gnu.java.awt.ClasspathToolkit; import gnu.java.awt.peer.ClasspathFontPeer; import gnu.java.awt.font.opentype.NameDecoder; @@ -172,6 +174,14 @@ public class GdkFontPeer extends ClasspathFontPeer private ByteBuffer nameTable = null; + /** + * The pointer to the native font data. + * + * This field is manipulated by native code. Don't change or remove + * without adjusting the native code. + */ + private Pointer nativeFont; + private native void initState (); private native void dispose (); private native void setFont (String family, int style, int size); @@ -351,7 +361,7 @@ public class GdkFontPeer extends ClasspathFontPeer return NameDecoder.getName(nameTable, name, locale); } - public boolean canDisplay (Font font, char c) + public boolean canDisplay (Font font, int c) { // FIXME: inquire with pango return true; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java index bd6daa2d1e5..67040b82a0f 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java @@ -52,6 +52,8 @@ import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import java.util.Locale; +import gnu.classpath.Pointer; + public class GdkGraphicsEnvironment extends ClasspathGraphicsEnvironment { private final int native_state = GtkGenericPeer.getUniqueInteger (); @@ -59,15 +61,24 @@ public class GdkGraphicsEnvironment extends ClasspathGraphicsEnvironment private GdkScreenGraphicsDevice defaultDevice; private GdkScreenGraphicsDevice[] devices; - + + /** + * The pointer to the native display resource. + * + * This field is manipulated by native code. Don't change or remove + * without adjusting the native code. + */ + private Pointer display; + static { System.loadLibrary("gtkpeer"); - initStaticState (); + GtkToolkit.initializeGlobalIDs(); + initIDs(); } - static native void initStaticState(); + private static native void initIDs(); public GdkGraphicsEnvironment () { diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java index 6f6ea560db7..e52bf050c09 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java @@ -68,6 +68,8 @@ import javax.imageio.spi.ImageWriterSpi; import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageOutputStream; +import gnu.classpath.Pointer; + public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder { static @@ -94,6 +96,14 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder // the current set of ImageConsumers for this decoder Vector curr; + /** + * The pointer to the native pixbuf loader. + * + * This field is manipulated by native code. Don't change or remove + * without adjusting the native code. + */ + private Pointer nativeDecoder; + // interface to GdkPixbuf // These native functions should be called with the pixbufLock held. native void initState (); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkRobotPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkRobotPeer.java index 6d0218d057a..d3e9774daa0 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkRobotPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkRobotPeer.java @@ -91,4 +91,9 @@ public class GdkRobotPeer implements RobotPeer return pixels; } + + public void dispose() + { + // Nothing to do here yet. + } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java index a69c6f0659e..7ef4645a257 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java @@ -46,6 +46,8 @@ import java.awt.Rectangle; import java.awt.Window; import java.util.ArrayList; +import gnu.classpath.Pointer; + class GdkScreenGraphicsDevice extends GraphicsDevice { private final int native_state = GtkGenericPeer.getUniqueInteger (); @@ -85,15 +87,23 @@ class GdkScreenGraphicsDevice extends GraphicsDevice * method must be called. */ DisplayMode fixedDisplayMode; - + + /** + * The pointer to the native screen resource. + * + * This field is manipulated by native code. Don't change or remove + * without adjusting the native code. + */ + private Pointer screen; + static { System.loadLibrary("gtkpeer"); - - initStaticState (); + GtkToolkit.initializeGlobalIDs(); + initIDs(); } - static native void initStaticState(); + static native void initIDs(); GdkScreenGraphicsDevice (GdkGraphicsEnvironment e) { diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java index a7ae8e17f2b..16c20ee253f 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -616,11 +616,18 @@ public class GtkComponentPeer extends GtkGenericPeer setVisible (true); } - protected void postMouseEvent(int id, long when, int mods, int x, int y, + protected void postMouseEvent(int id, long when, int mods, int x, int y, int clickCount, boolean popupTrigger) { - q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y, - clickCount, popupTrigger)); + // It is important to do the getLocationOnScreen() here, instead + // of using the old MouseEvent constructors, because + // Component.getLocationOnScreen() locks on the AWT lock, which can + // trigger a deadlock. You don't want this. + Point locOnScreen = getLocationOnScreen(); + q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y, + locOnScreen.x + x, locOnScreen.y + y, + clickCount, popupTrigger, + MouseEvent.NOBUTTON)); } /** @@ -899,4 +906,14 @@ public class GtkComponentPeer extends GtkGenericPeer // FIXME: implement } + + public boolean requestFocus(Component lightweightChild, boolean temporary, + boolean focusedWindowChangeAllowed, + long time, sun.awt.CausedFocusEvent.Cause cause) + { + // TODO: Implement this properly and remove the other requestFocus() + // methods. + return true; + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java index b35be522746..4278a4579e4 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java @@ -244,6 +244,13 @@ public class GtkFramePeer extends GtkWindowPeer // TODO Auto-generated method stub return false; } + + public Rectangle getBoundsPrivate() + { + // TODO: Implement this properly. + throw new InternalError("Not yet implemented"); + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkGenericPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkGenericPeer.java index 468c46dc4af..8d63699eab8 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkGenericPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkGenericPeer.java @@ -43,6 +43,8 @@ import java.awt.Font; import java.awt.Toolkit; import java.awt.event.ActionEvent; +import gnu.classpath.Pointer; + public class GtkGenericPeer { // Used by Native State Association (NSA) functions to map @@ -56,6 +58,40 @@ public class GtkGenericPeer protected final Object awtWidget; /** + * The pointer to the native GTK widget. + * + * This field is manipulated by native code. Don't change or remove + * without adjusting the native code. + */ + private Pointer widget; + + /** + * The pointer to the global reference to this object. The native + * code creates a JNI global reference of the peer object to be able + * to pass it to the event callbacks. It gets stored here, so that + * we can later delete it in the dispose() method. + * + * This field is manipulated by native code. Don't change or remove + * without adjusting the native code. + */ + private Pointer globalRef; + + /** + * We initialize the field IDs that are used by native code here because + * these remain valid until a class gets unloaded. + */ + static + { + GtkToolkit.initializeGlobalIDs(); + initIDs(); + } + + /** + * Initializes the field IDs that are used by the native code. + */ + private static native void initIDs(); + + /** * Dispose of our native state. Calls gtk_widget_destroy on the * native widget and removes the awtWidget from the native state * tables. Should be overridden by subclasses if this is not (all) diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java index df18d39c9d2..dc9c7155e6e 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -144,10 +144,39 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit static native void gtkQuit(); + /** + * Initializes field IDs that are used by native code. + */ + private static native void initIDs(); + + /** + * True when the field IDs are already initialized, false otherwise. + */ + private static boolean initializedGlobalIDs = false; + + /** + * Initializes some global fieldIDs for use in the native code. This is + * called by a couple of classes in the GTK peers to ensure that + * some necessary stuff is loaded. + */ + static synchronized void initializeGlobalIDs() + { + if (! initializedGlobalIDs) + { + initIDs(); + initializedGlobalIDs = true; + } + } + static { System.loadLibrary("gtkpeer"); - + + /** + * Gotta do that first. + */ + initializeGlobalIDs(); + int portableNativeSync; String portNatSyncProp = System.getProperty("gnu.classpath.awt.gtk.portable.native.sync"); @@ -716,4 +745,17 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit public native int getMouseNumberOfButtons(); + @Override + public boolean isModalExclusionTypeSupported + (Dialog.ModalExclusionType modalExclusionType) + { + return false; + } + + @Override + public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) + { + return false; + } + } // class GtkToolkit diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java index 1451dd93354..d8054150dea 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java @@ -398,4 +398,29 @@ public class GtkWindowPeer extends GtkContainerPeer { return new Rectangle(x, y, width, height); } + + public void updateIconImages() + { + // TODO: Implement properly. + } + + public void updateMinimumSize() + { + // TODO: Implement properly. + } + + public void setModalBlocked(java.awt.Dialog d, boolean b) + { + // TODO: Implement properly. + } + + public void updateFocusableWindowState() + { + // TODO: Implement properly. + } + + public void setAlwaysOnTop(boolean b) + { + // TODO: Implement properly. + } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java index 88438862b34..ad5cd5ecdf2 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java @@ -86,7 +86,17 @@ public class VolatileImageGraphics extends ComponentGraphics public GraphicsConfiguration getDeviceConfiguration() { - return owner.component.getGraphicsConfiguration(); + GraphicsConfiguration conf; + if (owner.component != null) + { + conf = owner.component.getGraphicsConfiguration(); + } + else + { + return java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getDefaultConfiguration(); + } + return conf; } public Graphics create() diff --git a/libjava/classpath/gnu/java/awt/peer/headless/HeadlessToolkit.java b/libjava/classpath/gnu/java/awt/peer/headless/HeadlessToolkit.java index 96798c9e9d8..58b5f333427 100644 --- a/libjava/classpath/gnu/java/awt/peer/headless/HeadlessToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/headless/HeadlessToolkit.java @@ -368,4 +368,18 @@ public class HeadlessToolkit return graphicsEnv; } + @Override + public boolean isModalExclusionTypeSupported + (Dialog.ModalExclusionType modalExclusionType) + { + return false; + } + + @Override + public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) + { + return false; + } + + } diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtComponentPeer.java index 4d7b58c4d87..334f5908825 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtComponentPeer.java @@ -821,4 +821,14 @@ public class QtComponentPeer extends NativeWrapper implements ComponentPeer { // TODO Auto-generated method stub } + + public boolean requestFocus(Component lightweightChild, boolean temporary, + boolean focusedWindowChangeAllowed, + long time, sun.awt.CausedFocusEvent.Cause cause) + { + // TODO: Implement this properly and remove the other requestFocus() + // methods. + return true; + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java b/libjava/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java index 2438fcc3282..3b182b5eada 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java @@ -94,7 +94,7 @@ public class QtFontMetrics extends FontMetrics // ****************** Package private *************************** - native boolean canDisplay( char c ); + native boolean canDisplay( int c ); // ****************** Public methods **************************** diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtFontPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtFontPeer.java index 6ffe3f69176..bd16daf28cb 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtFontPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtFontPeer.java @@ -98,7 +98,7 @@ public class QtFontPeer extends ClasspathFontPeer // ****************** ClasspathFontPeer Methods. - public boolean canDisplay (Font font, char c) + public boolean canDisplay (Font font, int c) { return metrics.canDisplay( c ); } diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtFramePeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtFramePeer.java index b2c6a5921cb..e3b578933ac 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtFramePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtFramePeer.java @@ -155,4 +155,10 @@ public class QtFramePeer extends QtWindowPeer implements FramePeer return false; } + public Rectangle getBoundsPrivate() + { + // TODO: Implement this properly. + throw new InternalError("Not yet implemented"); + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java b/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java index 9b53b278b26..4cea976ac22 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java @@ -452,4 +452,19 @@ public class QtToolkit extends ClasspathToolkit // return new QtEmbeddedWindowPeer( this, w ); return null; } + + @Override + public boolean isModalExclusionTypeSupported + (Dialog.ModalExclusionType modalExclusionType) + { + return false; + } + + @Override + public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) + { + return false; + } + + } diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtWindowPeer.java index 7baf8e6ebea..e0a9e8c55d9 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtWindowPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtWindowPeer.java @@ -77,4 +77,29 @@ public class QtWindowPeer extends QtContainerPeer implements WindowPeer return false; } + public void updateIconImages() + { + // TODO: Implement properly. + } + + public void updateMinimumSize() + { + // TODO: Implement properly. + } + + public void setModalBlocked(java.awt.Dialog d, boolean b) + { + // TODO: Implement properly. + } + + public void updateFocusableWindowState() + { + // TODO: Implement properly. + } + + public void setAlwaysOnTop(boolean b) + { + // TODO: Implement properly. + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingButtonPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingButtonPeer.java index 531d6f2db3b..192d612ee79 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingButtonPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingButtonPeer.java @@ -1,5 +1,5 @@ /* SwingButtonPeer.java -- A Swing based peer for AWT buttons - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,7 @@ import java.awt.Image; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.peer.ButtonPeer; @@ -70,12 +71,12 @@ public class SwingButtonPeer extends JButton implements SwingComponent { - Button button; + Button button; - SwingButton(Button button) - { - this.button = button; - } + SwingButton(Button button) + { + this.button = button; + } /** * Overridden so that this method returns the correct value even without a @@ -184,6 +185,26 @@ public class SwingButtonPeer par = button.getParent(); return par; } + + /** + * Handles focus events by forwarding it to + * <code>processFocusEvent()</code>. + * + * @param ev the Focus event + */ + public void handleFocusEvent(FocusEvent ev) + { + processFocusEvent(ev); + } + + public void requestFocus() { + SwingButtonPeer.this.requestFocus(awtComponent, false, true, 0); + } + + public boolean requestFocus(boolean temporary) { + return SwingButtonPeer.this.requestFocus(awtComponent, temporary, + true, 0); + } } /** diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingCheckboxPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingCheckboxPeer.java new file mode 100755 index 00000000000..a8e3cb01bab --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingCheckboxPeer.java @@ -0,0 +1,261 @@ +/* SwingCheckboxPeer.java -- A Swing based peer for AWT checkboxes + Copyright (C) 2007 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.swing; + +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.CheckboxGroup; +import java.awt.Container; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Label; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.peer.CheckboxPeer; + +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JToggleButton; + +/** + * A CheckboxPeer implementation that is backed by the Swing JCheckBox. + */ +public class SwingCheckboxPeer extends SwingComponentPeer implements + CheckboxPeer { + + /** + * A spezialized Swing checkbox used to paint the checkbox for the + * AWT checkbox. + */ + private class SwingCheckbox + extends JCheckBox + implements SwingComponent + { + Checkbox checkbox; + + SwingCheckbox(Checkbox checkbox) + { + this.checkbox = checkbox; + } + + /** + * Returns this checkbox. + * + * @return <code>this</code> + */ + public JComponent getJComponent() + { + return this; + } + + /** + * Handles mouse events by forwarding it to + * <code>processMouseEvent()</code>. + * + * @param ev the mouse event + */ + public void handleMouseEvent(MouseEvent ev) + { + ev.setSource(this); + processMouseEvent(ev); + } + + /** + * Handles mouse motion events by forwarding it to + * <code>processMouseMotionEvent()</code>. + * + * @param ev the mouse motion event + */ + public void handleMouseMotionEvent(MouseEvent ev) + { + ev.setSource(this); + processMouseMotionEvent(ev); + } + + /** + * Handles key events by forwarding it to <code>processKeyEvent()</code>. + * + * @param ev the mouse event + */ + public void handleKeyEvent(KeyEvent ev) + { + ev.setSource(this); + processKeyEvent(ev); + } + + /** + * Handles focus events by forwarding it to + * <code>processFocusEvent()</code>. + * + * @param ev the Focus event + */ + public void handleFocusEvent(FocusEvent ev) + { + processFocusEvent(ev); + } + + /** + * Overridden so that this method returns the correct value even without a + * peer. + * + * @return the screen location of the button + */ + public Point getLocationOnScreen() + { + return SwingCheckboxPeer.this.getLocationOnScreen(); + } + + /** + * Overridden so that the isShowing method returns the correct value + * for the swing button, even if it has no peer on its own. + * + * @return <code>true</code> if the button is currently showing, + * <code>false</code> otherwise + */ + public boolean isShowing() + { + boolean retVal = false; + if (checkbox != null) + retVal = checkbox.isShowing(); + return retVal; + } + + /** + * Overridden, so that the Swing button can create an Image without its + * own peer. + * + * @param w the width of the image + * @param h the height of the image + * + * @return an image + */ + public Image createImage(int w, int h) + { + return SwingCheckboxPeer.this.createImage(w, h); + } + + public Graphics getGraphics() + { + return SwingCheckboxPeer.this.getGraphics(); + } + + public Container getParent() + { + Container par = null; + if (checkbox != null) + par = checkbox.getParent(); + return par; + } + + public void requestFocus() { + SwingCheckboxPeer.this.requestFocus(awtComponent, false, true, 0); + } + + public boolean requestFocus(boolean temporary) { + return SwingCheckboxPeer.this.requestFocus(awtComponent, temporary, + true, 0); + } + } + + /** + * Listens for ActionEvents on the Swing button and triggers corresponding + * ActionEvents on the AWT button. + */ + class SwingCheckboxListener implements ItemListener + { + Checkbox awtCheckbox; + + SwingCheckboxListener(Checkbox checkbox) + { + awtCheckbox = checkbox; + } + + /** + * Receives notification when an action was performend on the button. + * + * @param event the action event + */ + public void itemStateChanged(ItemEvent event) + { + awtCheckbox.setState(event.getStateChange()==ItemEvent.SELECTED); + ItemListener[] l = awtCheckbox.getItemListeners(); + if (l.length == 0) + return; + ItemEvent ev = new ItemEvent(awtCheckbox, ItemEvent.ITEM_STATE_CHANGED, + awtCheckbox, event.getStateChange()); + for (int i = 0; i < l.length; ++i) + l[i].itemStateChanged(ev); + } + } + + /** + * Creates a new SwingCheckboxPeer instance. + */ + public SwingCheckboxPeer(Checkbox checkbox) + { + SwingCheckbox swingCheckbox = new SwingCheckbox(checkbox); + swingCheckbox.addItemListener(new SwingCheckboxListener(checkbox)); + + init(checkbox, swingCheckbox); + setLabel(checkbox.getLabel()); + setState(checkbox.getState()); + } + + public void setCheckboxGroup(CheckboxGroup group) + { + // TODO: Implement this. + } + + public void setLabel(String label) + { + ((JToggleButton) swingComponent).setText(label); + } + + public void setState(boolean state) + { + ((JToggleButton) swingComponent).setSelected(state); + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingComponent.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingComponent.java index 04ca7294f78..d22f55d6f19 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingComponent.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingComponent.java @@ -37,6 +37,7 @@ exception statement from your version. */ package gnu.java.awt.peer.swing; +import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; @@ -86,4 +87,13 @@ public interface SwingComponent * @param ev the key event */ void handleKeyEvent(KeyEvent ev); + + /** + * Handles a focus event. This is usually forwarded to + * {@link Component#processFocusEvent(FocusEvent)} of the swing + * component. + * + * @param ev the focus event + */ + void handleFocusEvent(FocusEvent ev); } diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java index bfa14dddee3..71a7bac4d00 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java @@ -1,5 +1,5 @@ /* SwingComponentPeer.java -- An abstract base class for Swing based peers - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -45,6 +45,7 @@ import java.awt.Component; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; +import java.awt.EventQueue; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; @@ -54,6 +55,7 @@ import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.BufferCapabilities.FlipContents; +import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.PaintEvent; @@ -349,12 +351,7 @@ public class SwingComponentPeer */ public Dimension getMinimumSize() { - Dimension retVal; - if (swingComponent != null) - retVal = swingComponent.getJComponent().getMinimumSize(); - else - retVal = new Dimension(0, 0); - return retVal; + return minimumSize(); } /** @@ -367,12 +364,7 @@ public class SwingComponentPeer */ public Dimension getPreferredSize() { - Dimension retVal; - if (swingComponent != null) - retVal = swingComponent.getJComponent().getPreferredSize(); - else - retVal = new Dimension(0, 0); - return retVal; + return preferredSize(); } /** @@ -395,30 +387,28 @@ public class SwingComponentPeer public void handleEvent(AWTEvent e) { switch (e.getID()) - { + { case PaintEvent.UPDATE: case PaintEvent.PAINT: - // Need to synchronize to avoid threading problems on the - // paint event list. - // We must synchronize on the tree lock first to avoid deadlock, - // because Container.paint() will grab it anyway. - synchronized (this) + if (awtComponent.isShowing()) { - assert paintArea != null; - if (awtComponent.isShowing()) + Rectangle clip ; + synchronized (this) { - Graphics g = awtComponent.getGraphics(); - try - { - Rectangle clip = paintArea; - g.clipRect(clip.x, clip.y, clip.width, clip.height); - peerPaint(g, e.getID() == PaintEvent.UPDATE); - } - finally - { - g.dispose(); - paintArea = null; - } + coalescePaintEvent((PaintEvent) e); + assert paintArea != null; + clip = paintArea; + paintArea = null; + } + Graphics g = awtComponent.getGraphics(); + try + { + g.clipRect(clip.x, clip.y, clip.width, clip.height); + peerPaint(g, e.getID() == PaintEvent.UPDATE); + } + finally + { + g.dispose(); } } break; @@ -438,10 +428,14 @@ public class SwingComponentPeer case KeyEvent.KEY_TYPED: handleKeyEvent((KeyEvent) e); break; + case FocusEvent.FOCUS_GAINED: + case FocusEvent.FOCUS_LOST: + handleFocusEvent((FocusEvent)e); + break; default: // Other event types are not handled here. break; - } + } } /** @@ -574,13 +568,16 @@ public class SwingComponentPeer * This is implemented to call repaint() on the Swing component. * * @param tm number of milliseconds to wait with repainting - * @param x the X coordinate of the upper left corner of the damaged rectangle - * @param y the Y coordinate of the upper left corner of the damaged rectangle + * @param x the X coordinate of the upper left corner of the damaged + * rectangle + * @param y the Y coordinate of the upper left corner of the damaged + * rectangle * @param width the width of the damaged rectangle * @param height the height of the damaged rectangle */ public void repaint(long tm, int x, int y, int width, int height) { + // NOTE: This is never called by AWT but is mandated by the peer interface. if (swingComponent != null) swingComponent.getJComponent().repaint(tm, x, y, width, height); else @@ -602,8 +599,10 @@ public class SwingComponentPeer */ public void requestFocus() { - if (swingComponent != null) - swingComponent.getJComponent().requestFocus(); + // NOTE: This is never called by AWT but is mandated by the peer interface. + Toolkit tk = Toolkit.getDefaultToolkit(); + EventQueue q = tk.getSystemEventQueue(); + q.postEvent(new FocusEvent(awtComponent, FocusEvent.FOCUS_GAINED, false)); } /** @@ -612,18 +611,22 @@ public class SwingComponentPeer * * This calls requestFocus() on the Swing component. * - * @param source TODO - * @param bool1 TODO - * @param bool2 TODO - * @param x TODO + * @param source the actual component that requests focus (may be a + * lightweight descendant of the heavyweight container) + * @param tmp true when the change is temporary + * @param allowWindowFocus + * @param tm the timestamp of the focus change * - * @return TODO + * @return true when the focus change is guaranteed to be granted, false + * otherwise */ - public boolean requestFocus(Component source, boolean bool1, boolean bool2, long x) + public boolean requestFocus(Component source, boolean tmp, + boolean allowWindowFocus, long tm) { - if (swingComponent != null) - swingComponent.getJComponent().requestFocus(); - return swingComponent != null; + Toolkit tk = Toolkit.getDefaultToolkit(); + EventQueue q = tk.getSystemEventQueue(); + q.postEvent(new FocusEvent(source, FocusEvent.FOCUS_GAINED, tmp)); + return true; } /** @@ -1101,6 +1104,19 @@ public class SwingComponentPeer } /** + * Handles focus events on the component. This is usually forwarded to the + * SwingComponent's processFocusEvent() method. + * + * @param e the key event + */ + protected void handleFocusEvent(FocusEvent e) + { + if (swingComponent != null) + swingComponent.handleFocusEvent(e); + } + + + /** * Returns the AWT component for this peer. * * @return the AWT component for this peer @@ -1109,4 +1125,12 @@ public class SwingComponentPeer { return awtComponent; } + + public boolean requestFocus(Component lightweightChild, boolean temporary, + boolean focusedWindowChangeAllowed, + long time, sun.awt.CausedFocusEvent.Cause cause) + { + return true; + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingContainerPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingContainerPeer.java index c78b644a765..2d5d97ff14b 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingContainerPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingContainerPeer.java @@ -1,5 +1,5 @@ /* SwingContainerPeer.java -- A Swing based peer for AWT containers - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -92,7 +92,7 @@ public class SwingContainerPeer * @see #peerPaintChildren(Graphics) * @see #removeHeavyweightDescendent(Component) */ - synchronized void addHeavyweightDescendent(Component comp) + protected synchronized void addHeavyweightDescendent(Component comp) { heavyweightDescendents.add(comp); focusOwner = null; @@ -106,13 +106,25 @@ public class SwingContainerPeer * @see #peerPaintChildren(Graphics) * @see #addHeavyweightDescendent(Component) */ - synchronized void removeHeavyweightDescendent(Component comp) + protected synchronized void removeHeavyweightDescendent(Component comp) { heavyweightDescendents.remove(comp); focusOwner = null; } /** + * Returns an array of all registered heavyweight descendents. + * + * @return all registered heavyweight descendents + */ + protected Component[] getHeavyweightDescendents() + { + Component[] heavyweights = new Component[heavyweightDescendents.size()]; + heavyweights = (Component[]) heavyweightDescendents.toArray(heavyweights); + return heavyweights; + } + + /** * Returns the insets of the container. * * This is implemented to return the insets of the Swing container. @@ -339,7 +351,7 @@ public class SwingContainerPeer { Component owner = getFocusOwner(); if(owner != null) - owner.dispatchEvent(e); + owner.getPeer().handleEvent(e); else super.handleKeyEvent(e); } diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingLabelPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingLabelPeer.java index 349c5a0abe2..55c394ecb6e 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingLabelPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingLabelPeer.java @@ -1,5 +1,5 @@ /* SwingLabelPeer.java -- A Swing based peer for AWT labels - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,6 +42,7 @@ import java.awt.Graphics; import java.awt.Image; import java.awt.Label; import java.awt.Point; +import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.peer.LabelPeer; @@ -120,6 +121,17 @@ public class SwingLabelPeer } /** + * Handles focus events by forwarding it to + * <code>processFocusEvent()</code>. + * + * @param ev the Focus event + */ + public void handleFocusEvent(FocusEvent ev) + { + processFocusEvent(ev); + } + + /** * Overridden so that this method returns the correct value even without a * peer. * diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingListPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingListPeer.java index aca2070486d..22a6052bb7e 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingListPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingListPeer.java @@ -1,5 +1,5 @@ /* SwingListPeer.java -- A Swing based peer for AWT lists - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -46,6 +46,7 @@ import java.awt.Image; import java.awt.List; import java.awt.Point; import java.awt.Rectangle; +import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.peer.ListPeer; @@ -129,6 +130,17 @@ public class SwingListPeer } /** + * Handles focus events by forwarding it to <code>processFocusEvent()</code>. + * + * @param ev the Focus event + */ + public void handleFocusEvent(FocusEvent ev) + { + processFocusEvent(ev); + } + + + /** * Overridden so that this method returns the correct value even without a * peer. * diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingPanelPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingPanelPeer.java index 3cea62ac4d1..37c6dbc7a5b 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingPanelPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingPanelPeer.java @@ -1,5 +1,5 @@ /* SwingPanelPeer.java -- A PanelPeer based on Swing - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -47,7 +47,7 @@ import java.awt.peer.PanelPeer; * @author Roman Kennke (kennke@aicas.com) */ // TODO: Maybe base implementation on JPanel. However, this doesn't seem -// necessary, but might be good for more consistend Look. +// necessary, but might be good for more consistent Look. public class SwingPanelPeer extends SwingContainerPeer implements PanelPeer diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingTextAreaPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingTextAreaPeer.java index 04ac011419f..2c438a1ccb1 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingTextAreaPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingTextAreaPeer.java @@ -1,5 +1,5 @@ /* SwingTextAreaPeer.java -- A Swing based peer for AWT textareas - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -45,14 +45,20 @@ import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; import java.awt.TextArea; +import java.awt.event.ComponentEvent; +import java.awt.event.FocusEvent; +import java.awt.event.HierarchyEvent; +import java.awt.event.InputMethodEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; import java.awt.im.InputMethodRequests; import java.awt.peer.TextAreaPeer; import javax.swing.JComponent; import javax.swing.JScrollPane; import javax.swing.JTextArea; +import javax.swing.JViewport; import javax.swing.text.BadLocationException; public class SwingTextAreaPeer @@ -65,15 +71,19 @@ public class SwingTextAreaPeer * * @author Roman Kennke (kennke@aicas.com) */ - private class SwingTextArea + private class SwingScrollPane extends JScrollPane implements SwingComponent { - SwingTextArea(Component comp) + SwingTextArea textArea; + + SwingScrollPane(SwingTextArea textArea) { - super(comp, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, + super(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); + + this.textArea = textArea; } /** @@ -94,8 +104,17 @@ public class SwingTextAreaPeer */ public void handleMouseEvent(MouseEvent ev) { - ev.setSource(this); - dispatchEvent(ev); + JViewport viewPort = getViewport(); + if(viewPort.contains(ev.getPoint())) + { + ev.setSource(textArea); + textArea.dispatchEvent(ev); + } + else + { + ev.setSource(this); + this.dispatchEvent(ev); + } } /** @@ -114,7 +133,7 @@ public class SwingTextAreaPeer */ public void handleMouseMotionEvent(MouseEvent ev) { - processMouseMotionEvent(ev); + textArea.processMouseMotionEvent(ev); } /** @@ -124,7 +143,18 @@ public class SwingTextAreaPeer */ public void handleKeyEvent(KeyEvent ev) { - processKeyEvent(ev); + textArea.processKeyEvent(ev); + } + + /** + * Handles focus events by forwarding it to + * <code>processFocusEvent()</code>. + * + * @param ev the Focus event + */ + public void handleFocusEvent(FocusEvent ev) + { + textArea.processFocusEvent(ev); } /** @@ -179,35 +209,160 @@ public class SwingTextAreaPeer par = SwingTextAreaPeer.this.awtComponent.getParent(); return par; } + + public void requestFocus() { + SwingTextAreaPeer.this.requestFocus(awtComponent, false, true, 0); + } + + public boolean requestFocus(boolean temporary) { + return SwingTextAreaPeer.this.requestFocus(awtComponent, temporary, + true, 0); + } + } + private class SwingTextArea extends JTextArea + { + /** + * Make this method accessible in this Package. + */ + protected final void processComponentKeyEvent(KeyEvent e) + { + super.processComponentKeyEvent(e); + } + + /** + * Make this method accessible in this Package. + */ + protected final void processMouseMotionEvent(MouseEvent ev) + { + super.processMouseMotionEvent(ev); + } + + /** + * Make this method accessible in this Package. + */ + protected final void processComponentEvent(ComponentEvent e) + { + super.processComponentEvent(e); + } + + /** + * Make this method accessible in this Package. + */ + protected final void processFocusEvent(FocusEvent e) + { + super.processFocusEvent(e); + } + + /** + * Make this method accessible in this Package. + */ + protected final void processHierarchyBoundsEvent(HierarchyEvent e) + { + super.processHierarchyBoundsEvent(e); + } + + /** + * Make this method accessible in this Package. + */ + protected final void processHierarchyEvent(HierarchyEvent e) + { + super.processHierarchyEvent(e); + } + + /** + * Make this method accessible in this Package. + */ + protected final void processInputMethodEvent(InputMethodEvent e) + { + super.processInputMethodEvent(e); + } + + /** + * Make this method accessible in this Package. + */ + protected final void processMouseEvent(MouseEvent e) + { + super.processMouseEvent(e); + } + + /** + * Make this method accessible in this Package. + */ + protected final void processMouseWheelEvent(MouseWheelEvent e) + { + super.processMouseWheelEvent(e); + } + + /** + * Make this method accessible in this Package. + */ + protected final void processKeyEvent(KeyEvent e) + { + super.processKeyEvent(e); + } + + public void requestFocus() { + SwingTextAreaPeer.this.requestFocus(awtComponent, false, true, 0); + } + + public boolean requestFocus(boolean temporary) { + return SwingTextAreaPeer.this.requestFocus(awtComponent, temporary, + true, 0); + } + } + /** * The actual JTextArea. */ - private JTextArea jTextArea; + private SwingTextArea jTextArea; public SwingTextAreaPeer(TextArea textArea) { super(); - System.err.println("new SwingTextAreaPeer"); - jTextArea = new JTextArea(); - SwingTextArea swingArea = new SwingTextArea(jTextArea); + jTextArea = new SwingTextArea(); + SwingScrollPane swingArea = new SwingScrollPane(jTextArea); init(textArea, swingArea); + JViewport viewport = new JViewport() + { + public Image createImage(int width, int height) + { + return awtComponent.createImage(width, height); + } + }; + + viewport.setView(jTextArea); + swingArea.setViewport(viewport); // Pull over the text from the text area. setText(textArea.getText()); + + // Pull over the number of rows and columns + // if non were set use default values + int columns = textArea.getColumns(); + int rows = textArea.getRows(); + + if(columns == 0 && rows == 0) + { + columns = 25; + textArea.setColumns(columns); + rows = 5; + textArea.setRows(rows); + } + + jTextArea.setColumns(columns); + jTextArea.setRows(rows); } public Dimension getMinimumSize(int rows, int cols) { - // TODO Auto-generated method stub - return null; + return jTextArea.getMinimumSize(); } public Dimension getPreferredSize(int rows, int cols) { - // TODO Auto-generated method stub - return null; + return jTextArea.getPreferredSize(); } public void insert(String text, int pos) @@ -220,16 +375,24 @@ public class SwingTextAreaPeer jTextArea.insert(text, pos); } + public Dimension minimumSize() + { + return jTextArea.getMinimumSize(); + } + + public Dimension preferredSize() + { + return jTextArea.getPreferredSize(); + } + public Dimension minimumSize(int rows, int cols) { - // TODO Auto-generated method stub - return null; + return jTextArea.getMinimumSize(); } public Dimension preferredSize(int rows, int cols) { - // TODO Auto-generated method stub - return null; + return jTextArea.getPreferredSize(); } public void replaceRange(String text, int start, int end) @@ -310,8 +473,16 @@ public class SwingTextAreaPeer public void setText(String text) { - System.err.println("setText: " + text); jTextArea.setText(text); } + public void reshape(int x, int y, int width, int height) + { + if (swingComponent != null) + { + swingComponent.getJComponent().setBounds(x, y, width, height); + swingComponent.getJComponent().validate(); + } + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingTextFieldPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingTextFieldPeer.java index d7d574a0bb9..29a689da42a 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingTextFieldPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingTextFieldPeer.java @@ -1,5 +1,5 @@ /* SwingTextFieldPeer.java -- A Swing based peer for AWT textfields - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,7 @@ import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; import java.awt.TextField; +import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.im.InputMethodRequests; @@ -72,13 +73,13 @@ public class SwingTextFieldPeer implements SwingComponent { - TextField textField; - - SwingTextField(TextField textField) - { - this.textField = textField; - } - + TextField textField; + + SwingTextField(TextField textField) + { + this.textField = textField; + } + /** * Overridden to provide normal behaviour even without a real peer * attached. @@ -91,8 +92,8 @@ public class SwingTextFieldPeer } /** - * Overridden so that the isShowing method returns the correct value for the - * swing button, even if it has no peer on its own. + * Overridden so that the isShowing method returns the correct value + * for the swing button, even if it has no peer on its own. * * @return <code>true</code> if the button is currently showing, * <code>false</code> otherwise @@ -162,6 +163,18 @@ public class SwingTextFieldPeer processKeyEvent(ev); } + /** + * Handles focus events by forwarding it to + * <code>processFocusEvent()</code>. + * + * @param ev the Focus event + */ + public void handleFocusEvent(FocusEvent ev) + { + processFocusEvent(ev); + } + + public Container getParent() { Container par = null; @@ -174,6 +187,16 @@ public class SwingTextFieldPeer { return SwingTextFieldPeer.this.getGraphics(); } + + public void requestFocus() { + SwingTextFieldPeer.this.requestFocus(awtComponent, false, true, 0); + } + + public boolean requestFocus(boolean temporary) { + return SwingTextFieldPeer.this.requestFocus(awtComponent, temporary, + true, 0); + } + } /** diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingToolkit.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingToolkit.java index 166e1f47b6f..63414050bfe 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingToolkit.java @@ -40,6 +40,7 @@ package gnu.java.awt.peer.swing; import java.awt.Button; import java.awt.Canvas; +import java.awt.Dialog; import java.awt.Label; import java.awt.Menu; import java.awt.MenuBar; @@ -162,4 +163,19 @@ public abstract class SwingToolkit extends ClasspathToolkit { return new SwingTextFieldPeer(textField); } + + @Override + public boolean isModalExclusionTypeSupported + (Dialog.ModalExclusionType modalExclusionType) + { + return false; + } + + @Override + public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) + { + return false; + } + + } diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingWindowPeer.java index 531552d902c..bdc494e958c 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingWindowPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingWindowPeer.java @@ -71,4 +71,29 @@ public abstract class SwingWindowPeer super(window); init(window, null); } + + public void updateIconImages() + { + // TODO: Implement properly. + } + + public void updateMinimumSize() + { + // TODO: Implement properly. + } + + public void setModalBlocked(java.awt.Dialog d, boolean b) + { + // TODO: Implement properly. + } + + public void updateFocusableWindowState() + { + // TODO: Implement properly. + } + + public void setAlwaysOnTop(boolean b) + { + // TODO: Implement properly. + } } diff --git a/libjava/classpath/gnu/java/awt/peer/x/KeyboardMapping.java b/libjava/classpath/gnu/java/awt/peer/x/KeyboardMapping.java index 8e0a31f5d36..8cda31d81dd 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/KeyboardMapping.java +++ b/libjava/classpath/gnu/java/awt/peer/x/KeyboardMapping.java @@ -405,8 +405,12 @@ final class KeyboardMapping if ((xMods & Input.SHIFT_MASK) != 0) mods |= KeyEvent.SHIFT_MASK | KeyEvent.SHIFT_DOWN_MASK; + if ((xMods & Input.META_MASK) != 0) + mods |= KeyEvent.META_MASK | KeyEvent.META_DOWN_MASK; if ((xMods & Input.ALT_MASK) != 0) mods |= KeyEvent.ALT_MASK | KeyEvent.ALT_DOWN_MASK; + if ((xMods & Input.MOD5_MASK) != 0) + mods |= KeyEvent.ALT_GRAPH_MASK | KeyEvent.ALT_GRAPH_DOWN_MASK; if ((xMods & Input.CONTROL_MASK) != 0) mods |= KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK; diff --git a/libjava/classpath/gnu/java/awt/peer/x/PixmapVolatileImage.java b/libjava/classpath/gnu/java/awt/peer/x/PixmapVolatileImage.java new file mode 100644 index 00000000000..131647fab29 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/PixmapVolatileImage.java @@ -0,0 +1,185 @@ +/* PixmapVolatileImage.java -- VolatileImage implementation around a Pixmap + Copyright (C) 2007 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.x; + +import gnu.x11.GC; +import gnu.x11.Pixmap; +import gnu.x11.image.Image; +import gnu.x11.image.ZPixmap; + +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.ImageCapabilities; +import java.awt.Point; +import java.awt.Transparency; +import java.awt.color.ColorSpace; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.ComponentSampleModel; +import java.awt.image.DataBuffer; +import java.awt.image.ImageObserver; +import java.awt.image.Raster; +import java.awt.image.SampleModel; +import java.awt.image.VolatileImage; +import java.awt.image.WritableRaster; + +/** + * A {@link VolatileImage} implementation that wraps an X Pixmap. + */ +class PixmapVolatileImage + extends VolatileImage +{ + + /** + * The shared capabilities instance. + */ + private static final ImageCapabilities caps = new ImageCapabilities(true); + + /** + * The underlying pixmap. + */ + private Pixmap pixmap; + + /** + * Creates a new PixmapVolatileImage. + * + * @param w the width of the image + * @param h the height of the image + */ + public PixmapVolatileImage(int w, int h) + { + GraphicsEnvironment env = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + XGraphicsDevice dev = (XGraphicsDevice) env.getDefaultScreenDevice(); + pixmap = new Pixmap(dev.getDisplay(), w, h); + + // Clear pixmap. + GC gc = new GC(pixmap); + gc.set_foreground(0xffffffff); + pixmap.fill_rectangle(gc, 0, 0, w, h); + + } + + @Override + public boolean contentsLost() + { + return false; + } + + @Override + public Graphics2D createGraphics() + { + return new XGraphics2D(pixmap); + } + + @Override + public ImageCapabilities getCapabilities() + { + return caps; + } + + @Override + public int getHeight() + { + return pixmap.height; + } + + @Override + public BufferedImage getSnapshot() + { + // TODO: Support non-24-bit resolutions. + int w = pixmap.width; + int h = pixmap.height; + ZPixmap zpixmap = (ZPixmap) pixmap.image(0, 0, w, h, 0xffffffff, + Image.Format.ZPIXMAP); + DataBuffer buffer = new ZPixmapDataBuffer(zpixmap); + SampleModel sm = new ComponentSampleModel(DataBuffer.TYPE_BYTE, w, h, 4, + w * 4, + new int[]{0, 1, 2, 3 }); + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); + ColorModel cm = new ComponentColorModel(cs, true, false, + Transparency.OPAQUE, + DataBuffer.TYPE_BYTE); + WritableRaster raster = Raster.createWritableRaster(sm, buffer, + new Point(0, 0)); + return new BufferedImage(cm, raster, false, null); + } + + @Override + public int getWidth() + { + return pixmap.width; + } + + @Override + public int validate(GraphicsConfiguration gc) + { + // TODO: Check compatibility with gc. + return IMAGE_OK; + } + + @Override + public int getHeight(ImageObserver observer) + { + return getHeight(); + } + + @Override + public Object getProperty(String name, ImageObserver observer) + { + return null; + } + + @Override + public int getWidth(ImageObserver observer) + { + return getWidth(); + } + + /** + * Returns the underlying X pixmap. This is used for the graphics code. + * + * @return the underlying X pixmap + */ + Pixmap getPixmap() + { + return pixmap; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XEventPump.java b/libjava/classpath/gnu/java/awt/peer/x/XEventPump.java index 870edf3796d..d376619c595 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XEventPump.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XEventPump.java @@ -97,8 +97,9 @@ public class XEventPump display = d; windows = new HashMap(); drag = -1; - Thread t = new Thread(this); - t.start(); + Thread thread = new Thread(this, "X Event Pump"); + thread.setDaemon(true); + thread.start(); } /** @@ -148,8 +149,9 @@ public class XEventPump private void handleEvent(Event xEvent) { - Integer key = new Integer(xEvent.window_id());; - Window awtWindow = (Window) windows.get(key); + + Integer key = null; + Window awtWindow = null; if (XToolkit.DEBUG) System.err.println("fetched event: " + xEvent); @@ -157,26 +159,45 @@ public class XEventPump { case ButtonPress.CODE: ButtonPress bp = (ButtonPress) xEvent; + key= new Integer(bp.event_window_id); + awtWindow = (Window) windows.get(key); // Create and post the mouse event. int button = bp.detail(); + + // AWT cannot handle more than 3 buttons and expects 0 instead. + if (button >= gnu.x11.Input.BUTTON3) + button = 0; drag = button; + MouseEvent mp = new MouseEvent(awtWindow, MouseEvent.MOUSE_PRESSED, - System.currentTimeMillis(), 0, + System.currentTimeMillis(), + KeyboardMapping.mapModifiers(bp.state()) | buttonToModifier(button), bp.event_x(), bp.event_y(), 1, false, button); Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mp); break; case ButtonRelease.CODE: ButtonRelease br = (ButtonRelease) xEvent; + key= new Integer(br.event_window_id); + awtWindow = (Window) windows.get(key); + + button = br.detail(); + // AWT cannot handle more than 3 buttons and expects 0 instead. + if (button >= gnu.x11.Input.BUTTON3) + button = 0; drag = -1; MouseEvent mr = new MouseEvent(awtWindow, MouseEvent.MOUSE_RELEASED, - System.currentTimeMillis(), 0, + System.currentTimeMillis(), + KeyboardMapping.mapModifiers(br.state()) | buttonToModifier(button), br.event_x(), br.event_y(), - 1, false, br.detail()); + 1, false, button); Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mr); break; case MotionNotify.CODE: MotionNotify mn = (MotionNotify) xEvent; + key= new Integer(mn.event_window_id); + awtWindow = (Window) windows.get(key); + MouseEvent mm; if (drag == -1) { @@ -195,6 +216,8 @@ public class XEventPump Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mm); break; case ConfigureNotify.CODE: + key= new Integer(((ConfigureNotify) xEvent).event_window_id); + awtWindow = (Window) windows.get(key); ConfigureNotify c = (ConfigureNotify) xEvent; if (XToolkit.DEBUG) System.err.println("resize request for window id: " + key); @@ -213,6 +236,8 @@ public class XEventPump } break; case Expose.CODE: + key= new Integer(((Expose) xEvent).window_id); + awtWindow = (Window) windows.get(key); Expose exp = (Expose) xEvent; if (XToolkit.DEBUG) System.err.println("expose request for window id: " + key); @@ -228,6 +253,8 @@ public class XEventPump break; case KeyPress.CODE: case KeyRelease.CODE: + key = new Integer(((Input) xEvent).event_window_id); + awtWindow = (Window) windows.get(key); handleKeyEvent(xEvent, awtWindow); break; default: @@ -282,6 +309,23 @@ public class XEventPump } + /** Translates an X button identifier to the AWT's MouseEvent modifier + * mask. As the AWT cannot handle more than 3 buttons those return + * <code>0</code>. + */ + static int buttonToModifier(int button) + { + switch (button) + { + case gnu.x11.Input.BUTTON1: + return MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON1_MASK; + case gnu.x11.Input.BUTTON2: + return MouseEvent.BUTTON2_DOWN_MASK | MouseEvent.BUTTON2_MASK; + case gnu.x11.Input.BUTTON3: + return MouseEvent.BUTTON3_DOWN_MASK | MouseEvent.BUTTON3_MASK; + } -} + return 0; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java b/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java deleted file mode 100644 index 8183fed0cd2..00000000000 --- a/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java +++ /dev/null @@ -1,759 +0,0 @@ -/* XFontPeer.java -- The font peer for X - 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.x; - -import java.awt.AWTError; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.font.LineMetrics; -import java.awt.font.TextAttribute; -import java.awt.geom.Rectangle2D; -import java.io.IOException; -import java.io.InputStream; -import java.text.CharacterIterator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; - -import gnu.java.awt.peer.ClasspathFontPeer; -import gnu.x11.Display; -import gnu.x11.Fontable; - -/** - * The bridge from AWT to X fonts. - * - * @author Roman Kennke (kennke@aicas.com) - */ -public class XFontPeer - extends ClasspathFontPeer -{ - - /** - * The font mapping as specified in the file fonts.properties. - */ - private static Properties fontProperties; - static - { - fontProperties = new Properties(); - InputStream in = XFontPeer.class.getResourceAsStream("fonts.properties"); - try - { - fontProperties.load(in); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - - /** - * The FontMetrics implementation for XFontPeer. - */ - private class XFontMetrics - extends FontMetrics - { - /** - * The ascent of the font. - */ - int ascent; - - /** - * The descent of the font. - */ - int descent; - - /** - * The maximum of the character advances. - */ - private int maxAdvance; - - /** - * The internal leading. - */ - int leading; - - /** - * Cached string metrics. This caches string metrics locally so that the - * server doesn't have to be asked each time. - */ - private HashMap metricsCache; - - /** - * The widths of the characters indexed by the characters themselves. - */ - private int[] charWidths; - - /** - * Creates a new XFontMetrics for the specified font. - * - * @param font the font - */ - protected XFontMetrics(Font font) - { - super(font); - metricsCache = new HashMap(); - Fontable.FontReply info = getXFont().info(); - ascent = info.font_ascent(); - descent = info.font_descent(); - maxAdvance = info.max_bounds().character_width(); - leading = 0; // TODO: Not provided by X. Possible not needed. - - if (info.min_byte1() == 0 && info.max_byte1() == 0) - readCharWidthsLinear(info); - else - readCharWidthsNonLinear(info); - } - - /** - * Reads the character widths when specified in a linear fashion. That is - * when the min-byte1 and max-byte2 fields are both zero in the X protocol. - * - * @param info the font info reply - */ - private void readCharWidthsLinear(Fontable.FontReply info) - { - int startIndex = info.min_char_or_byte2(); - int endIndex = info.max_char_or_byte2(); - charWidths = new int[endIndex + 1]; - // All the characters before startIndex are zero width. - for (int i = 0; i < startIndex; i++) - { - charWidths[i] = 0; - } - // All the other character info is fetched from the font info. - int index = startIndex; - Iterator charInfos = info.char_infos().iterator(); - while (charInfos.hasNext()) - { - Fontable.FontReply.CharInfo charInfo = - (Fontable.FontReply.CharInfo) charInfos.next(); - charWidths[index] = charInfo.character_width(); - index++; - } - } - - private void readCharWidthsNonLinear(Fontable.FontReply info) - { - // TODO: Implement. - throw new UnsupportedOperationException("Not yet implemented"); - } - - /** - * Returns the ascent of the font. - * - * @return the ascent of the font - */ - public int getAscent() - { - return ascent; - } - - /** - * Returns the descent of the font. - * - * @return the descent of the font - */ - public int getDescent() - { - return descent; - } - - /** - * Returns the overall height of the font. This is the distance from - * baseline to baseline (usually ascent + descent + leading). - * - * @return the overall height of the font - */ - public int getHeight() - { - return ascent + descent; - } - - /** - * Returns the leading of the font. - * - * @return the leading of the font - */ - public int getLeading() - { - return leading; - } - - /** - * Returns the maximum advance for this font. - * - * @return the maximum advance for this font - */ - public int getMaxAdvance() - { - return maxAdvance; - } - - /** - * Determines the width of the specified character <code>c</code>. - * - * @param c the character - * - * @return the width of the character - */ - public int charWidth(char c) - { - int width; - if (c > charWidths.length) - width = charWidths['?']; - else - width = charWidths[c]; - return width; - } - - /** - * Determines the overall width of the specified string. - * - * @param c the char buffer holding the string - * @param offset the starting offset of the string in the buffer - * @param length the number of characters in the string buffer - * - * @return the overall width of the specified string - */ - public int charsWidth(char[] c, int offset, int length) - { - int width = 0; - if (c.length > 0 && length > 0) - { - String s = new String(c, offset, length); - width = stringWidth(s); - } - return width; - } - - /** - * Determines the overall width of the specified string. - * - * @param s the string - * - * @return the overall width of the specified string - */ - public int stringWidth(String s) - { - int width = 0; - if (s.length() > 0) - { - if (metricsCache.containsKey(s)) - { - width = ((Integer) metricsCache.get(s)).intValue(); - } - else - { - Fontable.TextExtentReply extents = getXFont().text_extent(s); - /* - System.err.println("string: '" + s + "' : "); - System.err.println("ascent: " + extents.getAscent()); - System.err.println("descent: " + extents.getDescent()); - System.err.println("overall ascent: " + extents.getOverallAscent()); - System.err.println("overall descent: " + extents.getOverallDescent()); - System.err.println("overall width: " + extents.getOverallWidth()); - System.err.println("overall left: " + extents.getOverallLeft()); - System.err.println("overall right: " + extents.getOverallRight()); - */ - width = extents.overall_width(); // + extents.overall_left(); - //System.err.println("String: " + s + ", width: " + width); - metricsCache.put(s, new Integer(width)); - } - } - //System.err.print("stringWidth: '" + s + "': "); - //System.err.println(width); - return width; - } - } - - /** - * The LineMetrics implementation for the XFontPeer. - */ - private class XLineMetrics - extends LineMetrics - { - - /** - * Returns the ascent of the font. - * - * @return the ascent of the font - */ - public float getAscent() - { - return fontMetrics.ascent; - } - - public int getBaselineIndex() - { - // FIXME: Implement this. - throw new UnsupportedOperationException(); - } - - public float[] getBaselineOffsets() - { - // FIXME: Implement this. - throw new UnsupportedOperationException(); - } - - /** - * Returns the descent of the font. - * - * @return the descent of the font - */ - public float getDescent() - { - return fontMetrics.descent; - } - - /** - * Returns the overall height of the font. This is the distance from - * baseline to baseline (usually ascent + descent + leading). - * - * @return the overall height of the font - */ - public float getHeight() - { - return fontMetrics.ascent + fontMetrics.descent; - } - - /** - * Returns the leading of the font. - * - * @return the leading of the font - */ - public float getLeading() - { - return fontMetrics.leading; - } - - public int getNumChars() - { - // FIXME: Implement this. - throw new UnsupportedOperationException(); - } - - public float getStrikethroughOffset() - { - return 0.F; // TODO: Provided by X?? - } - - public float getStrikethroughThickness() - { - return 1.F; // TODO: Provided by X?? - } - - public float getUnderlineOffset() - { - return 0.F; // TODO: Provided by X?? - } - - public float getUnderlineThickness() - { - return 1.F; // TODO: Provided by X?? - } - - } - - /** - * The X font. - */ - private gnu.x11.Font xfont; - - private String name; - - private int style; - - private int size; - - /** - * The font metrics for this font. - */ - XFontMetrics fontMetrics; - - /** - * Creates a new XFontPeer for the specified font name, style and size. - * - * @param name the font name - * @param style the font style (bold / italic / normal) - * @param size the size of the font - */ - public XFontPeer(String name, int style, int size) - { - super(name, style, size); - this.name = name; - this.style = style; - this.size = size; - } - - /** - * Creates a new XFontPeer for the specified font name and style - * attributes. - * - * @param name the font name - * @param atts the font attributes - */ - public XFontPeer(String name, Map atts) - { - super(name, atts); - String family = name; - if (family == null || family.equals("")) - family = (String) atts.get(TextAttribute.FAMILY); - if (family == null) - family = "SansSerif"; - - int size = 12; - Float sizeFl = (Float) atts.get(TextAttribute.SIZE); - if (sizeFl != null) - size = sizeFl.intValue(); - - int style = 0; - // Detect italic attribute. - Float posture = (Float) atts.get(TextAttribute.POSTURE); - if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR)) - style |= Font.ITALIC; - - // Detect bold attribute. - Float weight = (Float) atts.get(TextAttribute.WEIGHT); - if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0) - style |= Font.BOLD; - - this.name = name; - this.style = style; - this.size = size; - } - - /** - * Initializes the font peer with the specified attributes. This method is - * called from both constructors. - * - * @param name the font name - * @param style the font style - * @param size the font size - */ - private void init(String name, int style, int size) - { - GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); - GraphicsDevice dev = env.getDefaultScreenDevice(); - if (dev instanceof XGraphicsDevice) - { - Display display = ((XGraphicsDevice) dev).getDisplay(); - String fontDescr = encodeFont(name, style, size); - if (XToolkit.DEBUG) - System.err.println("XLFD font description: " + fontDescr); - xfont = new gnu.x11.Font(display, fontDescr); - } - else - { - throw new AWTError("Local GraphicsEnvironment is not XWindowGraphicsEnvironment"); - } - } - - public boolean canDisplay(Font font, char c) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - public String getSubFamilyName(Font font, Locale locale) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - public String getPostScriptName(Font font) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - public int getNumGlyphs(Font font) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - public int getMissingGlyphCode(Font font) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - public byte getBaselineFor(Font font, char c) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - public String getGlyphName(Font font, int glyphIndex) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - public GlyphVector createGlyphVector(Font font, FontRenderContext frc, - CharacterIterator ci) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - public GlyphVector createGlyphVector(Font font, FontRenderContext ctx, - int[] glyphCodes) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc, - char[] chars, int start, int limit, - int flags) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - /** - * Returns the font metrics for the specified font. - * - * @param font the font for which to fetch the font metrics - * - * @return the font metrics for the specified font - */ - public FontMetrics getFontMetrics(Font font) - { - if (font.getPeer() != this) - throw new AWTError("The specified font has a different peer than this"); - - if (fontMetrics == null) - fontMetrics = new XFontMetrics(font); - return fontMetrics; - } - - /** - * Frees the font in the X server. - */ - protected void finalize() - { - if (xfont != null) - xfont.close(); - } - - public boolean hasUniformLineMetrics(Font font) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - /** - * Returns the line metrics for this font and the specified string and - * font render context. - */ - public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin, - int limit, FontRenderContext rc) - { - return new XLineMetrics(); - } - - public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc) - { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); - } - - /** - * Encodes a font name + style + size specification into a X logical font - * description (XLFD) as described here: - * - * http://www.meretrx.com/e93/docs/xlfd.html - * - * This is implemented to look up the font description in the - * fonts.properties of this package. - * - * @param name the font name - * @param atts the text attributes - * - * @return the encoded font description - */ - static String encodeFont(String name, Map atts) - { - String family = name; - if (family == null || family.equals("")) - family = (String) atts.get(TextAttribute.FAMILY); - if (family == null) - family = "SansSerif"; - - int size = 12; - Float sizeFl = (Float) atts.get(TextAttribute.SIZE); - if (sizeFl != null) - size = sizeFl.intValue(); - - int style = 0; - // Detect italic attribute. - Float posture = (Float) atts.get(TextAttribute.POSTURE); - if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR)) - style |= Font.ITALIC; - - // Detect bold attribute. - Float weight = (Float) atts.get(TextAttribute.WEIGHT); - if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0) - style |= Font.BOLD; - - return encodeFont(name, style, size); - } - - /** - * Encodes a font name + style + size specification into a X logical font - * description (XLFD) as described here: - * - * http://www.meretrx.com/e93/docs/xlfd.html - * - * This is implemented to look up the font description in the - * fonts.properties of this package. - * - * @param name the font name - * @param style the font style - * @param size the font size - * - * @return the encoded font description - */ - static String encodeFont(String name, int style, int size) - { - StringBuilder key = new StringBuilder(); - key.append(validName(name)); - key.append('.'); - switch (style) - { - case Font.BOLD: - key.append("bold"); - break; - case Font.ITALIC: - key.append("italic"); - break; - case (Font.BOLD | Font.ITALIC): - key.append("bolditalic"); - break; - case Font.PLAIN: - default: - key.append("plain"); - - } - - String protoType = fontProperties.getProperty(key.toString()); - int s = validSize(size); - return protoType.replaceFirst("%d", String.valueOf(s * 10)); - } - - /** - * Checks the specified font name for a valid font name. If the font name - * is not known, then this returns 'sansserif' as fallback. - * - * @param name the font name to check - * - * @return a valid font name - */ - static String validName(String name) - { - String retVal; - if (name.equalsIgnoreCase("sansserif") - || name.equalsIgnoreCase("serif") - || name.equalsIgnoreCase("monospaced") - || name.equalsIgnoreCase("dialog") - || name.equalsIgnoreCase("dialoginput")) - { - retVal = name.toLowerCase(); - } - else - { - retVal = "sansserif"; - } - return retVal; - } - - /** - * Translates an arbitrary point size to a size that is typically available - * on an X server. These are the sizes 8, 10, 12, 14, 18 and 24. - * - * @param size the queried size - * @return the real available size - */ - private static final int validSize(int size) - { - int val; - if (size <= 9) - val = 8; - else if (size <= 11) - val = 10; - else if (size <= 13) - val = 12; - else if (size <= 17) - val = 14; - else if (size <= 23) - val = 18; - else - val = 24; - return val; - } - - /** - * Returns the X Font reference. This lazily loads the font when first - * requested. - * - * @return the X Font reference - */ - gnu.x11.Font getXFont() - { - if (xfont == null) - { - init(name, style, size); - } - return xfont; - } -} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java b/libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java index ef9507f3050..ab3861be1a9 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java @@ -42,17 +42,21 @@ import java.awt.FontMetrics; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.font.LineMetrics; +import java.awt.font.TextAttribute; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.io.File; import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.text.CharacterIterator; import java.text.StringCharacterIterator; import java.util.Locale; import java.util.Map; +import java.util.Properties; import gnu.java.awt.font.FontDelegate; import gnu.java.awt.font.FontFactory; @@ -62,11 +66,30 @@ public class XFontPeer2 extends ClasspathFontPeer { + /** + * The font mapping as specified in the file fonts.properties. + */ + private static Properties fontProperties; + static + { + fontProperties = new Properties(); + InputStream in = XFontPeer2.class.getResourceAsStream("fonts.properties"); + try + { + fontProperties.load(in); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + private class XLineMetrics extends LineMetrics { private Font font; + private GlyphVector glyphVector; // private CharacterIterator characterIterator; // private int begin; // private int limit; @@ -79,6 +102,8 @@ public class XFontPeer2 // begin = b; // limit = l; fontRenderContext = rc; + glyphVector = fontDelegate.createGlyphVector(font, fontRenderContext, + ci); } public float getAscent() @@ -86,7 +111,7 @@ public class XFontPeer2 return fontDelegate.getAscent(font.getSize(), fontRenderContext.getTransform(), fontRenderContext.isAntiAliased(), fontRenderContext.usesFractionalMetrics(), true); - } + } public int getBaselineIndex() { @@ -102,21 +127,18 @@ public class XFontPeer2 public float getDescent() { - return (int) fontDelegate.getDescent(font.getSize(), - new AffineTransform(), false, false, - false); + return (int) fontDelegate.getDescent(font.getSize(), IDENDITY, false, + false, false); } public float getHeight() { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); + return (float) glyphVector.getLogicalBounds().getHeight(); } public float getLeading() { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); + return getHeight() - getAscent() - getDescent(); } public int getNumChars() @@ -150,6 +172,11 @@ public class XFontPeer2 private class XFontMetrics extends FontMetrics { + /** + * A cached point instance, to be used in #charWidth(). + */ + private Point2D cachedPoint = new Point2D.Double(); + XFontMetrics(Font f) { super(f); @@ -157,22 +184,20 @@ public class XFontPeer2 public int getAscent() { - return (int) fontDelegate.getAscent(getFont().getSize(), - new AffineTransform(), false, false, - false); + return (int) fontDelegate.getAscent(getFont().getSize(), IDENDITY, + false, false, false); } public int getDescent() { - return (int) fontDelegate.getDescent(getFont().getSize(), - new AffineTransform(), false, false, - false); + return (int) fontDelegate.getDescent(getFont().getSize(), IDENDITY, + false, false, false); } public int getHeight() { GlyphVector gv = fontDelegate.createGlyphVector(getFont(), - new FontRenderContext(new AffineTransform(), false, false), + new FontRenderContext(IDENDITY, false, false), new StringCharacterIterator("m")); Rectangle2D b = gv.getVisualBounds(); return (int) b.getHeight(); @@ -180,8 +205,9 @@ public class XFontPeer2 public int charWidth(char c) { - Point2D advance = new Point2D.Double(); - fontDelegate.getAdvance(c, getFont().getSize(), new AffineTransform(), + int code = fontDelegate.getGlyphIndex(c); + Point2D advance = cachedPoint; + fontDelegate.getAdvance(code, font.getSize2D(), IDENDITY, false, false, true, advance); return (int) advance.getX(); } @@ -194,13 +220,18 @@ public class XFontPeer2 public int stringWidth(String s) { GlyphVector gv = fontDelegate.createGlyphVector(getFont(), - new FontRenderContext(new AffineTransform(), false, false), + new FontRenderContext(IDENDITY, false, false), new StringCharacterIterator(s)); Rectangle2D b = gv.getVisualBounds(); return (int) b.getWidth(); } } + /** + * The indendity transform, to be used in several methods. + */ + private static final AffineTransform IDENDITY = new AffineTransform(); + private FontDelegate fontDelegate; XFontPeer2(String name, int style, int size) @@ -208,7 +239,7 @@ public class XFontPeer2 super(name, style, size); try { - File fontfile = new File("/usr/share/fonts/truetype/ttf-bitstream-vera/Vera.ttf"); + File fontfile = new File("/usr/share/fonts/truetype/freefont/FreeSans.ttf"); FileInputStream in = new FileInputStream(fontfile); FileChannel ch = in.getChannel(); ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, @@ -239,7 +270,7 @@ public class XFontPeer2 } } - public boolean canDisplay(Font font, char c) + public boolean canDisplay(Font font, int c) { // FIXME: Implement this. throw new UnsupportedOperationException("Not yet implemented"); @@ -326,4 +357,112 @@ public class XFontPeer2 throw new UnsupportedOperationException("Not yet implemented"); } + /** + * Encodes a font name + style + size specification into a X logical font + * description (XLFD) as described here: + * + * http://www.meretrx.com/e93/docs/xlfd.html + * + * This is implemented to look up the font description in the + * fonts.properties of this package. + * + * @param name the font name + * @param atts the text attributes + * + * @return the encoded font description + */ + static String encodeFont(String name, Map atts) + { + String family = name; + if (family == null || family.equals("")) + family = (String) atts.get(TextAttribute.FAMILY); + if (family == null) + family = "SansSerif"; + + int size = 12; + Float sizeFl = (Float) atts.get(TextAttribute.SIZE); + if (sizeFl != null) + size = sizeFl.intValue(); + + int style = 0; + // Detect italic attribute. + Float posture = (Float) atts.get(TextAttribute.POSTURE); + if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR)) + style |= Font.ITALIC; + + // Detect bold attribute. + Float weight = (Float) atts.get(TextAttribute.WEIGHT); + if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0) + style |= Font.BOLD; + + return encodeFont(name, style, size); + } + + /** + * Encodes a font name + style + size specification into a X logical font + * description (XLFD) as described here: + * + * http://www.meretrx.com/e93/docs/xlfd.html + * + * This is implemented to look up the font description in the + * fonts.properties of this package. + * + * @param name the font name + * @param style the font style + * @param size the font size + * + * @return the encoded font description + */ + static String encodeFont(String name, int style, int size) + { + StringBuilder key = new StringBuilder(); + key.append(validName(name)); + key.append('.'); + switch (style) + { + case Font.BOLD: + key.append("bold"); + break; + case Font.ITALIC: + key.append("italic"); + break; + case (Font.BOLD | Font.ITALIC): + key.append("bolditalic"); + break; + case Font.PLAIN: + default: + key.append("plain"); + + } + + String protoType = fontProperties.getProperty(key.toString()); + int s = size; + return protoType.replaceFirst("%d", String.valueOf(s * 10)); + } + + /** + * Checks the specified font name for a valid font name. If the font name + * is not known, then this returns 'sansserif' as fallback. + * + * @param name the font name to check + * + * @return a valid font name + */ + static String validName(String name) + { + String retVal; + if (name.equalsIgnoreCase("sansserif") + || name.equalsIgnoreCase("serif") + || name.equalsIgnoreCase("monospaced") + || name.equalsIgnoreCase("dialog") + || name.equalsIgnoreCase("dialoginput")) + { + retVal = name.toLowerCase(); + } + else + { + retVal = "sansserif"; + } + return retVal; + } } diff --git a/libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java b/libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java index 439a2a7bbf1..74e47bc2842 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java @@ -137,4 +137,10 @@ public class XFramePeer throw new UnsupportedOperationException("Not yet implemented."); } + public Rectangle getBoundsPrivate() + { + // TODO: Implement this properly. + throw new InternalError("Not yet implemented"); + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphics.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphics.java deleted file mode 100644 index 134d7d3305e..00000000000 --- a/libjava/classpath/gnu/java/awt/peer/x/XGraphics.java +++ /dev/null @@ -1,792 +0,0 @@ -/* XGraphics.java -- The Graphics implementation for X - 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.x; - -import gnu.x11.Colormap; -import gnu.x11.Data; -import gnu.x11.Display; -import gnu.x11.Drawable; -import gnu.x11.GC; -import gnu.x11.Pixmap; -import gnu.x11.Point; -import gnu.x11.image.ZPixmap; - -import java.awt.AWTError; -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Image; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.Toolkit; -import java.awt.Transparency; -import java.awt.image.BufferedImage; -import java.awt.image.ImageObserver; -import java.awt.image.ImageProducer; -import java.text.AttributedCharacterIterator; -import java.util.HashMap; - -public class XGraphics - extends Graphics - implements Cloneable -{ - - /** - * The X Drawable to draw on. - */ - private Drawable xdrawable; - - /** - * The X graphics context (GC). - */ - private GC xgc; - - /** - * The current translation. - */ - private int translateX; - private int translateY; - - /** - * The current clip. Possibly null. - */ - private Rectangle clip; - - /** - * The current font, possibly null. - */ - private Font font; - - /** - * The current foreground color, possibly null. - */ - private Color foreground; - - /** - * Indicates if this object has been disposed. - */ - private boolean disposed = false; - - // TODO: Workaround for limitation in current Escher. - private Pixmap.Format pixmapFormat; - private int imageByteOrder; - private int pixelByteCount; - - /** - * Creates a new XGraphics on the specified X Drawable. - * - * @param d the X Drawable for which we create the Graphics - */ - XGraphics(Drawable d) - { - xdrawable = d; - xgc = new GC(d); - translateX = 0; - translateY = 0; - clip = new Rectangle(0, 0, d.width, d.height); - - Display display = xdrawable.display; - pixmapFormat = display.default_pixmap_format; - imageByteOrder = display.image_byte_order; - pixelByteCount = pixmapFormat.bits_per_pixel () / 8; - } - - /** - * Creates an exact copy of this graphics context. - * - * @return an exact copy of this graphics context - */ - public Graphics create() - { - XGraphics copy = (XGraphics) clone(); - return copy; - } - - /** - * Translates the origin by (x, y). - */ - public void translate(int x, int y) - { - translateX += x; - translateY += y; - if (clip != null) - { - clip.x -= x; - clip.y -= y; - } - } - - /** - * Returns the current foreground color, possibly <code>null</code>. - * - * @return the current foreground color, possibly <code>null</code> - */ - public Color getColor() - { - return foreground; - } - - /** - * Sets the current foreground color. A <code>null</code> value doesn't - * change the current setting. - * - * @param c the foreground color to set - */ - public void setColor(Color c) - { - if (c != null) - { - XToolkit tk = (XToolkit) Toolkit.getDefaultToolkit(); - HashMap colorMap = tk.colorMap; - gnu.x11.Color col = (gnu.x11.Color) colorMap.get(c); - if (col == null) - { - Colormap map = xdrawable.display.default_colormap; - col = map.alloc_color (c.getRed() * 256, - c.getGreen() * 256, - c.getBlue() * 256); - colorMap.put(c, col); - } - xgc.set_foreground(col); - foreground = c; - } - } - - public void setPaintMode() - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public void setXORMode(Color color) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - /** - * Returns the current font, possibly <code>null</code>. - * - * @return the current font, possibly <code>null</code> - */ - public Font getFont() - { - return font; - } - - /** - * Sets the font on the graphics context. A <code>null</code> value doesn't - * change the current setting. - * - * @param f the font to set - */ - public void setFont(Font f) - { - if (f != null) - { - XFontPeer xFontPeer = (XFontPeer) f.getPeer(); - xgc.set_font(xFontPeer.getXFont()); - font = f; - } - } - - /** - * Returns the font metrics for the specified font. - * - * @param font the font for which we want the font metrics - * - * @return the font metrics for the specified font - */ - public FontMetrics getFontMetrics(Font font) - { - if (font == null) - { - if (this.font == null) - setFont(new Font("Dialog", Font.PLAIN, 12)); - font = this.font; - } - XFontPeer xFontPeer = (XFontPeer) font.getPeer(); - return xFontPeer.getFontMetrics(font); - } - - /** - * Returns the bounds of the current clip. - * - * @return the bounds of the current clip - */ - public Rectangle getClipBounds() - { - return clip != null ? clip.getBounds() : null; - } - - /** - * Clips the current clip with the specified clip. - */ - public void clipRect(int x, int y, int width, int height) - { - if (clip == null) - { - clip = new Rectangle(x, y, width, height); - } - else - { - computeIntersection(x, y, width, height, clip); - } - // Update the X clip setting. - setXClip(clip.x, clip.y, clip.width, clip.height); - } - - /** - * Returns <code>true</code> when the specified rectangle intersects with - * the current clip, <code>false</code> otherwise. This is overridden to - * avoid unnecessary creation of Rectangles via getBounds(). - * - * @param x the x coordinate of the rectangle - * @param y the y coordinate of the rectangle - * @param w the width of the rectangle - * @param h the height of the rectangle - * - * @return <code>true</code> when the specified rectangle intersects with - * the current clip, <code>false</code> otherwise - */ - public boolean hitClip(int x, int y, int w, int h) - { - boolean hit; - if (clip == null) - { - hit = true; - } - else - { - // It's easier to determine if the rectangle lies outside the clip, - // so we determine that and reverse the result (if it's not completely - // outside, it most likely hits the clip rectangle). - int x2 = x + w; - int y2 = y + h; - int clipX2 = clip.x + clip.width; - int clipY2 = clip.y + clip.height; - boolean outside = (x < clip.x && x2 < clip.x) // Left. - || (x > clipX2 && x2 > clipX2) // Right. - || (y < clip.y && y2 < clip.y) // Top. - || (y > clipY2 && y2 > clipY2); // Bottom. - hit = ! outside; - } - return hit; - } - - public void setClip(int x, int y, int width, int height) - { - if (clip != null) - clip.setBounds(x, y, width, height); - else - clip = new Rectangle(x, y, width, height); - setXClip(clip.x, clip.y, clip.width, clip.height); - } - - /** - * Sets the clip on the X server GC. The coordinates are not yet translated, - * this will be performed by the X server. - * - * @param x the clip, X coordinate - * @param y the clip, Y coordinate - * @param w the clip, width - * @param h the clip, height - */ - private void setXClip(int x, int y, int w, int h) - { - gnu.x11.Rectangle[] clipRects = new gnu.x11.Rectangle[] { - new gnu.x11.Rectangle(x, y, w, h) }; - xgc.set_clip_rectangles(translateX, translateY, clipRects, GC.YX_BANDED); - } - - public Shape getClip() - { - // Return a copy here, so nobody can trash our clip. - return clip == null ? null : clip.getBounds(); - } - - /** - * Sets the current clip. - * - * @param c the clip to set - */ - public void setClip(Shape c) - { - if (c != null) - { - Rectangle b; - if (c instanceof Rectangle) - { - b = (Rectangle) c; - } - else - { - b = c.getBounds(); - } - clip.setBounds(b); - setXClip(b.x, b.y, b.width, b.height); - } - else - { - clip.setBounds(0, 0, xdrawable.width, xdrawable.height); - setXClip(0, 0, xdrawable.width, xdrawable.height); - } - } - - public void copyArea(int x, int y, int width, int height, int dx, int dy) - { - // Clip and translate src rectangle. - int srcX = Math.min(Math.max(x, clip.x), clip.x + clip.width) - + translateX; - int srcY = Math.min(Math.max(y, clip.y), clip.y + clip.height) - + translateY; - int srcWidth = Math.min(Math.max(x + width, clip.x), - clip.x + clip.width) - x; - int srcHeight = Math.min(Math.max(y + height, clip.y), - clip.y + clip.height) - y; - xdrawable.copy_area(xdrawable, xgc, srcX, srcY, srcWidth, srcHeight, - srcX + dx, srcY + dy); - } - - /** - * Draws a line from point (x1, y1) to point (x2, y2). - */ - public void drawLine(int x1, int y1, int x2, int y2) - { - //System.err.println("drawLine: " + (x1 + translateX) + ", " + ( y1 + translateY) + ", " + (x2 + translateX) + ", " + (y2 + translateY) + " on: " + xdrawable); - xdrawable.line(xgc, x1 + translateX, y1 + translateY, - x2 + translateX, y2 + translateY); - } - - /** - * Fills the specified rectangle. - */ - public void fillRect(int x, int y, int width, int height) - { - xdrawable.rectangle(xgc, x + translateX, y + translateY, - width, height, true); - } - - public void clearRect(int x, int y, int width, int height) - { - xgc.set_foreground(Color.WHITE.getRGB()); - xdrawable.rectangle(xgc, x, y, width, height, true); - if (foreground != null) - xgc.set_foreground(foreground.getRGB()); - } - - public void drawRoundRect(int x, int y, int width, int height, int arcWidth, - int arcHeight) - { - // Draw 4 lines. - int arcRadiusX = arcWidth / 2; - int arcRadiusY = arcHeight / 2; - drawLine(x + arcRadiusX, y, x + width - arcRadiusX, y); - drawLine(x, y + arcRadiusY, x, y + height - arcRadiusY); - drawLine(x + arcRadiusX, y + height, x + width - arcRadiusX, y + height); - drawLine(x + width, y + arcRadiusY, x + width, y + height - arcRadiusY); - - // Draw the 4 arcs at the corners. - // Upper left. - drawArc(x, y, arcWidth, arcHeight, 90, 90); - // Lower left. - drawArc(x, y + height - arcHeight, arcWidth, arcHeight, 180, 90); - // Upper right. - drawArc(x + width - arcWidth, y, arcWidth, arcHeight, 0, 90); - // Lower right. - drawArc(x + width - arcWidth, y + height - arcHeight, arcWidth, arcHeight, - 270, 90); - } - - public void fillRoundRect(int x, int y, int width, int height, int arcWidth, - int arcHeight) - { - // Fill the 3 rectangles that make up the inner area. - int arcRadiusX = arcWidth / 2; - int arcRadiusY = arcHeight / 2; - // Left. - fillRect(x, y + arcRadiusY, arcRadiusX, height - arcHeight); - // Middle. - fillRect(x + arcRadiusX, y, width - arcWidth, height); - // Right. - fillRect(x + width - arcRadiusX, y + arcRadiusY, arcRadiusX, - height - arcHeight); - - // Fill the 4 arcs in the corners. - // Upper left. - fillArc(x, y, arcWidth, arcHeight, 90, 90); - // Lower left. - fillArc(x, y + height - arcHeight, arcWidth, arcHeight, 180, 90); - // Upper right. - fillArc(x + width - arcWidth, y, arcWidth, arcHeight, 0, 90); - // Lower right. - fillArc(x + width - arcWidth, y + height - arcHeight, arcWidth, arcHeight, - 270, 90); - } - - public void drawOval(int x, int y, int width, int height) - { - xdrawable.arc(xgc, x, y, width, height, 0, 360 * 64, false); - } - - public void fillOval(int x, int y, int width, int height) - { - xdrawable.arc(xgc, x, y, width, height, 0, 360 * 64, true); - } - - public void drawArc(int x, int y, int width, int height, int arcStart, - int arcAngle) - { - xdrawable.arc(xgc, x, y, width, height, arcStart * 64, arcAngle * 64, false); - } - - public void fillArc(int x, int y, int width, int height, int arcStart, - int arcAngle) - { - xdrawable.arc(xgc, x, y, width, height, arcStart * 64, arcAngle * 64, true); - } - - public void drawPolyline(int[] xPoints, int[] yPoints, int npoints) - { - int numPoints = Math.min(xPoints.length, yPoints.length); - Point[] points = new Point[numPoints]; - // FIXME: Improve Escher API to accept arrays to avoid creation - // of many Point objects. - for (int i = 0; i < numPoints; i++) - points[i] = new Point(xPoints[i], yPoints[i]); - xdrawable.poly_line(xgc, points, Drawable.ORIGIN); - } - - public void drawPolygon(int[] xPoints, int[] yPoints, int npoints) - { - int numPoints = Math.min(xPoints.length, yPoints.length); - Point[] points = new Point[numPoints]; - // FIXME: Improve Escher API to accept arrays to avoid creation - // of many Point objects. - for (int i = 0; i < numPoints; i++) - points[i] = new Point(xPoints[i], yPoints[i]); - xdrawable.poly_line(xgc, points, Drawable.ORIGIN); - } - - public void fillPolygon(int[] xPoints, int[] yPoints, int npoints) - { - int numPoints = Math.min(xPoints.length, yPoints.length); - Point[] points = new Point[numPoints]; - // FIXME: Improve Escher API to accept arrays to avoid creation - // of many Point objects. - for (int i = 0; i < numPoints; i++) - points[i] = new Point(xPoints[i], yPoints[i]); - xdrawable.fill_poly(xgc, points, Drawable.COMPLEX, Drawable.ORIGIN); - } - - /** - * Draws the specified string at (x, y). - */ - public void drawString(String string, int x, int y) - { - if (disposed) - throw new AWTError("XGraphics already disposed"); - - xdrawable.text(xgc, x + translateX, y + translateY, string); - } - - public void drawString(AttributedCharacterIterator ci, int x, int y) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - /** - * Draws the specified image on the drawable at position (x,y). - */ - public boolean drawImage(Image image, int x, int y, ImageObserver observer) - { - if (image instanceof XImage) - { - XImage xim = (XImage) image; - Pixmap pm = xim.pixmap; - xdrawable.copy_area(pm, xgc, 0, 0, pm.width, pm.height, - x + translateX, y + translateY); - } - else if (image instanceof BufferedImage - && ((BufferedImage) image).getTransparency() != Transparency.OPAQUE) - { - BufferedImage bi = (BufferedImage) image; - int width = bi.getWidth(); - int height = bi.getHeight(); - Data img = xdrawable.image(x + translateX, y + translateY, - width, height, 0xFFFFFFFF, 2); - - // Compute line byte count. - int lineBitCount = width * pixmapFormat.bits_per_pixel (); - int rem = lineBitCount % pixmapFormat.scanline_pad (); - int linePadCount = lineBitCount / pixmapFormat.scanline_pad () - + (rem == 0 ? 0 : 1); - int lineByteCount = linePadCount * pixmapFormat.scanline_pad () / 8; - - // Composite source and destination pixel data. - int[] trgb = new int[3]; // The device rgb pixels. - for (int yy = 0; yy < height; yy++) - { - for (int xx = 0; xx < width; xx++) - { - getRGB(xx, yy, img, trgb, lineByteCount); - int srgb = bi.getRGB(xx, yy); - float alpha = ((srgb >> 24) & 0xff) / 256F; - float tAlpha = 1.F - alpha; - int red = (srgb >> 16) & 0xFF; - int green = (srgb >> 8) & 0xFF; - int blue = (srgb) & 0xFF; - trgb[0] = (int) (trgb[0] * tAlpha + red * alpha); - trgb[1] = (int) (trgb[1] * tAlpha + green * alpha); - trgb[2] = (int) (trgb[2] * tAlpha + blue * alpha); - setRGB(xx, yy, img, trgb, lineByteCount); - } - } - - // Now we have the transparent image composited onto the target - // Image, now we only must copy it to the Drawable. - ZPixmap pm = new ZPixmap(xdrawable.display); - pm.width = width; - pm.height = height; - pm.init(); - System.arraycopy(img.data, 32, pm.data, 0, img.data.length - 32); - xdrawable.put_image(xgc, pm, x + translateX, y + translateY); - } - else - { - // Pre-render the image into an XImage. - ImageProducer source = image.getSource(); - ImageConverter conv = new ImageConverter(); - source.startProduction(conv); - XImage xim = conv.getXImage(); - Pixmap pm = xim.pixmap; - xdrawable.copy_area(pm, xgc, 0, 0, pm.width, pm.height, - x + translateX, y + translateY); - } - return true; - } - - /** - * Helper method to work around limitation in the current Escher impl. - * - * @param x the x position - * @param y the y position - * @param img the image data - * @param rgb an 3-size array that holds the rgb values on method exit - */ - private void getRGB(int x, int y, Data img, int[] rgb, int lineByteCount) - { - // TODO: Does this also work on non-RGB devices? - int i = y * lineByteCount + pixelByteCount * x; - if (imageByteOrder == gnu.x11.image.Image.LSB_FIRST) - {//if (i >= 5716-33) System.err.println("lbc: " + lineByteCount + ", " + pixelByteCount); - rgb[2] = img.data[32 + i]; - rgb[1] = img.data[32 + i + 1]; - rgb[0] = img.data[32 + i + 2]; - } - else - { // MSB_FIRST - rgb[0] = img.data[32 + i]; - rgb[1] = img.data[32 + i + 1]; - rgb[2] = img.data[32 + i + 2]; - } - - } - - /** - * Helper method to work around limitation in the current Escher impl. - * - * @param x the x position - * @param y the y position - * @param img the image data - * @param rgb an 3-size array that holds the rgb values on method exit - */ - private void setRGB(int x, int y, Data img, int[] rgb, int lineByteCount) - { - // TODO: Does this also work on non-RGB devices? - int i = y * lineByteCount + pixelByteCount * x; - if (imageByteOrder == gnu.x11.image.Image.LSB_FIRST) - { - img.data[32 + i] = (byte) rgb[2]; - img.data[32 + i + 1] = (byte) rgb[1]; - img.data[32 + i + 2] = (byte) rgb[0]; - } - else - { // MSB_FIRST - img.data[32 + i] = (byte) rgb[0]; - img.data[32 + i + 1] = (byte) rgb[1]; - img.data[32 + i + 2] = (byte) rgb[2]; - } - } - - public boolean drawImage(Image image, int x, int y, int width, int height, - ImageObserver observer) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public boolean drawImage(Image image, int x, int y, Color bgcolor, - ImageObserver observer) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public boolean drawImage(Image image, int x, int y, int width, int height, - Color bgcolor, ImageObserver observer) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - ImageObserver observer) - { - return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, - observer); - } - - public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, Color bgcolor, - ImageObserver observer) - { - - // FIXME: What to do with bgcolor? - - // Scale the image. - int sw = image.getWidth(observer); - int sh = image.getHeight(observer); - double scaleX = Math.abs(dx2 - dx1) / (double) Math.abs(sx2 - sx1); - double scaleY = Math.abs(dy2 - dy1) / (double) Math.abs(sy2 - sy1); - Image scaled = image.getScaledInstance((int) (scaleX * sw), - (int) (scaleY * sh), - Image.SCALE_FAST); - - // Scaled source coordinates. - int sx1s = (int) (scaleX * Math.min(sx1, sx2)); - int sx2s = (int) (scaleX * Math.max(sx1, sx2)); - - // Temporarily clip to the target rectangle. - Rectangle old = clip; - clipRect(dx1, dy1, dx2 - dx1, dy2 - dy1); - - // Draw scaled image. - boolean res = drawImage(scaled, dx1 - sx1s, dy1 - sx2s, observer); - - // Reset clip. - setClip(old); - - return res; - } - - /** - * Frees any resources associated with this object. - */ - public void dispose() - { - if (! disposed) - { - xgc.free(); - xdrawable.display.flush(); - disposed = true; - } - } - - // Additional helper methods. - - /** - * Creates and returns an exact copy of this XGraphics. - */ - protected Object clone() - { - try - { - XGraphics copy = (XGraphics) super.clone(); - copy.xgc = xgc.copy(); - if (clip != null) - { - copy.clip = new Rectangle(clip); - copy.setXClip(clip.x, clip.y, clip.width, clip.height); - } - return copy; - } - catch (CloneNotSupportedException ex) - { - assert false; - } - return null; - } - - /** - * Computes the intersection between two rectangles and stores the result - * int the second rectangle. - * - * This method has been copied from {@link javax.swing.SwingUtilities}. - * - * @param x the x coordinate of the rectangle #1 - * @param y the y coordinate of the rectangle #1 - * @param w the width of the rectangle #1 - * @param h the height of the rectangle #1 - * @param rect the rectangle #2 and output rectangle - */ - private static void computeIntersection(int x, int y, int w, int h, - Rectangle rect) - { - int x2 = (int) rect.x; - int y2 = (int) rect.y; - int w2 = (int) rect.width; - int h2 = (int) rect.height; - - int dx = (x > x2) ? x : x2; - int dy = (y > y2) ? y : y2; - int dw = (x + w < x2 + w2) ? (x + w - dx) : (x2 + w2 - dx); - int dh = (y + h < y2 + h2) ? (y + h - dy) : (y2 + h2 - dy); - - if (dw >= 0 && dh >= 0) - rect.setBounds(dx, dy, dw, dh); - else - rect.setBounds(0, 0, 0, 0); - } - - -} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java index 5dc79ff5c2b..73e780cc5a2 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java @@ -37,16 +37,23 @@ exception statement from your version. */ package gnu.java.awt.peer.x; +import java.awt.Color; import java.awt.Graphics; import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Paint; import java.awt.Rectangle; import java.awt.Shape; import java.awt.Toolkit; import java.awt.geom.AffineTransform; import java.awt.image.ColorModel; +import java.awt.image.ImageObserver; import java.awt.image.Raster; +import java.util.HashMap; import gnu.java.awt.java2d.AbstractGraphics2D; +import gnu.java.awt.java2d.ScanlineCoverage; +import gnu.x11.Colormap; import gnu.x11.Drawable; import gnu.x11.GC; import gnu.x11.image.ZPixmap; @@ -70,6 +77,11 @@ public class XGraphics2D */ private boolean disposed; + /** + * The current foreground color, possibly null. + */ + private Color foreground; + XGraphics2D(Drawable d) { super(); @@ -80,31 +92,9 @@ public class XGraphics2D //setClip(new Rectangle(0, 0, xdrawable.width, xdrawable.height)); } - /** - * Draws a pixel in the target coordinate space using the specified color. - * - * @param x the x coordinate - * @param y the y coordinate - */ - protected void rawSetPixel(int x, int y) - { - xdrawable.point(xgc, x, y); - } - -// protected void rawFillPolygon(double[] xpoints, double[] ypoints, int npoints) -// { -// Point[] points = new Point[npoints]; -// for (int n = 0; n < npoints; n++) -// { -// points[n] = new Point((int) xpoints[n], (int) ypoints[n]); -// } -// xdrawable.fill_poly(xgc, points, Drawable.COMPLEX, Drawable.ORIGIN); -// xdrawable.display.flush(); -// } - protected void rawDrawLine(int x0, int y0, int x1, int y1) { - xdrawable.line(xgc, x0, y0, x1, y1); + xdrawable.segment(xgc, x0, y0, x1, y1); } protected void rawFillRect(int x, int y, int w, int h) @@ -112,17 +102,6 @@ public class XGraphics2D xdrawable.rectangle(xgc, x, y, w, h, true); } - protected void rawSetForeground(java.awt.Color c) - { - if (c != null) - xgc.set_foreground(c.getRGB()); - } - - protected void rawSetForeground(int r, int g, int b) - { - xgc.set_foreground( r << 16 | g << 8 | b ); - } - /** * Returns the color model of this Graphics object. * @@ -178,55 +157,6 @@ public class XGraphics2D return copy; } -// /** -// * Draws the specified image on the drawable at position (x,y). -// */ -// -// public boolean drawImage(Image image, int x, int y, ImageObserver observer) -// { -// AffineTransform transform = getTransform(); -// int translateX = (int) transform.getTranslateX(); -// int translateY = (int) transform.getTranslateY(); -// if (image instanceof XImage) -// { -// XImage xim = (XImage) image; -// Pixmap pm = xim.pixmap; -// xdrawable.copy_area(pm, xgc, 0, 0, pm.width, pm.height, -// x + translateX, y + translateY); -// } -// else if (image instanceof BufferedImage) -// { -// BufferedImage bufferedImage = (BufferedImage) image; -// Raster raster = bufferedImage.getData(); -// int w = bufferedImage.getWidth(); -// int h = bufferedImage.getHeight(); -// // Push data to X server. -// ZPixmap zPixmap = new ZPixmap(xdrawable.display, w, h, -// xdrawable.display.default_pixmap_format); -// System.err.println("data buffer length: " + zPixmap.data.length); -// int[] pixel = new int[4]; -// for (int tx = 0; tx < w; tx++) -// { -// for (int ty = 0; ty < h; ty++) -// { -// pixel = raster.getPixel(tx, ty, pixel); -//// System.err.print("r: " + pixel[0]); -//// System.err.print(", g: " + pixel[1]); -//// System.err.println(", b: " + pixel[2]); -// zPixmap.set_red(tx, ty, pixel[0]); -// zPixmap.set_green(tx, ty, pixel[1]); -// zPixmap.set_blue(tx, ty, pixel[2]); -// } -// } -// xdrawable.put_image(xgc, zPixmap, x, y); -// } -// else -// { -// throw new UnsupportedOperationException("Not yet implemented."); -// } -// return true; -// } -// public void setClip(Shape c) { super.setClip(c); @@ -287,9 +217,115 @@ public class XGraphics2D } } + public void renderScanline(int y, ScanlineCoverage c) + { + ScanlineCoverage.Iterator iter = c.iterate(); + float coverageAlpha = 0; + int maxCoverage = c.getMaxCoverage(); + Color old = getColor(); + Color col = getColor(); + if (col == null) + col = Color.BLACK; + while (iter.hasNext()) + { + ScanlineCoverage.Range range = iter.next(); + // TODO: Dumb implementation for testing. + coverageAlpha = range.getCoverage(); + if (coverageAlpha > 0) + { + int red = col.getRed(); + int green = col.getGreen(); + int blue = col.getBlue(); + if (coverageAlpha < c.getMaxCoverage()) + { + float alpha = coverageAlpha / maxCoverage; + red = 255 - (int) ((255 - red) * alpha); + green = 255 - (int) ((255 - green) * alpha); + blue = 255 - (int) ((255 - blue) * alpha); + } + xgc.set_foreground(red << 16 | green << 8 | blue); + int x0 = range.getXPos(); + int l = range.getLength(); + xdrawable.fill_rectangle(xgc, x0, y, l, 1); + } + } + if (old != null) + xgc.set_foreground(old.getRGB()); + } + + protected void fillScanline(int x0, int x1, int y) + { + xdrawable.segment(xgc, x0, y, x1, y); + } + + protected void fillScanlineAA(int x0, int x1, int y, int alpha) + { + //System.err.println("fillScanlineAA: " + x0 + ", " + x1 + ", " + y + ", " + alpha); + // FIXME: This is for testing only. + Color c = getColor(); + setColor(new Color(255-alpha, 255-alpha, 255-alpha)); + xdrawable.segment(xgc, x0, y, x1, y); + setColor(c); + } protected void init() { super.init(); } + + public void setPaint(Paint p) + { + super.setPaint(p); + if (p instanceof Color) + { + Color c = (Color) p; + XToolkit tk = (XToolkit) Toolkit.getDefaultToolkit(); + HashMap colorMap = tk.colorMap; + gnu.x11.Color col = (gnu.x11.Color) colorMap.get(c); + if (col == null) + { + Colormap map = xdrawable.display.default_colormap; + col = map.alloc_color (c.getRed() * 256, + c.getGreen() * 256, + c.getBlue() * 256); + colorMap.put(c, col); + } + xgc.set_foreground(col); + foreground = c; + } + } + + protected void fillShape(Shape s, boolean isFont) + { + synchronized (xdrawable.display) { + super.fillShape(s, isFont); + } + } + + protected boolean rawDrawImage(Image image, int x, int y, ImageObserver obs) + { + boolean ret; + if (image instanceof XImage) + { + XImage xImage = (XImage) image; + xdrawable.copy_area(xImage.pixmap, xgc, 0, 0, xImage.getWidth(obs), + xImage.getHeight(obs), x, y); + ret = true; + } + else if (image instanceof PixmapVolatileImage) + { + PixmapVolatileImage pvi = (PixmapVolatileImage) image; + xdrawable.copy_area(pvi.getPixmap(), xgc, 0, 0, pvi.getWidth(obs), + pvi.getHeight(obs), x, y); + ret = true; + } + else + { + ret = super.rawDrawImage(image, x, y, obs); + } + return ret; + } + + } + diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java index d6e66cbd202..11a9c9694f1 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java @@ -39,11 +39,20 @@ package gnu.java.awt.peer.x; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; +import java.awt.Point; import java.awt.Rectangle; +import java.awt.Transparency; +import java.awt.color.ColorSpace; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; +import java.awt.image.ComponentColorModel; +import java.awt.image.ComponentSampleModel; +import java.awt.image.DataBuffer; +import java.awt.image.Raster; +import java.awt.image.SampleModel; import java.awt.image.VolatileImage; +import java.awt.image.WritableRaster; public class XGraphicsConfiguration extends GraphicsConfiguration @@ -63,26 +72,60 @@ public class XGraphicsConfiguration public BufferedImage createCompatibleImage(int w, int h) { - return new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + return createCompatibleImage(w, h, Transparency.OPAQUE); } - public VolatileImage createCompatibleVolatileImage(int w, int h) + public BufferedImage createCompatibleImage(int w, int h, int transparency) { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); + BufferedImage bi; + switch (transparency) + { + case Transparency.OPAQUE: + DataBuffer buffer = new ZPixmapDataBuffer(w, h); + SampleModel sm = new ComponentSampleModel(DataBuffer.TYPE_BYTE, w, h, + 4, w * 4, + new int[]{0, 1, 2, 3 }); + ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); + ColorModel cm = new ComponentColorModel(cs, true, false, + Transparency.OPAQUE, + DataBuffer.TYPE_BYTE); + WritableRaster raster = Raster.createWritableRaster(sm, buffer, + new Point(0, 0)); + bi = new BufferedImage(cm, raster, false, null); + break; + case Transparency.BITMASK: + case Transparency.TRANSLUCENT: + bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + break; + default: + throw new IllegalArgumentException("Illegal transparency: " + + transparency); + } + return bi; } - public VolatileImage createCompatibleVolatileImage(int width, int height, - int transparency) + public VolatileImage createCompatibleVolatileImage(int w, int h) { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); + return createCompatibleVolatileImage(w, h, Transparency.OPAQUE); } - public BufferedImage createCompatibleImage(int w, int h, int transparency) + public VolatileImage createCompatibleVolatileImage(int width, int height, + int transparency) { - // TODO: Implement this. - throw new UnsupportedOperationException("Not yet implemented."); + VolatileImage im; + switch (transparency) + { + case Transparency.OPAQUE: + im = new PixmapVolatileImage(width, height); + break; + case Transparency.BITMASK: + case Transparency.TRANSLUCENT: + throw new UnsupportedOperationException("Not yet implemented"); + default: + throw new IllegalArgumentException("Unknown transparency type: " + + transparency); + } + return im; } public ColorModel getColorModel() diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphicsDevice.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsDevice.java index 6a020ec4e7a..eff5902d22e 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XGraphicsDevice.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsDevice.java @@ -38,15 +38,12 @@ exception statement from your version. */ package gnu.java.awt.peer.x; import gnu.classpath.SystemProperties; -import gnu.java.net.local.LocalSocket; -import gnu.java.net.local.LocalSocketAddress; -import gnu.x11.Connection; import gnu.x11.Display; -import java.awt.AWTError; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; -import java.net.SocketException; +import java.lang.reflect.Constructor; +import java.net.Socket; /** * This class represents an X Display. The actual connection is established @@ -127,33 +124,21 @@ public class XGraphicsDevice || displayName.hostname.equals("")) && SystemProperties.getProperty("gnu.xawt.no_local_sockets") == null) { - // TODO: Is this 100% ok? - String sockPath = "/tmp/.X11-unix/X" + displayName.display_no; - LocalSocketAddress addr = new LocalSocketAddress(sockPath); - try + Socket socket = createLocalSocket(); + if (socket != null) { - if (XToolkit.DEBUG) - System.err.println("connecting to local socket: " - + sockPath); - LocalSocket socket = new LocalSocket(addr); display = new Display(socket, "localhost", displayName.display_no, displayName.screen_no); - display.connection.send_mode = Connection.ASYNCHRONOUS; - if (XToolkit.DEBUG) - System.err.println("connected to local socket"); } - catch (SocketException ex) - { - AWTError err = new AWTError("could not connect to X server"); - err.initCause(ex); - throw err; - } - } - else - { - display = new Display(displayName); } + + // The following happens when we are configured to use plain sockets, + // when the connection is probably remote or when we couldn't load + // the LocalSocket class stuff. + if (display == null) + display = new Display(displayName); + eventPump = new XEventPump(display); } return display; @@ -163,4 +148,36 @@ public class XGraphicsDevice { return eventPump; } + + /** + * Tries to load the LocalSocket class and initiate a connection to the + * local X server. + */ + private Socket createLocalSocket() + { + Socket socket = null; + try + { + // TODO: Is this 100% ok? + String sockPath = "/tmp/.X11-unix/X" + displayName.display_no; + Class localSocketAddressClass = + Class.forName("gnu.java.net.local.LocalSocketAddress"); + Constructor localSocketAddressConstr = + localSocketAddressClass.getConstructor(new Class[]{ String.class }); + Object addr = + localSocketAddressConstr.newInstance(new Object[]{ sockPath }); + Class localSocketClass = + Class.forName("gnu.java.net.local.LocalSocket"); + Constructor localSocketConstructor = + localSocketClass.getConstructor(new Class[]{localSocketAddressClass}); + Object localSocket = + localSocketConstructor.newInstance(new Object[]{ addr }); + socket = (Socket) localSocket; + } + catch (Exception ex) + { + // Whatever goes wrong here, we return null. + } + return socket; + } } diff --git a/libjava/classpath/gnu/java/awt/peer/x/XImage.java b/libjava/classpath/gnu/java/awt/peer/x/XImage.java index b9e993628f5..7d4636b95da 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XImage.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XImage.java @@ -86,7 +86,7 @@ public class XImage */ public Graphics getGraphics() { - XGraphics g = new XGraphics(pixmap); + XGraphics2D g = new XGraphics2D(pixmap); return g; } diff --git a/libjava/classpath/gnu/java/awt/peer/x/XLightweightPeer.java b/libjava/classpath/gnu/java/awt/peer/x/XLightweightPeer.java deleted file mode 100644 index 2613d84d80c..00000000000 --- a/libjava/classpath/gnu/java/awt/peer/x/XLightweightPeer.java +++ /dev/null @@ -1,56 +0,0 @@ -/* XLightweightPeer.java -- A lightweight peer for X - 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.x; - -import java.awt.Component; -import java.awt.peer.LightweightPeer; - -import gnu.java.awt.peer.swing.SwingContainerPeer; - -public class XLightweightPeer - extends SwingContainerPeer - implements LightweightPeer -{ - - XLightweightPeer(Component c) - { - super(c); - init(c, null); - } -} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XToolkit.java b/libjava/classpath/gnu/java/awt/peer/x/XToolkit.java index a286fd6f006..08186326ffa 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XToolkit.java @@ -44,7 +44,6 @@ import java.awt.Canvas; import java.awt.Checkbox; import java.awt.CheckboxMenuItem; import java.awt.Choice; -import java.awt.Component; import java.awt.Dialog; import java.awt.Dimension; import java.awt.EventQueue; @@ -69,6 +68,8 @@ import java.awt.TextArea; import java.awt.TextField; import java.awt.Transparency; import java.awt.Window; +import java.awt.Dialog.ModalExclusionType; +import java.awt.Dialog.ModalityType; import java.awt.datatransfer.Clipboard; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.peer.DragSourceContextPeer; @@ -88,7 +89,6 @@ import java.awt.peer.FileDialogPeer; import java.awt.peer.FontPeer; import java.awt.peer.FramePeer; import java.awt.peer.LabelPeer; -import java.awt.peer.LightweightPeer; import java.awt.peer.ListPeer; import java.awt.peer.MenuBarPeer; import java.awt.peer.MenuItemPeer; @@ -179,16 +179,16 @@ public class XToolkit */ public ClasspathFontPeer getClasspathFontPeer(String name, Map attrs) { - String canonical = XFontPeer.encodeFont(name, attrs); + String canonical = XFontPeer2.encodeFont(name, attrs); ClasspathFontPeer font; if (!fontCache.containsKey(canonical)) { String graphics2d = SystemProperties.getProperty("gnu.xawt.graphics2d"); - if (graphics2d != null && graphics2d.equals("gl")) + //if (graphics2d != null && graphics2d.equals("gl")) font = new XFontPeer2(name, attrs); - else - font = new XFontPeer(name, attrs); +// else +// font = new XFontPeer(name, attrs); fontCache.put(canonical, font); } else @@ -601,8 +601,20 @@ public class XToolkit return (XGraphicsDevice) env.getDefaultScreenDevice(); } - protected LightweightPeer createComponent(Component c) + @Override + public boolean isModalExclusionTypeSupported + (Dialog.ModalExclusionType modalExclusionType) { - return new XLightweightPeer(c); + // TODO: Implement properly. + return false; } + + @Override + public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) + { + // TODO: Implement properly. + return false; + } + + } diff --git a/libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java index 28cc5a5edf5..10d1e96858a 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java @@ -43,12 +43,16 @@ import java.awt.EventQueue; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.awt.Image; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.PaintEvent; import java.awt.event.WindowEvent; +import java.awt.image.VolatileImage; import gnu.x11.Window; import gnu.x11.event.Event; @@ -135,12 +139,22 @@ public class XWindowPeer */ public Graphics getGraphics() { - return new XGraphics(xwindow); + return new XGraphics2D(xwindow); } public Image createImage(int w, int h) { - return new XImage(w, h); + // FIXME: Should return a buffered image. + return createVolatileImage(w, h); + } + + @Override + public VolatileImage createVolatileImage(int width, int height) + { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + return gc.createCompatibleVolatileImage(width, height); } /** @@ -168,6 +182,9 @@ public class XWindowPeer new Rectangle(0, 0, w.getWidth(), w.getHeight()))); + Graphics g = getGraphics(); + g.clearRect(0, 0, awtComponent.getWidth(), awtComponent.getHeight()); + g.dispose(); // // Reset input selection. // atts.set_override_redirect(false); // xwindow.change_attributes(atts); @@ -240,7 +257,7 @@ public class XWindowPeer */ public FontMetrics getFontMetrics(Font font) { - XFontPeer fontPeer = (XFontPeer) font.getPeer(); + XFontPeer2 fontPeer = (XFontPeer2) font.getPeer(); return fontPeer.getFontMetrics(font); } diff --git a/libjava/classpath/gnu/java/awt/peer/x/ZPixmapDataBuffer.java b/libjava/classpath/gnu/java/awt/peer/x/ZPixmapDataBuffer.java new file mode 100644 index 00000000000..8043c5b8f46 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/ZPixmapDataBuffer.java @@ -0,0 +1,62 @@ +package gnu.java.awt.peer.x; + +import gnu.x11.Display; +import gnu.x11.image.ZPixmap; + +import java.awt.GraphicsEnvironment; +import java.awt.image.DataBuffer; + +/** + * A DataBuffer implementation that is based on a ZPixmap. This is used + * as backing store for BufferedImages. + */ +class ZPixmapDataBuffer + extends DataBuffer +{ + + /** + * The backing ZPixmap. + */ + private ZPixmap zpixmap; + + /** + * Creates a new ZPixmapDataBuffer with a specified width and height. + * + * @param d the X display + * @param w the width + * @param h the height + */ + ZPixmapDataBuffer(int w, int h) + { + super(TYPE_BYTE, w * h * 3); // TODO: Support non-24-bit-resolutions. + GraphicsEnvironment env = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + XGraphicsDevice dev = (XGraphicsDevice) env.getDefaultScreenDevice(); + Display d = dev.getDisplay(); + zpixmap = new ZPixmap(d, w, h, d.default_pixmap_format); + } + + /** + * Creates a ZPixmapDataBuffer from an existing ZPixmap. + * + * @param zpixmap the ZPixmap to wrap + */ + ZPixmapDataBuffer(ZPixmap zpixmap) + { + super(TYPE_BYTE, zpixmap.get_data_length()); + this.zpixmap = zpixmap; + } + + @Override + public int getElem(int bank, int i) + { + return 0xff & zpixmap.get_data_element(i); + } + + @Override + public void setElem(int bank, int i, int val) + { + zpixmap.set_data_element(i, (byte) val); + } + +} |