aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/java/awt
diff options
context:
space:
mode:
authorTom Tromey <tromey@gcc.gnu.org>2005-07-16 00:30:23 +0000
committerTom Tromey <tromey@gcc.gnu.org>2005-07-16 00:30:23 +0000
commitf911ba985aa7fe0096c386c5be385ac5825ea527 (patch)
treea0b991cf5866ae1d616639b906ac001811d74508 /libjava/classpath/gnu/java/awt
parent6f4434b39b261de5317dc81ddfdd94d2e1d62b11 (diff)
downloadgcc-f911ba985aa7fe0096c386c5be385ac5825ea527.zip
gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.tar.gz
gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.tar.bz2
Initial revision
From-SVN: r102074
Diffstat (limited to 'libjava/classpath/gnu/java/awt')
-rw-r--r--libjava/classpath/gnu/java/awt/AWTUtilities.java321
-rw-r--r--libjava/classpath/gnu/java/awt/BitMaskExtent.java79
-rw-r--r--libjava/classpath/gnu/java/awt/BitwiseXORComposite.java295
-rw-r--r--libjava/classpath/gnu/java/awt/Buffers.java243
-rw-r--r--libjava/classpath/gnu/java/awt/ClasspathToolkit.java379
-rw-r--r--libjava/classpath/gnu/java/awt/ComponentDataBlitOp.java156
-rw-r--r--libjava/classpath/gnu/java/awt/EmbeddedWindow.java139
-rw-r--r--libjava/classpath/gnu/java/awt/EventModifier.java107
-rw-r--r--libjava/classpath/gnu/java/awt/FocusManager.java52
-rw-r--r--libjava/classpath/gnu/java/awt/GradientPaintContext.java164
-rw-r--r--libjava/classpath/gnu/java/awt/color/CieXyzConverter.java73
-rw-r--r--libjava/classpath/gnu/java/awt/color/ClutProfileConverter.java152
-rw-r--r--libjava/classpath/gnu/java/awt/color/ColorLookUpTable.java429
-rw-r--r--libjava/classpath/gnu/java/awt/color/ColorSpaceConverter.java69
-rw-r--r--libjava/classpath/gnu/java/awt/color/GrayProfileConverter.java137
-rw-r--r--libjava/classpath/gnu/java/awt/color/GrayScaleConverter.java110
-rw-r--r--libjava/classpath/gnu/java/awt/color/LinearRGBConverter.java152
-rw-r--r--libjava/classpath/gnu/java/awt/color/ProfileHeader.java398
-rw-r--r--libjava/classpath/gnu/java/awt/color/PyccConverter.java72
-rw-r--r--libjava/classpath/gnu/java/awt/color/RgbProfileConverter.java244
-rw-r--r--libjava/classpath/gnu/java/awt/color/SrgbConverter.java152
-rw-r--r--libjava/classpath/gnu/java/awt/color/TagEntry.java121
-rw-r--r--libjava/classpath/gnu/java/awt/color/ToneReproductionCurve.java177
-rw-r--r--libjava/classpath/gnu/java/awt/color/package.html46
-rw-r--r--libjava/classpath/gnu/java/awt/doc-files/BitwiseXORComposite-1.pngbin0 -> 8845 bytes
-rw-r--r--libjava/classpath/gnu/java/awt/image/ImageDecoder.java156
-rw-r--r--libjava/classpath/gnu/java/awt/image/XBMDecoder.java155
-rw-r--r--libjava/classpath/gnu/java/awt/image/package.html46
-rw-r--r--libjava/classpath/gnu/java/awt/package.html46
-rw-r--r--libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java846
-rw-r--r--libjava/classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java104
-rw-r--r--libjava/classpath/gnu/java/awt/peer/EmbeddedWindowPeer.java47
-rw-r--r--libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java298
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GThreadMutex.java109
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java303
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java134
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java307
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkGlyphVector.java359
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java388
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java1453
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java138
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java107
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java681
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkRobotPeer.java94
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java115
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java434
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java107
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java100
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java86
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxMenuItemPeer.java69
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java128
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java130
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java170
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java651
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java156
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java94
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.java73
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java219
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkFontPeer.java225
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java256
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkGenericPeer.java98
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java494
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java155
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java84
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java180
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java80
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java63
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java120
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java103
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java70
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java74
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java113
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java80
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java212
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java196
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java653
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java118
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java212
-rw-r--r--libjava/classpath/gnu/java/awt/peer/gtk/package.html46
-rw-r--r--libjava/classpath/gnu/java/awt/peer/package.html46
80 files changed, 16248 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/java/awt/AWTUtilities.java b/libjava/classpath/gnu/java/awt/AWTUtilities.java
new file mode 100644
index 0000000..a02d1c4
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/AWTUtilities.java
@@ -0,0 +1,321 @@
+/* AWTUtilities.java -- Common utility methods for AWT and Swing.
+ Copyright (C) 2005 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;
+
+import java.awt.Component;
+import java.awt.Container;
+import java.util.AbstractSequentialList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.WeakHashMap;
+
+/**
+ * This class provides utility methods that are commonly used in AWT
+ * (and Swing).
+ */
+public class AWTUtilities
+{
+
+ /**
+ * This List implementation wraps the Component[] returned by
+ * {@link Container#getComponents()} and iterates over the visible Components
+ * in that array. This class is used in {@link #getVisibleChildren}.
+ */
+ static class VisibleComponentList extends AbstractSequentialList
+ {
+ /**
+ * The ListIterator for this List.
+ */
+ class VisibleComponentIterator implements ListIterator
+ {
+ /** The current index in the Component[]. */
+ int index;
+
+ /** The index in the List of visible Components. */
+ int listIndex;
+
+ /**
+ * Creates a new VisibleComponentIterator that starts at the specified
+ * <code>listIndex</code>. The array of Components is searched from
+ * the beginning to find the matching array index.
+ *
+ * @param listIndex the index from where to begin iterating
+ */
+ VisibleComponentIterator(int listIndex)
+ {
+ this.listIndex = listIndex;
+ int visibleComponentsFound = 0;
+ for (index = 0; visibleComponentsFound != listIndex; index++)
+ {
+ if (components[index].isVisible())
+ visibleComponentsFound++;
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if there are more visible components in the
+ * array, <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if there are more visible components in the
+ * array, <code>false</code> otherwise
+ */
+ public boolean hasNext()
+ {
+ boolean hasNext = false;
+ for (int i = index; i < components.length; i++)
+ {
+ if (components[i].isVisible())
+ {
+ hasNext = true;
+ break;
+ }
+ }
+ return hasNext;
+ }
+
+ /**
+ * Returns the next visible <code>Component</code> in the List.
+ *
+ * @return the next visible <code>Component</code> in the List
+ *
+ * @throws if there is no next element
+ */
+ public Object next()
+ {
+ Object o = null;
+ for (; index < components.length; index++)
+ {
+ if (components[index].isVisible())
+ {
+ o = components[index];
+ break;
+ }
+ }
+ if (o != null)
+ {
+ index++;
+ listIndex++;
+ return o;
+ }
+ else
+ throw new NoSuchElementException();
+ }
+
+ /**
+ * Returns <code>true</code> if there are more visible components in the
+ * array in the reverse direction, <code>false</code> otherwise.
+ *
+ * @return <code>true</code> if there are more visible components in the
+ * array in the reverse direction, <code>false</code> otherwise
+ */
+ public boolean hasPrevious()
+ {
+ boolean hasPrevious = false;
+ for (int i = index - 1; i >= 0; i--)
+ {
+ if (components[i].isVisible())
+ {
+ hasPrevious = true;
+ break;
+ }
+ }
+ return hasPrevious;
+ }
+
+ /**
+ * Returns the previous visible <code>Component</code> in the List.
+ *
+ * @return the previous visible <code>Component</code> in the List
+ *
+ * @throws NoSuchElementException if there is no previous element
+ */
+ public Object previous()
+ {
+ Object o = null;
+ for (index--; index >= 0; index--)
+ {
+ if (components[index].isVisible())
+ {
+ o = components[index];
+ break;
+ }
+ }
+ if (o != null)
+ {
+ listIndex--;
+ return o;
+ }
+ else
+ throw new NoSuchElementException();
+ }
+
+ /**
+ * Returns the index of the next element in the List.
+ *
+ * @return the index of the next element in the List
+ */
+ public int nextIndex()
+ {
+ return listIndex + 1;
+ }
+
+ /**
+ * Returns the index of the previous element in the List.
+ *
+ * @return the index of the previous element in the List
+ */
+ public int previousIndex()
+ {
+ return listIndex - 1;
+ }
+
+ /**
+ * This operation is not supported because the List is immutable.
+ *
+ * @throws UnsupportedOperationException because the List is immutable
+ */
+ public void remove()
+ {
+ throw new UnsupportedOperationException
+ ("VisibleComponentList is immutable");
+ }
+
+ /**
+ * This operation is not supported because the List is immutable.
+ *
+ * @param o not used here
+ *
+ * @throws UnsupportedOperationException because the List is immutable
+ */
+ public void set(Object o)
+ {
+ throw new UnsupportedOperationException
+ ("VisibleComponentList is immutable");
+ }
+
+ /**
+ * This operation is not supported because the List is immutable.
+ *
+ * @param o not used here
+ *
+ * @throws UnsupportedOperationException because the List is immutable
+ */
+ public void add(Object o)
+ {
+ throw new UnsupportedOperationException
+ ("VisibleComponentList is immutable");
+ }
+ }
+
+ /**
+ * The components over which we iterate. Only the visible components
+ * are returned by this List.
+ */
+ Component[] components;
+
+ /**
+ * Creates a new instance of VisibleComponentList that wraps the specified
+ * <code>Component[]</code>.
+ *
+ * @param c the <code>Component[]</code> to be wrapped.
+ */
+ VisibleComponentList(Component[] c)
+ {
+ components = c;
+ }
+
+ /**
+ * Returns a {@link ListIterator} for iterating over this List.
+ *
+ * @return a {@link ListIterator} for iterating over this List
+ */
+ public ListIterator listIterator(int index)
+ {
+ return new VisibleComponentIterator(index);
+ }
+
+ /**
+ * Returns the number of visible components in the wrapped Component[].
+ *
+ * @return the number of visible components
+ */
+ public int size()
+ {
+ int visibleComponents = 0;
+ for (int i = 0; i < components.length; i++)
+ if (components[i].isVisible())
+ visibleComponents++;
+ return visibleComponents;
+ }
+ }
+
+ /**
+ * The cache for our List instances. We try to hold one instance of
+ * VisibleComponentList for each Component[] that is requested. Note
+ * that we use a WeakHashMap for caching, so that the cache itself
+ * does not keep the array or the List from beeing garbage collected
+ * if no other objects hold references to it.
+ */
+ static WeakHashMap visibleChildrenCache = new WeakHashMap();
+
+ /**
+ * Returns the visible children of a {@link Container}. This method is
+ * commonly needed in LayoutManagers, because they only have to layout
+ * the visible children of a Container.
+ *
+ * @param c the Container from which to extract the visible children
+ *
+ * @return the visible children of <code>c</code>
+ */
+ public static List getVisibleChildren(Container c)
+ {
+ Component[] children = c.getComponents();
+ Object o = visibleChildrenCache.get(children);
+ VisibleComponentList visibleChildren = null;
+ if (o == null)
+ {
+ visibleChildren = new VisibleComponentList(children);
+ visibleChildrenCache.put(children, visibleChildren);
+ }
+ else
+ visibleChildren = (VisibleComponentList) o;
+
+ return visibleChildren;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/BitMaskExtent.java b/libjava/classpath/gnu/java/awt/BitMaskExtent.java
new file mode 100644
index 0000000..2813499
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/BitMaskExtent.java
@@ -0,0 +1,79 @@
+/* Copyright (C) 2000, 2002 Free Software Foundation
+
+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;
+
+/**
+ * Simple transparent utility class that can be used to perform bit
+ * mask extent calculations.
+ */
+public final class BitMaskExtent
+{
+ /** The number of the least significant bit of the bit mask extent. */
+ public byte leastSignificantBit;
+
+ /** The number of bits in the bit mask extent. */
+ public byte bitWidth;
+
+ /**
+ * Set the bit mask. This will calculate and set the leastSignificantBit
+ * and bitWidth fields.
+ *
+ * @see #leastSignificantBit
+ * @see #bitWidth
+ */
+ public void setMask(long mask)
+ {
+ leastSignificantBit = 0;
+ bitWidth = 0;
+ if (mask == 0) return;
+ long shiftMask = mask;
+ for (; (shiftMask&1) == 0; shiftMask >>>=1) leastSignificantBit++;
+ for (; (shiftMask&1) != 0; shiftMask >>>=1) bitWidth++;
+
+ if (shiftMask != 0)
+ throw new IllegalArgumentException("mask must be continuous");
+ }
+
+ /**
+ * Calculate the bit mask based on the values of the
+ * leastSignificantBit and bitWidth fields.
+ */
+ public long toMask()
+ {
+ return ((1<<bitWidth)-1) << leastSignificantBit;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/BitwiseXORComposite.java b/libjava/classpath/gnu/java/awt/BitwiseXORComposite.java
new file mode 100644
index 0000000..b568e11
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/BitwiseXORComposite.java
@@ -0,0 +1,295 @@
+/* BitwiseXORComposite.java -- Composite for emulating old-style XOR.
+ Copyright (C) 2003, 2004 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;
+
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+
+
+/**
+ * A composite for emulating traditional bitwise XOR of pixel values.
+ * Please note that this composite does <i>not</i> implement the Porter-Duff
+ * XOR operator, but an exclusive or of overlapping subpixel regions.
+ *
+ * <p><img src="doc-files/BitwiseXORComposite-1.png" width="545"
+ * height="138" alt="A screen shot of BitwiseXORComposite in action"
+ * />
+ *
+ * <p>The above screen shot shows the result of applying six different
+ * BitwiseXORComposites. They were constructed with the colors colors
+ * white, blue, black, orange, green, and brown, respectively. Each
+ * composite was used to paint a fully white rectangle on top of the
+ * blue bar in the background.
+ *
+ * <p>The purpose of this composite is to support the {@link
+ * Graphics#setXORMode(Color)} method in composite-aware graphics
+ * implementations. Applications typically would use
+ * <code>setXORMode</code> for drawing &#x201c;highlights&#x201d; such
+ * as text selections or cursors by inverting colors temporarily and
+ * then inverting them back.
+ *
+ * <p>A concrete <code>Graphics</code> implementation may contain
+ * the following code:
+ *
+ * <p><pre> public void setXORMode(Color xorColor)
+ * {
+ * setComposite(new gnu.java.awt.BitwiseXORComposite(xorColor));
+ * }
+ *
+ * public void setPaintMode()
+ * {
+ * setComposite(java.awt.AlphaComposite.SrcOver);
+ * }</pre>
+ *
+ * @author Graydon Hoare (graydon@redhat.com)
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public class BitwiseXORComposite
+ implements Composite
+{
+ /**
+ * The color whose RGB value is xor-ed with the values of each
+ * pixel.
+ */
+ protected Color xorColor;
+
+
+ /**
+ * Constructs a new composite for xor-ing the pixel value.
+ *
+ * @param xorColor the color whose pixel value will be bitwise
+ * xor-ed with the source and destination pixels.
+ */
+ public BitwiseXORComposite(Color xorColor)
+ {
+ this.xorColor = xorColor;
+ }
+
+
+ /**
+ * Creates a context object for performing the compositing
+ * operation. Several contexts may co-exist for one composite; each
+ * context may simultaneously be called from concurrent threads.
+ *
+ * @param srcColorModel the color model of the source.
+ * @param dstColorModel the color model of the destination.
+ * @param hints hints for choosing between rendering alternatives.
+ */
+ public CompositeContext createContext(ColorModel srcColorModel,
+ ColorModel dstColorModel,
+ RenderingHints hints)
+ {
+ if (IntContext.isSupported(srcColorModel, dstColorModel, hints))
+ return new IntContext(srcColorModel, xorColor);
+
+ return new GeneralContext(srcColorModel, dstColorModel, xorColor);
+ }
+
+
+ /**
+ * A fallback CompositeContext that performs bitwise XOR of pixel
+ * values with the pixel value of the specified <code>xorColor</code>.
+ *
+ * <p>Applying this CompositeContext on a 1024x1024 BufferedImage of
+ * <code>TYPE_INT_RGB</code> took 611 ms on a lightly loaded 2.4 GHz
+ * Intel Pentium 4 CPU running Sun J2SE 1.4.1_01 on GNU/Linux
+ * 2.4.20. The timing is the average of ten runs on the same
+ * BufferedImage. Since the measurements were taken with {@link
+ * System#currentTimeMillis()}, they are rather inaccurate.
+ *
+ * @author Graydon Hoare (graydon@redhat.com)
+ */
+ private static class GeneralContext
+ implements CompositeContext
+ {
+ ColorModel srcColorModel;
+ ColorModel dstColorModel;
+ Color xorColor;
+
+ public GeneralContext(ColorModel srcColorModel,
+ ColorModel dstColorModel,
+ Color xorColor)
+ {
+ this.srcColorModel = srcColorModel;
+ this.dstColorModel = dstColorModel;
+ this.xorColor = xorColor;
+ }
+
+
+ public void compose(Raster src, Raster dstIn, WritableRaster dstOut)
+ {
+ Rectangle srcRect = src.getBounds();
+ Rectangle dstInRect = dstIn.getBounds();
+ Rectangle dstOutRect = dstOut.getBounds();
+
+ int xp = xorColor.getRGB();
+ int w = Math.min(Math.min(srcRect.width, dstOutRect.width),
+ dstInRect.width);
+ int h = Math.min(Math.min(srcRect.height, dstOutRect.height),
+ dstInRect.height);
+
+ Object srcPix = null, dstPix = null, rpPix = null;
+
+ // Re-using the rpPix object saved 1-2% of execution time in
+ // the 1024x1024 pixel benchmark.
+
+ for (int y = 0; y < h; y++)
+ {
+ for (int x = 0; x < w; x++)
+ {
+ srcPix = src.getDataElements(x + srcRect.x, y + srcRect.y, srcPix);
+ dstPix = dstIn.getDataElements(x + dstInRect.x, y + dstInRect.y,
+ dstPix);
+ int sp = srcColorModel.getRGB(srcPix);
+ int dp = dstColorModel.getRGB(dstPix);
+ int rp = sp ^ xp ^ dp;
+ dstOut.setDataElements(x + dstOutRect.x, y + dstOutRect.y,
+ dstColorModel.getDataElements(rp, rpPix));
+ }
+ }
+ }
+
+
+ /**
+ * Disposes any cached resources. The default implementation does
+ * nothing because no resources are cached.
+ */
+ public void dispose()
+ {
+ }
+ }
+
+
+ /**
+ * An optimized CompositeContext that performs bitwise XOR of
+ * <code>int</code> pixel values with the pixel value of a specified
+ * <code>xorColor</code>. This CompositeContext working only for
+ * rasters whose transfer format is {@link DataBuffer#TYPE_INT}.
+ *
+ * <p>Applying this CompositeContext on a 1024x1024 BufferedImage of
+ * <code>TYPE_INT_RGB</code> took 69 ms on a lightly loaded 2.4 GHz
+ * Intel Pentium 4 CPU running Sun J2SE 1.4.1_01 on GNU/Linux
+ * 2.4.20. The timing is the average of ten runs on the same
+ * BufferedImage. Since the measurements were taken with {@link
+ * System#currentTimeMillis()}, they are rather inaccurate.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+ private static class IntContext
+ extends GeneralContext
+ {
+ public IntContext(ColorModel colorModel, Color xorColor)
+ {
+ super(colorModel, colorModel, xorColor);
+ }
+
+
+ public void compose(Raster src, Raster dstIn,
+ WritableRaster dstOut)
+ {
+ int aX, bX, dstX, aY, bY, dstY, width, height;
+ int xorPixel;
+ int[] srcLine, dstLine;
+
+ aX = src.getMinX();
+ aY = src.getMinY();
+ bX = dstIn.getMinX();
+ bY = dstIn.getMinY();
+ dstX = dstOut.getMinX();
+ dstY = dstOut.getMinY();
+ width = Math.min(Math.min(src.getWidth(), dstIn.getWidth()),
+ dstOut.getWidth());
+ height = Math.min(Math.min(src.getHeight(), dstIn.getHeight()),
+ dstOut.getHeight());
+ if ((width < 1) || (height < 1))
+ return;
+
+ srcLine = new int[width];
+ dstLine = new int[width];
+
+ /* We need an int[] array with at least one element here;
+ * srcLine is as good as any other.
+ */
+ srcColorModel.getDataElements(this.xorColor.getRGB(), srcLine);
+ xorPixel = srcLine[0];
+
+ for (int y = 0; y < height; y++)
+ {
+ src.getDataElements(aX, y + aY, width, 1, srcLine);
+ dstIn.getDataElements(bX, y + bY, width, 1, dstLine);
+
+ for (int x = 0; x < width; x++)
+ dstLine[x] ^= srcLine[x] ^ xorPixel;
+
+ dstOut.setDataElements(dstX, y + dstY, width, 1, dstLine);
+ }
+ }
+
+
+ /**
+ * Determines whether an instance of this CompositeContext would
+ * be able to process the specified color models.
+ */
+ public static boolean isSupported(ColorModel srcColorModel,
+ ColorModel dstColorModel,
+ RenderingHints hints)
+ {
+ // FIXME: It would be good if someone could review these checks.
+ // They probably need to be more restrictive.
+
+ int transferType;
+
+ transferType = srcColorModel.getTransferType();
+ if (transferType != dstColorModel.getTransferType())
+ return false;
+
+ if (transferType != DataBuffer.TYPE_INT)
+ return false;
+
+ return true;
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/Buffers.java b/libjava/classpath/gnu/java/awt/Buffers.java
new file mode 100644
index 0000000..c6ccf91
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/Buffers.java
@@ -0,0 +1,243 @@
+/* Buffers.java --
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
+
+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;
+
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferDouble;
+import java.awt.image.DataBufferFloat;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.DataBufferUShort;
+
+/**
+ * Utility class for creating and accessing data buffers of arbitrary
+ * data types.
+ */
+public final class Buffers
+{
+ /**
+ * Create a data buffer of a particular type.
+ *
+ * @param dataType the desired data type of the buffer.
+ * @param data an array containing data, or null
+ * @param size the size of the data buffer bank
+ */
+ public static DataBuffer createBuffer(int dataType, Object data,
+ int size)
+ {
+ if (data == null) return createBuffer(dataType, size, 1);
+
+ return createBufferFromData(dataType, data, size);
+ }
+
+
+ /**
+ * Create a data buffer of a particular type.
+ *
+ * @param dataType the desired data type of the buffer.
+ * @param size the size of the data buffer bank
+ */
+ public static DataBuffer createBuffer(int dataType, int size) {
+ return createBuffer(dataType, size, 1);
+ }
+
+ /**
+ * Create a data buffer of a particular type.
+ *
+ * @param dataType the desired data type of the buffer.
+ * @param size the size of the data buffer bank
+ * @param numBanks the number of banks the buffer should have
+ */
+ public static DataBuffer createBuffer(int dataType, int size, int numBanks)
+ {
+ switch (dataType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ return new DataBufferByte(size, numBanks);
+ case DataBuffer.TYPE_SHORT:
+ return new DataBufferShort(size, numBanks);
+ case DataBuffer.TYPE_USHORT:
+ return new DataBufferUShort(size, numBanks);
+ case DataBuffer.TYPE_INT:
+ return new DataBufferInt(size, numBanks);
+ case DataBuffer.TYPE_FLOAT:
+ return new DataBufferFloat(size, numBanks);
+ case DataBuffer.TYPE_DOUBLE:
+ return new DataBufferDouble(size, numBanks);
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Create a data buffer of a particular type.
+ *
+ * @param dataType the desired data type of the buffer
+ * @param data an array containing the data
+ * @param size the size of the data buffer bank
+ */
+ public static DataBuffer createBufferFromData(int dataType, Object data,
+ int size)
+ {
+ switch (dataType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ return new DataBufferByte((byte[]) data, size);
+ case DataBuffer.TYPE_SHORT:
+ return new DataBufferShort((short[]) data, size);
+ case DataBuffer.TYPE_USHORT:
+ return new DataBufferUShort((short[]) data, size);
+ case DataBuffer.TYPE_INT:
+ return new DataBufferInt((int[]) data, size);
+ case DataBuffer.TYPE_FLOAT:
+ return new DataBufferFloat((float[]) data, size);
+ case DataBuffer.TYPE_DOUBLE:
+ return new DataBufferDouble((double[]) data, size);
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Return the data array of a data buffer, regardless of the data
+ * type.
+ *
+ * @return an array of primitive values. The actual array type
+ * depends on the data type of the buffer.
+ */
+ public static Object getData(DataBuffer buffer)
+ {
+ if (buffer instanceof DataBufferByte)
+ return ((DataBufferByte) buffer).getData();
+
+ if (buffer instanceof DataBufferShort)
+ return ((DataBufferShort) buffer).getData();
+
+ if (buffer instanceof DataBufferUShort)
+ return ((DataBufferUShort) buffer).getData();
+
+ if (buffer instanceof DataBufferInt)
+ return ((DataBufferInt) buffer).getData();
+
+ if (buffer instanceof DataBufferFloat)
+ return ((DataBufferFloat) buffer).getData();
+
+ if (buffer instanceof DataBufferDouble)
+ return ((DataBufferDouble) buffer).getData();
+
+ throw new ClassCastException("Unknown data buffer type");
+ }
+
+
+ /**
+ * Copy data from array contained in data buffer, much like
+ * System.arraycopy. Create a suitable destination array if the
+ * given destination array is null.
+ */
+ public static Object getData(DataBuffer src, int srcOffset,
+ Object dest, int destOffset,
+ int length)
+ {
+ Object from;
+ if (src instanceof DataBufferByte)
+ {
+ from = ((DataBufferByte) src).getData();
+ if (dest == null) dest = new byte[length+destOffset];
+ }
+ else if (src instanceof DataBufferShort)
+ {
+ from = ((DataBufferShort) src).getData();
+ if (dest == null) dest = new short[length+destOffset];
+ }
+ else if (src instanceof DataBufferUShort)
+ {
+ from = ((DataBufferUShort) src).getData();
+ if (dest == null) dest = new short[length+destOffset];
+ }
+ else if (src instanceof DataBufferInt)
+ {
+ from = ((DataBufferInt) src).getData();
+ if (dest == null) dest = new int[length+destOffset];
+ }
+ else if (src instanceof DataBufferFloat)
+ {
+ from = ((DataBufferFloat) src).getData();
+ if (dest == null) dest = new float[length+destOffset];
+ }
+ else if (src instanceof DataBufferDouble)
+ {
+ from = ((DataBufferDouble) src).getData();
+ if (dest == null) dest = new double[length+destOffset];
+ }
+ else
+ {
+ throw new ClassCastException("Unknown data buffer type");
+ }
+
+ System.arraycopy(from, srcOffset, dest, destOffset, length);
+ return dest;
+ }
+
+ /**
+ * @param bits the width of a data element measured in bits
+ *
+ * @return the smallest data type that can store data elements of
+ * the given number of bits, without any truncation.
+ */
+ public static int smallestAppropriateTransferType(int bits)
+ {
+ if (bits <= 8)
+ {
+ return DataBuffer.TYPE_BYTE;
+ }
+ else if (bits <= 16)
+ {
+ return DataBuffer.TYPE_USHORT;
+ }
+ else if (bits <= 32)
+ {
+ return DataBuffer.TYPE_INT;
+ }
+ else
+ {
+ return DataBuffer.TYPE_UNDEFINED;
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/ClasspathToolkit.java b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java
new file mode 100644
index 0000000..5fb444f
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java
@@ -0,0 +1,379 @@
+/* ClasspathToolkit.java -- Abstract superclass for Classpath toolkits.
+ Copyright (C) 2003, 2004 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;
+
+import gnu.java.awt.EmbeddedWindow;
+import gnu.java.awt.peer.ClasspathFontPeer;
+import gnu.java.awt.peer.EmbeddedWindowPeer;
+import gnu.java.awt.peer.ClasspathTextLayoutPeer;
+
+import java.awt.AWTException;
+import java.awt.Dimension;
+import java.awt.DisplayMode;
+import java.awt.EventQueue;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.font.FontRenderContext;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageProducer;
+import java.awt.peer.RobotPeer;
+import java.io.File;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.AttributedString;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.imageio.spi.IIORegistry;
+
+/**
+ * An abstract superclass for Classpath toolkits.
+ *
+ * <p>There exist some parts of AWT and Java2D that are specific to
+ * the underlying platform, but for which the {@link Toolkit} class
+ * does not provide suitable abstractions. Examples include some
+ * methods of {@link Font} or {@link GraphicsEnvironment}. Those
+ * methods use ClasspathToolkit as a central place for obtaining
+ * platform-specific functionality.
+ *
+ * <p>In addition, ClasspathToolkit implements some abstract methods
+ * of {@link java.awt.Toolkit} that are not really platform-specific,
+ * such as the maintenance of a cache of loaded images.
+ *
+ * <p><b>Thread Safety:</b> The methods of this class may safely be
+ * called without external synchronization. This also hold for any
+ * inherited {@link Toolkit} methods. Subclasses are responsible for
+ * the necessary synchronization.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public abstract class ClasspathToolkit
+ extends Toolkit
+{
+ /**
+ * A map from URLs to previously loaded images, used by {@link
+ * #getImage(java.net.URL)}. For images that were loaded via a path
+ * to an image file, the map contains a key with a file URL.
+ */
+ private HashMap imageCache;
+
+
+ /**
+ * Returns a shared instance of the local, platform-specific
+ * graphics environment.
+ *
+ * <p>This method is specific to GNU Classpath. It gets called by
+ * the Classpath implementation of {@link
+ * GraphicsEnvironment.getLocalGraphcisEnvironment()}.
+ */
+ public abstract GraphicsEnvironment getLocalGraphicsEnvironment();
+
+
+ /**
+ * Determines the current size of the default, primary screen.
+ *
+ * @throws HeadlessException if the local graphics environment is
+ * headless, which means that no screen is attached and no user
+ * interaction is allowed.
+ */
+ public Dimension getScreenSize()
+ {
+ DisplayMode mode;
+
+ // getDefaultScreenDevice throws HeadlessException if the
+ // local graphics environment is headless.
+ mode = GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDisplayMode();
+
+ return new Dimension(mode.getWidth(), mode.getHeight());
+ }
+
+
+ /**
+ * Determines the current color model of the default, primary
+ * screen.
+ *
+ * @see GraphicsEnvironment#getDefaultScreenDevice()
+ * @see java.awt.GraphicsDevice#getDefaultConfiguration()
+ * @see java.awt.GraphicsConfiguration#getColorModel()
+ *
+ * @throws HeadlessException if the local graphics environment is
+ * headless, which means that no screen is attached and no user
+ * interaction is allowed.
+ */
+ public ColorModel getColorModel()
+ {
+ // getDefaultScreenDevice throws HeadlessException if the
+ // local graphics environment is headless.
+ return GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDefaultConfiguration()
+ .getColorModel();
+ }
+
+ /**
+ * Retrieves the metrics for rendering a font on the screen.
+ *
+ * @param font the font whose metrics are requested.
+ */
+ public FontMetrics getFontMetrics(Font font)
+ {
+ return ((ClasspathFontPeer) font.getPeer ()).getFontMetrics (font);
+ }
+
+
+ /**
+ * Acquires an appropriate {@link ClasspathFontPeer}, for use in
+ * classpath's implementation of {@link java.awt.Font}.
+ *
+ * @param name The logical name of the font. This may be either a face
+ * name or a logical font name, or may even be null. A default
+ * implementation of name decoding is provided in
+ * {@link ClasspathFontPeer}, but may be overridden in other toolkits.
+ *
+ * @param attrs Any extra {@link java.awt.font.TextAttribute} attributes
+ * this font peer should have, such as size, weight, family name, or
+ * transformation.
+ */
+ public abstract ClasspathFontPeer getClasspathFontPeer (String name, Map attrs);
+
+ public abstract ClasspathTextLayoutPeer
+ getClasspathTextLayoutPeer (AttributedString str, FontRenderContext frc);
+
+
+ /**
+ * Creates a {@link Font}, in a platform-specific manner.
+ *
+ * The default implementation simply constructs a {@link Font}, but some
+ * toolkits may wish to override this, to return {@link Font} subclasses which
+ * implement {@link java.awt.font.OpenType} or
+ * {@link java.awt.font.MultipleMaster}.
+ */
+ public Font getFont (String name, Map attrs)
+ {
+ return new Font (name, attrs);
+ }
+
+
+ /**
+ * Creates a font, reading the glyph definitions from a stream.
+ *
+ * <p>This method provides the platform-specific implementation for
+ * the static factory method {@link Font#createFont(int,
+ * java.io.InputStream)}.
+ *
+ * @param format the format of the font data, such as {@link
+ * Font#TRUETYPE_FONT}. An implementation may ignore this argument
+ * if it is able to automatically recognize the font format from the
+ * provided data.
+ *
+ * @param stream an input stream from where the font data is read
+ * in. The stream will be advanced to the position after the font
+ * data, but not closed.
+ *
+ * @throws IllegalArgumentException if <code>format</code> is
+ * not supported.
+ *
+ * @throws FontFormatException if <code>stream</code> does not
+ * contain data in the expected format, or if required tables are
+ * missing from a font.
+ *
+ * @throws IOException if a problem occurs while reading in the
+ * contents of <code>stream</code>.
+ */
+ public abstract Font createFont(int format, InputStream stream);
+
+
+ /**
+ * Returns an image from the specified file, which must be in a
+ * recognized format. The set of recognized image formats may vary
+ * from toolkit to toolkit.
+ *
+ * <p>This method maintains a cache for images. If an image has been
+ * loaded from the same path before, the cached copy will be
+ * returned. The implementation may hold cached copies for an
+ * indefinite time, which can consume substantial resources with
+ * large images. Users are therefore advised to use {@link
+ * #createImage(java.lang.String)} instead.
+ *
+ * <p>The default implementation creates a file URL for the
+ * specified path and invokes {@link #getImage(URL)}.
+ *
+ * @param path A path to the image file.
+ *
+ * @return IllegalArgumentException if <code>path</code> does not
+ * designate a valid path.
+ */
+ public Image getImage(String path)
+ {
+ try
+ {
+ return getImage(new File(path).toURL());
+ }
+ catch (MalformedURLException muex)
+ {
+ throw (IllegalArgumentException) new IllegalArgumentException(path)
+ .initCause(muex);
+ }
+ }
+
+
+ /**
+ * Loads an image from the specified URL. The image data must be in
+ * a recognized format. The set of recognized image formats may vary
+ * from toolkit to toolkit.
+ *
+ * <p>This method maintains a cache for images. If an image has been
+ * loaded from the same URL before, the cached copy will be
+ * returned. The implementation may hold cached copies for an
+ * indefinite time, which can consume substantial resources with
+ * large images. Users are therefore advised to use {@link
+ * #createImage(java.net.URL)} instead.
+ *
+ * @param url the URL from where the image is read.
+ */
+ public Image getImage(URL url)
+ {
+ Image result;
+
+ synchronized (this)
+ {
+ // Many applications never call getImage. Therefore, we lazily
+ // create the image cache when it is actually needed.
+ if (imageCache == null)
+ imageCache = new HashMap();
+ else
+ {
+ result = (Image) imageCache.get(url);
+ if (result != null)
+ return result;
+ }
+
+ // The createImage(URL) method, which is specified by
+ // java.awt.Toolkit, is not implemented by this abstract class
+ // because it is platform-dependent. Once Classpath has support
+ // for the javax.imageio package, it might be worth considering
+ // that toolkits provide native stream readers. Then, the class
+ // ClasspathToolkit could provide a general implementation that
+ // delegates the image format parsing to javax.imageio.
+ result = createImage(url);
+
+ // It is not clear whether it would be a good idea to use weak
+ // references here. The advantage would be reduced memory
+ // consumption, since loaded images would not be kept
+ // forever. But on VMs that frequently perform garbage
+ // collection (which includes VMs with a parallel or incremental
+ // collector), the image might frequently need to be re-loaded,
+ // possibly over a slow network connection.
+ imageCache.put(url, result);
+
+ return result;
+ }
+ }
+
+
+ /**
+ * Returns an image from the specified file, which must be in a
+ * recognized format. The set of recognized image formats may vary
+ * from toolkit to toolkit.
+ *
+ * <p>A new image is created every time this method gets called,
+ * even if the same path has been passed before.
+ *
+ * <p>The default implementation creates a file URL for the
+ * specified path and invokes {@link #createImage(URL)}.
+ *
+ * @param path A path to the file to be read in.
+ */
+ public Image createImage(String path)
+ {
+ try
+ {
+ // The abstract method createImage(URL) is defined by
+ // java.awt.Toolkit, but intentionally not implemented by
+ // ClasspathToolkit because it is platform specific.
+ return createImage(new File(path).toURL());
+ }
+ catch (MalformedURLException muex)
+ {
+ throw (IllegalArgumentException) new IllegalArgumentException(path)
+ .initCause(muex);
+ }
+ }
+
+ /**
+ * Creates an ImageProducer from the specified URL. The image is assumed
+ * to be in a recognised format. If the toolkit does not implement the
+ * image format or the image format is not recognised, null is returned.
+ * This default implementation is overriden by the Toolkit implementations.
+ *
+ * @param url URL to read image data from.
+ */
+ public ImageProducer createImageProducer(URL url)
+ {
+ return null;
+ }
+
+ public abstract RobotPeer createRobot (GraphicsDevice screen)
+ throws AWTException;
+
+ /**
+ * Creates an embedded window peer, and associates it with an
+ * EmbeddedWindow object.
+ *
+ * @param w The embedded window with which to associate a peer.
+ */
+ public abstract EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w);
+
+ /**
+ * Used to register ImageIO SPIs provided by the toolkit.
+ */
+
+ public void registerImageIOSpis(IIORegistry reg)
+ {
+ }
+
+ public abstract boolean nativeQueueEmpty();
+ public abstract void wakeNativeQueue();
+ public abstract void iterateNativeQueue(EventQueue locked, boolean block);
+}
diff --git a/libjava/classpath/gnu/java/awt/ComponentDataBlitOp.java b/libjava/classpath/gnu/java/awt/ComponentDataBlitOp.java
new file mode 100644
index 0000000..545427e
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/ComponentDataBlitOp.java
@@ -0,0 +1,156 @@
+/* Copyright (C) 2000, 2002, 2004 Free Software Foundation
+
+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;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ComponentSampleModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.RasterOp;
+import java.awt.image.WritableRaster;
+
+/**
+ * This raster copy operation assumes that both source and destination
+ * sample models are tightly pixel packed and contain the same number
+ * of bands.
+ *
+ * @throws java.lang.ClassCastException if the sample models of the
+ * rasters are not of type ComponentSampleModel.
+ *
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ */
+public class ComponentDataBlitOp implements RasterOp
+{
+ public static final ComponentDataBlitOp INSTANCE = new ComponentDataBlitOp();
+
+ public WritableRaster filter(Raster src, WritableRaster dest)
+ {
+ if (dest == null)
+ dest = createCompatibleDestRaster(src);
+
+ DataBuffer srcDB = src.getDataBuffer();
+ DataBuffer destDB = dest.getDataBuffer();
+
+ ComponentSampleModel srcSM = (ComponentSampleModel) src.getSampleModel();
+ ComponentSampleModel destSM = (ComponentSampleModel) dest.getSampleModel();
+
+
+ // Calculate offset to data in the underlying arrays:
+
+ int srcScanlineStride = srcSM.getScanlineStride();
+ int destScanlineStride = destSM.getScanlineStride();
+ int srcX = src.getMinX() - src.getSampleModelTranslateX();
+ int srcY = src.getMinY() - src.getSampleModelTranslateY();
+ int destX = dest.getMinX() - dest.getSampleModelTranslateX();
+ int destY = dest.getMinY() - dest.getSampleModelTranslateY();
+
+ int numBands = srcSM.getNumBands();
+
+ /* We can't use getOffset(x, y) from the sample model since we
+ don't want the band offset added in. */
+
+ int srcOffset =
+ numBands*srcX + srcScanlineStride*srcY + // from sample model
+ srcDB.getOffset(); // from data buffer
+
+ int destOffset =
+ numBands*destX + destScanlineStride*destY + // from sample model
+ destDB.getOffset(); // from data buffer
+
+ // Determine how much, and how many times to blit.
+
+ int rowSize = src.getWidth()*numBands;
+ int h = src.getHeight();
+
+ if ((rowSize == srcScanlineStride) &&
+ (rowSize == destScanlineStride))
+ {
+ // collapse scan line blits to one large blit.
+ rowSize *= h;
+ h = 1;
+ }
+
+
+ // Do blitting
+
+ Object srcArray = Buffers.getData(srcDB);
+ Object destArray = Buffers.getData(destDB);
+
+ for (int yd = 0; yd<h; yd++)
+ {
+ System.arraycopy(srcArray, srcOffset,
+ destArray, destOffset,
+ rowSize);
+ srcOffset += srcScanlineStride;
+ destOffset += destScanlineStride;
+ }
+
+
+ return dest;
+ }
+
+ public Rectangle2D getBounds2D(Raster src)
+ {
+ return src.getBounds();
+ }
+
+ public WritableRaster createCompatibleDestRaster(Raster src) {
+
+ /* FIXME: Maybe we should explicitly create a raster with a
+ tightly pixel packed sample model, rather than assuming
+ that the createCompatibleWritableRaster() method in Raster
+ will create one. */
+
+ return src.createCompatibleWritableRaster();
+ }
+
+ public Point2D getPoint2D(Point2D srcPoint, Point2D destPoint)
+ {
+ if (destPoint == null)
+ return (Point2D) srcPoint.clone();
+
+ destPoint.setLocation(srcPoint);
+ return destPoint;
+ }
+
+ public RenderingHints getRenderingHints()
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/EmbeddedWindow.java b/libjava/classpath/gnu/java/awt/EmbeddedWindow.java
new file mode 100644
index 0000000..a85ce74
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/EmbeddedWindow.java
@@ -0,0 +1,139 @@
+/* EmbeddedWindow.java --
+ Copyright (C) 2003, 2004 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;
+
+import gnu.java.awt.peer.EmbeddedWindowPeer;
+import gnu.java.security.action.SetAccessibleAction;
+
+import java.awt.Component;
+import java.awt.Frame;
+import java.awt.Toolkit;
+import java.lang.reflect.Field;
+import java.security.AccessController;
+
+/**
+ * Represents an AWT window that can be embedded into another
+ * application.
+ *
+ * @author Michael Koch (konqueror@gmx.de)
+ */
+public class EmbeddedWindow extends Frame
+{
+ private long handle;
+
+ /**
+ * Creates a window to be embedded into another application. The
+ * window will only be embedded after its setHandle method has been
+ * called.
+ */
+ public EmbeddedWindow ()
+ {
+ super();
+ this.handle = 0;
+ }
+
+ /**
+ * Creates a window to be embedded into another application.
+ *
+ * @param handle the native handle to the screen area where the AWT
+ * window should be embedded
+ */
+ public EmbeddedWindow (long handle)
+ {
+ super();
+ this.handle = handle;
+ }
+
+ /**
+ * Creates the native peer for this embedded window.
+ */
+ public void addNotify()
+ {
+ // Assume we're using ClasspathToolkit
+ ClasspathToolkit tk = (ClasspathToolkit) getToolkit();
+
+ // Circumvent the package-privateness of the AWT internal
+ // java.awt.Component.peer member variable.
+ try
+ {
+ Field peerField = Component.class.getDeclaredField("peer");
+ AccessController.doPrivileged(new SetAccessibleAction(peerField));
+ peerField.set(this, tk.createEmbeddedWindow (this));
+ }
+ catch (IllegalAccessException e)
+ {
+ // This should never happen.
+ }
+ catch (NoSuchFieldException e)
+ {
+ // This should never happen.
+ }
+
+ super.addNotify();
+ }
+
+ /**
+ * If the native peer for this embedded window has been created,
+ * then setHandle will embed the window. If not, setHandle tells
+ * us where to embed ourselves when our peer is created.
+ *
+ * @param handle the native handle to the screen area where the AWT
+ * window should be embedded
+ */
+ public void setHandle(long handle)
+ {
+ if (this.handle != 0)
+ throw new RuntimeException ("EmbeddedWindow is already embedded");
+
+ this.handle = handle;
+ if (getPeer() != null)
+ ((EmbeddedWindowPeer) getPeer()).embed (this.handle);
+ }
+
+ /**
+ * Gets the native handle of the screen area where the window will
+ * be embedded.
+ *
+ * @return The native handle that was passed to the constructor.
+ */
+ public long getHandle()
+ {
+ return handle;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/EventModifier.java b/libjava/classpath/gnu/java/awt/EventModifier.java
new file mode 100644
index 0000000..565fcbc
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/EventModifier.java
@@ -0,0 +1,107 @@
+/* EventModifier.java -- tool for converting modifier bits to 1.4 syle
+ Copyright (C) 2002 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;
+
+import java.awt.event.InputEvent;
+
+public class EventModifier
+{
+ /** The mask for old events. */
+ public static final int OLD_MASK = 0x3f;
+
+ /** The mask for new events. */
+ public static final int NEW_MASK = 0x3fc0;
+
+ /**
+ * Non-instantiable.
+ */
+ private EventModifier()
+ {
+ throw new InternalError();
+ }
+
+ /**
+ * Converts the old style modifiers (0x3f) to the new style (0xffffffc0).
+ *
+ * @param mod the modifiers to convert
+ * @return the adjusted modifiers
+ */
+ public static int extend(int mod)
+ {
+ // Favor what we hope will be the common case.
+ if ((mod & OLD_MASK) == 0)
+ return mod;
+ if ((mod & InputEvent.SHIFT_MASK) != 0)
+ mod |= InputEvent.SHIFT_DOWN_MASK;
+ if ((mod & InputEvent.CTRL_MASK) != 0)
+ mod |= InputEvent.CTRL_DOWN_MASK;
+ if ((mod & InputEvent.META_MASK) != 0)
+ mod |= InputEvent.META_DOWN_MASK;
+ if ((mod & InputEvent.ALT_MASK) != 0)
+ mod |= InputEvent.ALT_DOWN_MASK;
+ if ((mod & InputEvent.BUTTON1_MASK) != 0)
+ mod |= InputEvent.BUTTON1_DOWN_MASK;
+ if ((mod & InputEvent.ALT_GRAPH_MASK) != 0)
+ mod |= InputEvent.ALT_GRAPH_DOWN_MASK;
+ return mod & ~OLD_MASK;
+ }
+
+ /**
+ * Converts the new style modifiers (0xffffffc0) to the old style (0x3f).
+ *
+ * @param mod the modifiers to convert
+ * @return the adjusted modifiers
+ */
+ public static int revert(int mod)
+ {
+ if ((mod & InputEvent.SHIFT_DOWN_MASK) != 0)
+ mod |= InputEvent.SHIFT_MASK;
+ if ((mod & InputEvent.CTRL_DOWN_MASK) != 0)
+ mod |= InputEvent.CTRL_MASK;
+ if ((mod & InputEvent.META_DOWN_MASK) != 0)
+ mod |= InputEvent.META_MASK;
+ if ((mod & InputEvent.ALT_DOWN_MASK) != 0)
+ mod |= InputEvent.ALT_MASK;
+ if ((mod & InputEvent.ALT_GRAPH_DOWN_MASK) != 0)
+ mod |= InputEvent.ALT_GRAPH_MASK;
+ if ((mod & InputEvent.BUTTON1_DOWN_MASK) != 0)
+ mod |= InputEvent.BUTTON1_MASK;
+ return mod & OLD_MASK;
+ }
+} // class EventModifier
diff --git a/libjava/classpath/gnu/java/awt/FocusManager.java b/libjava/classpath/gnu/java/awt/FocusManager.java
new file mode 100644
index 0000000..49b40bf
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/FocusManager.java
@@ -0,0 +1,52 @@
+/* FocusManager.java -- Provide Swing FocusManager API compatibility
+ Copyright (C) 2005 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;
+
+/**
+ * This is a subclass of the otherwise abstract class
+ * {@link javax.swing.FocusManager}. Its sole purpose is to make the Swing
+ * FocusManager usable as a FocusManager in AWT, so that we can provide both
+ * the new (1.4) KeyboardFocusManager API and still support the older
+ * Swing FocusManager.
+ *
+ * @author Roman Kennke
+ */
+public class FocusManager
+ extends javax.swing.FocusManager
+{
+}
diff --git a/libjava/classpath/gnu/java/awt/GradientPaintContext.java b/libjava/classpath/gnu/java/awt/GradientPaintContext.java
new file mode 100644
index 0000000..5e1d62d
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/GradientPaintContext.java
@@ -0,0 +1,164 @@
+/* GradientPaintContext.java --
+ Copyright (C) 2005, 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;
+
+import java.awt.geom.Point2D;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.awt.PaintContext;
+import java.awt.Color;
+
+/**
+ * A {@link PaintContext} used by the {@link GradientPaint} class.
+ */
+public class GradientPaintContext implements PaintContext
+{
+
+ // This implementation follows the technique described in
+ // "Java(tm) 2D Graphics" by Jonathan Knudsen (O'Reilly 1999).
+
+ /** The x-coordinate of the anchor point for color 1. */
+ private final float x1;
+
+ /** The y-coordinate of the anchor point for color 1. */
+ private final float y1;
+
+ /** Color 1. */
+ private final Color c1;
+
+ /** The x-coordinate of the anchor point for color 2. */
+ private final float x2;
+
+ /** The y-coordinate of the anchor point for color 2. */
+ private final float y2;
+
+ /** Color 2. */
+ private final Color c2;
+
+ /** A flag indicating whether the gradient is cyclic or acyclic. */
+ private final boolean cyclic;
+
+ /** The length of the gradient line - computed from the two anchor points. */
+ private final double length;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param x1 the x-coordinate for the anchor point for color 1.
+ * @param y1 the y-coordinate for the anchor point for color 1.
+ * @param c1 color 1.
+ * @param x2 the x-coordinate for the anchor point for color 2.
+ * @param y2 the y-coordinate for the anchor point for color 2.
+ * @param c2 color 2.
+ * @param cyclic a flag that determines whether the gradient is cyclic
+ * or acyclic.
+ */
+ public GradientPaintContext(float x1, float y1, Color c1,
+ float x2, float y2, Color c2, boolean cyclic)
+ {
+ this.x1 = x1;
+ this.y1 = y1;
+ this.c1 = c1;
+ this.x2 = x2;
+ this.y2 = y2;
+ this.c2 = c2;
+ this.cyclic = cyclic;
+ length = Point2D.distance(x1, y1, x2, y2);
+ }
+
+ /**
+ * Return the color model of this context. It may be different from the
+ * hint specified during createContext, as not all contexts can generate
+ * color patterns in an arbitrary model.
+ *
+ * @return the context color model
+ */
+ public ColorModel getColorModel()
+ {
+ return ColorModel.getRGBdefault();
+ }
+
+ /**
+ * Return a raster containing the colors for the graphics operation.
+ *
+ * @param x the x-coordinate, in device space
+ * @param y the y-coordinate, in device space
+ * @param w the width, in device space
+ * @param h the height, in device space
+ * @return a raster for the given area and color
+ */
+ public Raster getRaster(int x, int y, int w, int h) {
+ ColorModel cm = getColorModel();
+ WritableRaster raster = cm.createCompatibleWritableRaster(w, h);
+ int[] data = new int[w * h * 4];
+ double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
+ for (int r = 0; r < h; r++) {
+ for (int c = 0; c < w; c++) {
+ double u = 0.0;
+ if (pd2 != 0)
+ u = (((x + c) - x1) * (x2 - x1) + ((y + r) - y1) * (y2 - y1))
+ / Math.sqrt(pd2);
+ double ratio = u / length;
+ if (cyclic)
+ ratio = Math.abs(ratio - Math.floor((ratio + 1.0) / 2.0) * 2.0);
+ else
+ ratio = Math.max(0.0, Math.min(1.0, ratio));
+ int base = (r * w + c) * 4;
+ data[base] = (int) (c1.getRed() + ratio * (c2.getRed() - c1.getRed()));
+ data[base + 1]
+ = (int) (c1.getGreen() + ratio * (c2.getGreen() - c1.getGreen()));
+ data[base + 2]
+ = (int) (c1.getBlue() + ratio * (c2.getBlue() - c1.getBlue()));
+ data[base + 3]
+ = (int) (c1.getAlpha() + ratio * (c2.getAlpha() - c1.getAlpha()));
+ }
+ }
+ raster.setPixels(0, 0, w, h, data);
+ return raster;
+ }
+
+ /**
+ * Release the resources allocated for the paint (none in this
+ * implementation).
+ */
+ public void dispose() {
+ // nothing to do
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/awt/color/CieXyzConverter.java b/libjava/classpath/gnu/java/awt/color/CieXyzConverter.java
new file mode 100644
index 0000000..1742805
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/CieXyzConverter.java
@@ -0,0 +1,73 @@
+/* CieXyzConverter.java -- CieXyz conversion class
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+
+/**
+ * CieXyzConverter - converts to/from a D50-relative CIE XYZ color space.
+ *
+ * The sRGB<->CIE XYZ conversions in SrgbConverter are used.
+ *
+ * @author Sven de Marothy
+ */
+public class CieXyzConverter implements ColorSpaceConverter
+{
+ public float[] toCIEXYZ(float[] in)
+ {
+ float[] out = new float[3];
+ System.arraycopy(in, 0, out, 0, 3);
+ return out;
+ }
+
+ public float[] fromCIEXYZ(float[] in)
+ {
+ float[] out = new float[3];
+ System.arraycopy(in, 0, out, 0, 3);
+ return out;
+ }
+
+ public float[] toRGB(float[] in)
+ {
+ return SrgbConverter.XYZtoRGB(in);
+ }
+
+ public float[] fromRGB(float[] in)
+ {
+ return SrgbConverter.RGBtoXYZ(in);
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/color/ClutProfileConverter.java b/libjava/classpath/gnu/java/awt/color/ClutProfileConverter.java
new file mode 100644
index 0000000..bff97cc
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/ClutProfileConverter.java
@@ -0,0 +1,152 @@
+/* ClutProfileConverter.java -- Conversion routines for CLUT-Based profiles
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+import java.awt.color.ICC_Profile;
+
+
+/**
+ * ClutProfileConverter - conversions through a CLUT-based profile
+ *
+ * @author Sven de Marothy
+ */
+public class ClutProfileConverter implements ColorSpaceConverter
+{
+ private ColorLookUpTable toPCS;
+ private ColorLookUpTable fromPCS;
+ private int nChannels;
+
+ public ClutProfileConverter(ICC_Profile profile)
+ {
+ nChannels = profile.getNumComponents();
+
+ // Sun does not specifiy which rendering intent should be used,
+ // neither does the ICC v2 spec really.
+ // Try intent 0
+ try
+ {
+ toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB0Tag);
+ }
+ catch (Exception e)
+ {
+ toPCS = null;
+ }
+
+ try
+ {
+ fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA0Tag);
+ }
+ catch (Exception e)
+ {
+ fromPCS = null;
+ }
+
+ if (toPCS != null || fromPCS != null)
+ return;
+
+ // If no intent 0 clut is available, look for a intent 1 clut.
+ try
+ {
+ toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB1Tag);
+ }
+ catch (Exception e)
+ {
+ toPCS = null;
+ }
+
+ try
+ {
+ fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA1Tag);
+ }
+ catch (Exception e)
+ {
+ fromPCS = null;
+ }
+
+ if (toPCS != null || fromPCS != null)
+ return;
+
+ // Last shot.. intent 2 CLUT.
+ try
+ {
+ toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB2Tag);
+ }
+ catch (Exception e)
+ {
+ toPCS = null;
+ }
+
+ try
+ {
+ fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA2Tag);
+ }
+ catch (Exception e)
+ {
+ fromPCS = null;
+ }
+
+ if (toPCS == null && fromPCS == null)
+ throw new IllegalArgumentException("No CLUTs in profile!");
+ }
+
+ public float[] toCIEXYZ(float[] in)
+ {
+ if (toPCS != null)
+ return toPCS.lookup(in);
+ else
+ return new float[3];
+ }
+
+ public float[] toRGB(float[] in)
+ {
+ return SrgbConverter.XYZtoRGB(toCIEXYZ(in));
+ }
+
+ public float[] fromCIEXYZ(float[] in)
+ {
+ if (fromPCS != null)
+ return fromPCS.lookup(in);
+ else
+ return new float[nChannels];
+ }
+
+ public float[] fromRGB(float[] in)
+ {
+ return fromCIEXYZ(SrgbConverter.RGBtoXYZ(in));
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/color/ColorLookUpTable.java b/libjava/classpath/gnu/java/awt/color/ColorLookUpTable.java
new file mode 100644
index 0000000..6b6418b
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/ColorLookUpTable.java
@@ -0,0 +1,429 @@
+/* ColorLookUpTable.java -- ICC v2 CLUT
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.nio.ByteBuffer;
+
+
+/**
+ * ColorLookUpTable handles color lookups through a color lookup table,
+ * as defined in the ICC specification.
+ * Both 'mft2' and 'mft1' (8 and 16-bit) type CLUTs are handled.
+ *
+ * This will have to be updated later for ICC 4.0.0
+ *
+ * @author Sven de Marothy
+ */
+public class ColorLookUpTable
+{
+ /**
+ * CIE 1931 D50 white point (in Lab coordinates)
+ */
+ private static float[] D50 = { 0.96422f, 1.00f, 0.82521f };
+
+ /**
+ * Number of input/output channels
+ */
+ int nIn;
+
+ /**
+ * Number of input/output channels
+ */
+ int nOut;
+ int nInTableEntries; // Number of input table entries
+ int nOutTableEntries; // Number of output table entries
+ int gridpoints; // Number of gridpoints
+ int nClut; // This is nOut*(gridpoints**nIn)
+ double[][] inTable; // 1D input table ([channel][table])
+ short[][] outTable; // 1D input table ([channel][table])
+ double[] clut; // The color lookup table
+ float[][] inMatrix; // input matrix (XYZ only)
+ boolean useMatrix; // Whether to use the matrix or not.
+ int[] multiplier;
+ int[] offsets; // Hypercube offsets
+ boolean inputLab; // Set if the CLUT input CS is Lab
+ boolean outputLab; // Set if the CLUT output CS is Lab
+
+ /**
+ * Constructor
+ * Requires a profile file to get the CLUT from and the tag of the
+ * CLUT to create. (icSigXToYZTag where X,Y = [A | B], Z = [0,1,2])
+ */
+ public ColorLookUpTable(ICC_Profile profile, int tag)
+ {
+ useMatrix = false;
+
+ switch (tag)
+ {
+ case ICC_Profile.icSigAToB0Tag:
+ case ICC_Profile.icSigAToB1Tag:
+ case ICC_Profile.icSigAToB2Tag:
+ if (profile.getColorSpaceType() == ColorSpace.TYPE_XYZ)
+ useMatrix = true;
+ inputLab = false;
+ outputLab = (profile.getPCSType() == ColorSpace.TYPE_Lab);
+ break;
+ case ICC_Profile.icSigBToA0Tag:
+ case ICC_Profile.icSigBToA1Tag:
+ case ICC_Profile.icSigBToA2Tag:
+ if (profile.getPCSType() == ColorSpace.TYPE_XYZ)
+ useMatrix = true;
+ inputLab = (profile.getPCSType() == ColorSpace.TYPE_Lab);
+ outputLab = false;
+ break;
+ default:
+ throw new IllegalArgumentException("Not a clut-type tag.");
+ }
+
+ byte[] data = profile.getData(tag);
+ if (data == null)
+ throw new IllegalArgumentException("Unsuitable profile, does not contain a CLUT.");
+
+ // check 'mft'
+ if (data[0] != 0x6d || data[1] != 0x66 || data[2] != 0x74)
+ throw new IllegalArgumentException("Unsuitable profile, invalid CLUT data.");
+
+ if (data[3] == 0x32)
+ readClut16(data);
+ else if (data[3] == 0x31)
+ readClut8(data);
+ else
+ throw new IllegalArgumentException("Unknown/invalid CLUT type.");
+ }
+
+ /**
+ * Loads a 16-bit CLUT into our data structures
+ */
+ private void readClut16(byte[] data)
+ {
+ ByteBuffer buf = ByteBuffer.wrap(data);
+
+ nIn = data[8] & (0xFF);
+ nOut = data[9] & (0xFF);
+ nInTableEntries = buf.getShort(48);
+ nOutTableEntries = buf.getShort(50);
+ gridpoints = data[10] & (0xFF);
+
+ inMatrix = new float[3][3];
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ inMatrix[i][j] = ((float) (buf.getInt(12 + (i * 3 + j) * 4))) / 65536.0f;
+
+ inTable = new double[nIn][nInTableEntries];
+ for (int channel = 0; channel < nIn; channel++)
+ for (int i = 0; i < nInTableEntries; i++)
+ inTable[channel][i] = (double) ((int) buf.getShort(52
+ + (channel * nInTableEntries
+ + i) * 2)
+ & (0xFFFF)) / 65536.0;
+
+ nClut = nOut;
+ multiplier = new int[nIn];
+ multiplier[nIn - 1] = nOut;
+ for (int i = 0; i < nIn; i++)
+ {
+ nClut *= gridpoints;
+ if (i > 0)
+ multiplier[nIn - i - 1] = multiplier[nIn - i] * gridpoints;
+ }
+
+ int clutOffset = 52 + nIn * nInTableEntries * 2;
+ clut = new double[nClut];
+ for (int i = 0; i < nClut; i++)
+ clut[i] = (double) ((int) buf.getShort(clutOffset + i * 2) & (0xFFFF)) / 65536.0;
+
+ outTable = new short[nOut][nOutTableEntries];
+ for (int channel = 0; channel < nOut; channel++)
+ for (int i = 0; i < nOutTableEntries; i++)
+ outTable[channel][i] = buf.getShort(clutOffset
+ + (nClut
+ + channel * nOutTableEntries + i) * 2);
+
+ // calculate the hypercube corner offsets
+ offsets = new int[(1 << nIn)];
+ offsets[0] = 0;
+ for (int j = 0; j < nIn; j++)
+ {
+ int factor = 1 << j;
+ for (int i = 0; i < factor; i++)
+ offsets[factor + i] = offsets[i] + multiplier[j];
+ }
+ }
+
+ /**
+ * Loads a 8-bit CLUT into our data structures.
+ */
+ private void readClut8(byte[] data)
+ {
+ ByteBuffer buf = ByteBuffer.wrap(data);
+
+ nIn = (data[8] & (0xFF));
+ nOut = (data[9] & (0xFF));
+ nInTableEntries = 256; // always 256
+ nOutTableEntries = 256; // always 256
+ gridpoints = (data[10] & (0xFF));
+
+ inMatrix = new float[3][3];
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ inMatrix[i][j] = ((float) (buf.getInt(12 + (i * 3 + j) * 4))) / 65536.0f;
+
+ inTable = new double[nIn][nInTableEntries];
+ for (int channel = 0; channel < nIn; channel++)
+ for (int i = 0; i < nInTableEntries; i++)
+ inTable[channel][i] = (double) ((int) buf.get(48
+ + (channel * nInTableEntries
+ + i)) & (0xFF)) / 255.0;
+
+ nClut = nOut;
+ multiplier = new int[nIn];
+ multiplier[nIn - 1] = nOut;
+ for (int i = 0; i < nIn; i++)
+ {
+ nClut *= gridpoints;
+ if (i > 0)
+ multiplier[nIn - i - 1] = multiplier[nIn - i] * gridpoints;
+ }
+
+ int clutOffset = 48 + nIn * nInTableEntries;
+ clut = new double[nClut];
+ for (int i = 0; i < nClut; i++)
+ clut[i] = (double) ((int) buf.get(clutOffset + i) & (0xFF)) / 255.0;
+
+ outTable = new short[nOut][nOutTableEntries];
+ for (int channel = 0; channel < nOut; channel++)
+ for (int i = 0; i < nOutTableEntries; i++)
+ outTable[channel][i] = (short) (buf.get(clutOffset + nClut
+ + channel * nOutTableEntries
+ + i) * 257);
+
+ // calculate the hypercube corner offsets
+ offsets = new int[(1 << nIn)];
+ offsets[0] = 0;
+ for (int j = 0; j < nIn; j++)
+ {
+ int factor = 1 << j;
+ for (int i = 0; i < factor; i++)
+ offsets[factor + i] = offsets[i] + multiplier[j];
+ }
+ }
+
+ /**
+ * Performs a lookup through the Color LookUp Table.
+ * If the CLUT tag type is AtoB the conversion will be from the device
+ * color space to the PCS, BtoA type goes in the opposite direction.
+ *
+ * For convenience, the PCS values for input or output will always be
+ * CIE XYZ (D50), if the actual PCS is Lab, the values will be converted.
+ *
+ * N-dimensional linear interpolation is used.
+ */
+ float[] lookup(float[] in)
+ {
+ float[] in2 = new float[in.length];
+ if (useMatrix)
+ {
+ for (int i = 0; i < 3; i++)
+ in2[i] = in[0] * inMatrix[i][0] + in[1] * inMatrix[i][1]
+ + in[2] * inMatrix[i][2];
+ }
+ else if (inputLab)
+ in2 = XYZtoLab(in);
+ else
+ System.arraycopy(in, 0, in2, 0, in.length);
+
+ // input table
+ for (int i = 0; i < nIn; i++)
+ {
+ int index = (int) Math.floor(in2[i] * (double) (nInTableEntries - 1)); // floor in
+
+ // clip values.
+ if (index >= nInTableEntries - 1)
+ in2[i] = (float) inTable[i][nInTableEntries - 1];
+ else if (index < 0)
+ in2[i] = (float) inTable[i][0];
+ else
+ {
+ // linear interpolation
+ double alpha = in2[i] * ((double) nInTableEntries - 1.0) - index;
+ in2[i] = (float) (inTable[i][index] * (1 - alpha)
+ + inTable[i][index + 1] * alpha);
+ }
+ }
+
+ // CLUT lookup
+ double[] output2 = new double[nOut];
+ double[] weights = new double[(1 << nIn)];
+ double[] clutalpha = new double[nIn]; // interpolation values
+ int offset = 0; // = gp
+ for (int i = 0; i < nIn; i++)
+ {
+ int index = (int) Math.floor(in2[i] * ((double) gridpoints - 1.0));
+ double alpha = in2[i] * ((double) gridpoints - 1.0) - (double) index;
+
+ // clip values.
+ if (index >= gridpoints - 1)
+ {
+ index = gridpoints - 1;
+ alpha = 1.0;
+ }
+ else if (index < 0)
+ index = 0;
+ clutalpha[i] = alpha;
+ offset += index * multiplier[i];
+ }
+
+ // Calculate interpolation weights
+ weights[0] = 1.0;
+ for (int j = 0; j < nIn; j++)
+ {
+ int factor = 1 << j;
+ for (int i = 0; i < factor; i++)
+ {
+ weights[factor + i] = weights[i] * clutalpha[j];
+ weights[i] *= (1.0 - clutalpha[j]);
+ }
+ }
+
+ for (int i = 0; i < nOut; i++)
+ output2[i] = weights[0] * clut[offset + i];
+
+ for (int i = 1; i < (1 << nIn); i++)
+ {
+ int offset2 = offset + offsets[i];
+ for (int f = 0; f < nOut; f++)
+ output2[f] += weights[i] * clut[offset2 + f];
+ }
+
+ // output table
+ float[] output = new float[nOut];
+ for (int i = 0; i < nOut; i++)
+ {
+ int index = (int) Math.floor(output2[i] * ((double) nOutTableEntries
+ - 1.0));
+
+ // clip values.
+ if (index >= nOutTableEntries - 1)
+ output[i] = outTable[i][nOutTableEntries - 1];
+ else if (index < 0)
+ output[i] = outTable[i][0];
+ else
+ {
+ // linear interpolation
+ double a = output2[i] * ((double) nOutTableEntries - 1.0)
+ - (double) index;
+ output[i] = (float) ((double) ((int) outTable[i][index] & (0xFFFF)) * (1
+ - a)
+ + (double) ((int) outTable[i][index + 1] & (0xFFFF)) * a) / 65536f;
+ }
+ }
+
+ if (outputLab)
+ return LabtoXYZ(output);
+ return output;
+ }
+
+ /**
+ * Converts CIE Lab coordinates to (D50) XYZ ones.
+ */
+ private float[] LabtoXYZ(float[] in)
+ {
+ // Convert from byte-packed format to a
+ // more convenient one (actual Lab values)
+ // (See ICC spec for details)
+ // factor is 100 * 65536 / 65280
+ in[0] = (float) (100.392156862745 * in[0]);
+ in[1] = (in[1] * 256.0f) - 128.0f;
+ in[2] = (in[2] * 256.0f) - 128.0f;
+
+ float[] out = new float[3];
+
+ out[1] = (in[0] + 16.0f) / 116.0f;
+ out[0] = in[1] / 500.0f + out[1];
+ out[2] = out[1] - in[2] / 200.0f;
+
+ for (int i = 0; i < 3; i++)
+ {
+ double exp = out[i] * out[i] * out[i];
+ if (exp <= 0.008856)
+ out[i] = (out[i] - 16.0f / 116.0f) / 7.787f;
+ else
+ out[i] = (float) exp;
+ out[i] = D50[i] * out[i];
+ }
+ return out;
+ }
+
+ /**
+ * Converts CIE XYZ coordinates to Lab ones.
+ */
+ private float[] XYZtoLab(float[] in)
+ {
+ float[] temp = new float[3];
+
+ for (int i = 0; i < 3; i++)
+ {
+ temp[i] = in[i] / D50[i];
+
+ if (temp[i] <= 0.008856f)
+ temp[i] = (7.7870689f * temp[i]) + (16f / 116.0f);
+ else
+ temp[i] = (float) Math.exp((1.0 / 3.0) * Math.log(temp[i]));
+ }
+
+ float[] out = new float[3];
+ out[0] = (116.0f * temp[1]) - 16f;
+ out[1] = 500.0f * (temp[0] - temp[1]);
+ out[2] = 200.0f * (temp[1] - temp[2]);
+
+ // Normalize to packed format
+ out[0] = (float) (out[0] / 100.392156862745);
+ out[1] = (out[1] + 128f) / 256f;
+ out[2] = (out[2] + 128f) / 256f;
+ for (int i = 0; i < 3; i++)
+ {
+ if (out[i] < 0f)
+ out[i] = 0f;
+ if (out[i] > 1f)
+ out[i] = 1f;
+ }
+ return out;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/color/ColorSpaceConverter.java b/libjava/classpath/gnu/java/awt/color/ColorSpaceConverter.java
new file mode 100644
index 0000000..63ba08a
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/ColorSpaceConverter.java
@@ -0,0 +1,69 @@
+/* ColorSpaceConverter.java -- an interface for colorspace conversion
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+
+/**
+ * ColorSpaceConverter - used by java.awt.color.ICC_ColorSpace
+ *
+ * Color space conversion can occur in several ways:
+ *
+ * -Directly (for the built in spaces sRGB, linear RGB, gray, CIE XYZ and PYCC
+ * -ICC_ProfileRGB works through TRC curves and a matrix
+ * -ICC_ProfileGray works through a single TRC
+ * -Everything else is done through Color lookup tables.
+ *
+ * The different conversion methods are implemented through
+ * an interface. The built-in colorspaces are implemented directly
+ * with the relevant conversion equations.
+ *
+ * In this way, we hopefully will always use the fastest and most
+ * accurate method available.
+ *
+ * @author Sven de Marothy
+ */
+public interface ColorSpaceConverter
+{
+ float[] toCIEXYZ(float[] in);
+
+ float[] fromCIEXYZ(float[] in);
+
+ float[] toRGB(float[] in);
+
+ float[] fromRGB(float[] in);
+}
diff --git a/libjava/classpath/gnu/java/awt/color/GrayProfileConverter.java b/libjava/classpath/gnu/java/awt/color/GrayProfileConverter.java
new file mode 100644
index 0000000..3c72513
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/GrayProfileConverter.java
@@ -0,0 +1,137 @@
+/* GrayProfileConverter.java -- Gray profile conversion class
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+import java.awt.color.ICC_Profile;
+import java.awt.color.ICC_ProfileGray;
+import java.awt.color.ProfileDataException;
+
+/**
+ * GrayProfileConverter - converts Grayscale profiles (ICC_ProfileGray)
+ *
+ * This type of profile contains a single tone reproduction curve (TRC).
+ * Conversion consists of simple TRC lookup.
+ *
+ * This implementation is very lazy and does everything applying the TRC and
+ * utilizing the built-in linear grayscale color space.
+ *
+ * @author Sven de Marothy
+ */
+public class GrayProfileConverter implements ColorSpaceConverter
+{
+ private GrayScaleConverter gc;
+ private ToneReproductionCurve trc;
+ private ColorLookUpTable toPCS;
+ private ColorLookUpTable fromPCS;
+
+ /**
+ * Constructs the converter described by an ICC_ProfileGray object
+ */
+ public GrayProfileConverter(ICC_ProfileGray profile)
+ {
+ try
+ {
+ trc = new ToneReproductionCurve(profile.getGamma());
+ }
+ catch (ProfileDataException e)
+ {
+ trc = new ToneReproductionCurve(profile.getTRC());
+ }
+
+ // linear grayscale converter
+ gc = new GrayScaleConverter();
+
+ // If a CLUT is available, it should be used, and the TRCs ignored.
+ // Note: A valid profile may only have CLUTs in one direction, and
+ // TRC:s without useful info, making reverse-transforms impossible.
+ // In this case the TRC will be used for the reverse-transform with
+ // unpredictable results. This is in line with the Java specification,
+ try
+ {
+ toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB0Tag);
+ }
+ catch (Exception e)
+ {
+ toPCS = null;
+ }
+
+ try
+ {
+ fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA0Tag);
+ }
+ catch (Exception e)
+ {
+ fromPCS = null;
+ }
+ }
+
+ public float[] toCIEXYZ(float[] in)
+ {
+ if (toPCS != null)
+ return toPCS.lookup(in);
+ float[] gray = new float[1];
+ gray[0] = trc.lookup(in[0]);
+ return gc.toCIEXYZ(gray);
+ }
+
+ public float[] toRGB(float[] in)
+ {
+ float[] gray = new float[1];
+ gray[0] = trc.lookup(in[0]);
+ return gc.toRGB(gray);
+ }
+
+ public float[] fromRGB(float[] in)
+ {
+ // get linear grayscale value
+ float[] gray = gc.fromRGB(in);
+ gray[0] = trc.reverseLookup(gray[0]);
+ return gray;
+ }
+
+ public float[] fromCIEXYZ(float[] in)
+ {
+ if (fromPCS != null)
+ return fromPCS.lookup(in);
+
+ float[] gray = gc.fromCIEXYZ(in);
+ gray[0] = trc.reverseLookup(gray[0]);
+ return gray;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/color/GrayScaleConverter.java b/libjava/classpath/gnu/java/awt/color/GrayScaleConverter.java
new file mode 100644
index 0000000..7a27ddb
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/GrayScaleConverter.java
@@ -0,0 +1,110 @@
+/* GrayScaleConverter.java -- Linear grayscale conversion class
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+
+/**
+ * Linear Grayscale converter
+ *
+ * @author Sven de Marothy
+ */
+public class GrayScaleConverter implements ColorSpaceConverter
+{
+ // intensity factors (ITU Rec. BT.709)
+ double[] coeff = { 0.2125f, 0.7154f, 0.0721f };
+
+ /**
+ * CIE 1931 D50 white point (in Lab coordinates)
+ */
+ private static float[] D50 = { 0.96422f, 1.00f, 0.82521f };
+
+ public float[] toCIEXYZ(float[] in)
+ {
+ float g = in[0];
+ if (g < 0)
+ g = 1 + g;
+ float[] out = { g * D50[0], g * D50[1], g * D50[2] }; // White spot
+ return out;
+ }
+
+ public float[] toRGB(float[] in)
+ {
+ float[] out = new float[3];
+ if (in[0] <= 0.00304f)
+ out[0] = in[0] * 12.92f;
+ else
+ out[0] = 1.055f * ((float) Math.exp((1 / 2.4) * Math.log(in[0])))
+ - 0.055f;
+ out[1] = out[2] = out[0];
+ return out;
+ }
+
+ public float[] fromCIEXYZ(float[] in)
+ {
+ float[] temp = new float[3];
+ temp[0] = 3.1338f * in[0] - 1.6171f * in[1] - 0.4907f * in[2];
+ temp[1] = -0.9785f * in[0] + 1.9160f * in[1] + 0.0334f * in[2];
+ temp[2] = 0.0720f * in[0] - 0.2290f * in[1] + 1.4056f * in[2];
+ float[] out = new float[1];
+ for (int i = 0; i < 3; i++)
+ out[0] = (float) (temp[i] * coeff[i]);
+ return out;
+ }
+
+ public float[] fromRGB(float[] in)
+ {
+ float[] out = new float[1];
+
+ // Convert non-linear RGB coordinates to linear ones,
+ // numbers from the w3 spec.
+ out[0] = 0;
+ for (int i = 0; i < 3; i++)
+ {
+ float n = in[i];
+ if (n < 0)
+ n = 0f;
+ if (n > 1)
+ n = 1f;
+ if (n <= 0.03928f)
+ out[0] += (float) (coeff[i] * n / 12.92);
+ else
+ out[0] += (float) (coeff[i] * Math.exp(2.4 * Math.log((n + 0.055) / 1.055)));
+ }
+ return out;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/color/LinearRGBConverter.java b/libjava/classpath/gnu/java/awt/color/LinearRGBConverter.java
new file mode 100644
index 0000000..13a4e2c
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/LinearRGBConverter.java
@@ -0,0 +1,152 @@
+/* LinearRGBConverter.java -- conversion to a linear RGB color space
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+
+/**
+ * LinearRGBConverter - conversion routines for a linear sRGB colorspace
+ * sRGB is a standard for RGB colorspaces, adopted by the w3c.
+ *
+ * The specification is available at:
+ * http://www.w3.org/Graphics/Color/sRGB.html
+ *
+ * @author Sven de Marothy
+ */
+public class LinearRGBConverter implements ColorSpaceConverter
+{
+ /**
+ * linear RGB --> sRGB
+ * Use the inverse gamma curve
+ */
+ public float[] toRGB(float[] in)
+ {
+ float[] out = new float[3];
+ for (int i = 0; i < 3; i++)
+ {
+ float n = in[i];
+ if (n < 0)
+ n = 0f;
+ if (n > 1)
+ n = 1f;
+ if (n <= 0.00304f)
+ out[i] = in[0] * 12.92f;
+ else
+ out[i] = 1.055f * ((float) Math.exp((1 / 2.4) * Math.log(n)))
+ - 0.055f;
+ }
+ return out;
+ }
+
+ /**
+ * sRGB --> linear RGB
+ * Use the gamma curve (gamma=2.4 in sRGB)
+ */
+ public float[] fromRGB(float[] in)
+ {
+ float[] out = new float[3];
+
+ // Convert non-linear RGB coordinates to linear ones,
+ // numbers from the w3 spec.
+ for (int i = 0; i < 3; i++)
+ {
+ float n = in[i];
+ if (n < 0)
+ n = 0f;
+ if (n > 1)
+ n = 1f;
+ if (n <= 0.03928f)
+ out[i] = (float) (n / 12.92);
+ else
+ out[i] = (float) (Math.exp(2.4 * Math.log((n + 0.055) / 1.055)));
+ }
+ return out;
+ }
+
+ /**
+ * Linear RGB --> CIE XYZ (D50 relative)
+ * This is a simple matrix transform, the matrix (relative D65)
+ * is given in the sRGB spec. This has been combined with a
+ * linear Bradford transform for the D65-->D50 mapping, resulting
+ * in a single matrix which does the whole thing.
+ *
+ */
+ public float[] fromCIEXYZ(float[] in)
+ {
+ /*
+ * Note: The numbers which were used to calculate this only had four
+ * digits of accuracy. So don't be fooled by the number of digits here.
+ * If someone has more accurate source, feel free to update this.
+ */
+ float[] out = new float[3];
+ out[0] = (float) (3.13383065124221 * in[0] - 1.61711949411313 * in[1]
+ - 0.49071914111101 * in[2]);
+ out[1] = (float) (-0.97847026691142 * in[0] + 1.91597856031996 * in[1]
+ + 0.03340430640699 * in[2]);
+ out[2] = (float) (0.07203679486279 * in[0] - 0.22903073553113 * in[1]
+ + 1.40557835776234 * in[2]);
+ if (out[0] < 0)
+ out[0] = 0f;
+ if (out[1] < 0)
+ out[1] = 0f;
+ if (out[2] < 0)
+ out[2] = 0f;
+ if (out[0] > 1.0f)
+ out[0] = 1.0f;
+ if (out[1] > 1.0f)
+ out[1] = 1.0f;
+ if (out[2] > 1.0f)
+ out[2] = 1.0f;
+ return out;
+ }
+
+ /**
+ * Linear RGB --> CIE XYZ (D50 relative)
+ * Uses the inverse of the above matrix.
+ */
+ public float[] toCIEXYZ(float[] in)
+ {
+ float[] out = new float[3];
+ out[0] = (float) (0.43606375022190 * in[0] + 0.38514960146481 * in[1]
+ + 0.14308641888799 * in[2]);
+ out[1] = (float) (0.22245089403542 * in[0] + 0.71692584775182 * in[1]
+ + 0.06062451125578 * in[2]);
+ out[2] = (float) (0.01389851860679 * in[0] + 0.09707969011198 * in[1]
+ + 0.71399604572506 * in[2]);
+ return out;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/color/ProfileHeader.java b/libjava/classpath/gnu/java/awt/color/ProfileHeader.java
new file mode 100644
index 0000000..4fdef56
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/ProfileHeader.java
@@ -0,0 +1,398 @@
+/* ProfileHeader.java -- Encapsules ICC Profile header data
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.nio.ByteBuffer;
+
+
+/**
+ * Header, abstracts and validates the header data.
+ *
+ * @author Sven de Marothy
+ */
+public class ProfileHeader
+{
+ /**
+ * Magic identifier (ASCII 'acsp')
+ */
+ private static final int icMagicNumber = 0x61637370;
+
+ /**
+ * Mapping from ICC Profile signatures to ColorSpace types
+ */
+ private static final int[] csTypeMap =
+ {
+ ICC_Profile.icSigXYZData,
+ ColorSpace.TYPE_XYZ,
+ ICC_Profile.icSigLabData,
+ ColorSpace.TYPE_Lab,
+ ICC_Profile.icSigLuvData,
+ ColorSpace.TYPE_Luv,
+ ICC_Profile.icSigYCbCrData,
+ ColorSpace.TYPE_YCbCr,
+ ICC_Profile.icSigYxyData,
+ ColorSpace.TYPE_Yxy,
+ ICC_Profile.icSigRgbData,
+ ColorSpace.TYPE_RGB,
+ ICC_Profile.icSigGrayData,
+ ColorSpace.TYPE_GRAY,
+ ICC_Profile.icSigHsvData,
+ ColorSpace.TYPE_HSV,
+ ICC_Profile.icSigHlsData,
+ ColorSpace.TYPE_HLS,
+ ICC_Profile.icSigCmykData,
+ ColorSpace.TYPE_CMYK,
+ ICC_Profile.icSigCmyData,
+ ColorSpace.TYPE_CMY,
+ ICC_Profile.icSigSpace2CLR,
+ ColorSpace.TYPE_2CLR,
+ ICC_Profile.icSigSpace3CLR,
+ ColorSpace.TYPE_3CLR,
+ ICC_Profile.icSigSpace4CLR,
+ ColorSpace.TYPE_4CLR,
+ ICC_Profile.icSigSpace5CLR,
+ ColorSpace.TYPE_5CLR,
+ ICC_Profile.icSigSpace6CLR,
+ ColorSpace.TYPE_6CLR,
+ ICC_Profile.icSigSpace7CLR,
+ ColorSpace.TYPE_7CLR,
+ ICC_Profile.icSigSpace8CLR,
+ ColorSpace.TYPE_8CLR,
+ ICC_Profile.icSigSpace9CLR,
+ ColorSpace.TYPE_9CLR,
+ ICC_Profile.icSigSpaceACLR,
+ ColorSpace.TYPE_ACLR,
+ ICC_Profile.icSigSpaceBCLR,
+ ColorSpace.TYPE_BCLR,
+ ICC_Profile.icSigSpaceCCLR,
+ ColorSpace.TYPE_CCLR,
+ ICC_Profile.icSigSpaceDCLR,
+ ColorSpace.TYPE_DCLR,
+ ICC_Profile.icSigSpaceECLR,
+ ColorSpace.TYPE_ECLR,
+ ICC_Profile.icSigSpaceFCLR,
+ ColorSpace.TYPE_FCLR
+ };
+
+ /**
+ * Size of an ICC header (128 bytes)
+ */
+ public static final int HEADERSIZE = 128;
+
+ /**
+ * Mapping of ICC class signatures to profile class constants
+ */
+ private static final int[] classMap =
+ {
+ ICC_Profile.icSigInputClass,
+ ICC_Profile.CLASS_INPUT,
+ ICC_Profile.icSigDisplayClass,
+ ICC_Profile.CLASS_DISPLAY,
+ ICC_Profile.icSigOutputClass,
+ ICC_Profile.CLASS_OUTPUT,
+ ICC_Profile.icSigLinkClass,
+ ICC_Profile.CLASS_DEVICELINK,
+ ICC_Profile.icSigColorSpaceClass,
+ ICC_Profile.CLASS_COLORSPACECONVERSION,
+ ICC_Profile.icSigAbstractClass,
+ ICC_Profile.CLASS_ABSTRACT,
+ ICC_Profile.icSigNamedColorClass,
+ ICC_Profile.CLASS_NAMEDCOLOR
+ };
+ private int size;
+ private int cmmId;
+
+ // Major/Minor version, The ICC-1998 spec is major v2
+ private int majorVersion;
+
+ // Major/Minor version, The ICC-1998 spec is major v2
+ private int minorVersion;
+ private int profileClass; // profile device class
+ private int colorSpace; // data color space type
+ private int profileColorSpace; // profile connection space (PCS) type
+ private byte[] timestamp; // original creation timestamp
+ private int platform; // platform signature
+ private int flags; // flags
+ private int magic; // magic number.
+ private int manufacturerSig; // manufacturer sig
+ private int modelSig; // model sig
+ private byte[] attributes; // Attributes
+ private int intent; // rendering intent
+ private byte[] illuminant; // illuminant info (Coordinates of D50 in the PCS)
+ private int creatorSig; // Creator sig (same type as manufacturer)
+
+ /**
+ * Creates a 'default' header for use with our predefined profiles.
+ * Note the device and profile color spaces are not set.
+ */
+ public ProfileHeader()
+ {
+ creatorSig = 0;
+ intent = 0;
+ modelSig = manufacturerSig = (int) 0x6E6f6E65; // 'none'
+ magic = icMagicNumber;
+ cmmId = 0;
+ platform = 0; // no preferred platform
+ timestamp = new byte[8];
+ majorVersion = 2;
+ minorVersion = 0x10;
+ flags = 0;
+
+ // D50 in XYZ format (encoded)
+ illuminant = new byte[]
+ {
+ (byte) 0x00, (byte) 0x00, (byte) 0xf6, (byte) 0xd6,
+ (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00,
+ (byte) 0x00, (byte) 0x00, (byte) 0xd3, (byte) 0x2d
+ };
+ attributes = new byte[8];
+ profileClass = ICC_Profile.CLASS_DISPLAY;
+ }
+
+ /**
+ * Creates a header from profile data. Only the header portion (128 bytes)
+ * is read, so the array passed need not be the full profile.
+ */
+ public ProfileHeader(byte[] data)
+ {
+ ByteBuffer buf = ByteBuffer.wrap(data);
+
+ // Get size (the sign bit shouldn't matter.
+ // A valid profile can never be +2Gb)
+ size = buf.getInt(ICC_Profile.icHdrSize);
+
+ // CMM ID
+ cmmId = buf.getInt(ICC_Profile.icHdrCmmId);
+
+ // Version number
+ majorVersion = (int) (data[ICC_Profile.icHdrVersion]);
+ minorVersion = (int) (data[ICC_Profile.icHdrVersion + 1]);
+
+ // Profile/Device class
+ int classSig = buf.getInt(ICC_Profile.icHdrDeviceClass);
+ profileClass = -1;
+ for (int i = 0; i < classMap.length; i += 2)
+ if (classMap[i] == classSig)
+ {
+ profileClass = classMap[i + 1];
+ break;
+ }
+
+ // get the data color space
+ int csSig = buf.getInt(ICC_Profile.icHdrColorSpace);
+ colorSpace = -1;
+ for (int i = 0; i < csTypeMap.length; i += 2)
+ if (csTypeMap[i] == csSig)
+ {
+ colorSpace = csTypeMap[i + 1];
+ break;
+ }
+
+ // get the profile color space (PCS), must be xyz or lab except
+ // for device-link-class profiles
+ int pcsSig = buf.getInt(ICC_Profile.icHdrPcs);
+ profileColorSpace = -1;
+ if (profileClass != ICC_Profile.CLASS_DEVICELINK)
+ {
+ if (pcsSig == ICC_Profile.icSigXYZData)
+ profileColorSpace = ColorSpace.TYPE_XYZ;
+ if (pcsSig == ICC_Profile.icSigLabData)
+ profileColorSpace = ColorSpace.TYPE_Lab;
+ }
+ else
+ {
+ for (int i = 0; i < csTypeMap.length; i += 2)
+ if (csTypeMap[i] == pcsSig)
+ {
+ profileColorSpace = csTypeMap[i + 1];
+ break;
+ }
+ }
+
+ // creation timestamp
+ timestamp = new byte[8];
+ System.arraycopy(data, ICC_Profile.icHdrDate, timestamp, 0, 8);
+
+ // magic number
+ magic = buf.getInt(ICC_Profile.icHdrMagic);
+
+ // platform info
+ platform = buf.getInt(ICC_Profile.icHdrPlatform);
+ // get flags
+ flags = buf.getInt(ICC_Profile.icHdrFlags);
+ // get manufacturer sign
+ manufacturerSig = buf.getInt(ICC_Profile.icHdrManufacturer);
+ // get header model
+ modelSig = buf.getInt(ICC_Profile.icHdrModel);
+ // attributes
+ attributes = new byte[8];
+ System.arraycopy(data, ICC_Profile.icHdrAttributes, attributes, 0, 8);
+ // rendering intent
+ intent = buf.getInt(ICC_Profile.icHdrRenderingIntent);
+ // illuminant info
+ illuminant = new byte[12];
+ System.arraycopy(data, ICC_Profile.icHdrIlluminant, illuminant, 0, 12);
+ // Creator signature
+ creatorSig = buf.getInt(ICC_Profile.icHdrCreator);
+ // The rest of the header (Total size: 128 bytes) is unused..
+ }
+
+ /**
+ * Verify that the header is valid
+ * @param size equals the file size if it is to be verified, -1 otherwise
+ * @throws IllegalArgumentException if the header is found to be invalid.
+ */
+ public void verifyHeader(int size) throws IllegalArgumentException
+ {
+ // verify size
+ if (size != -1 && this.size != size)
+ throw new IllegalArgumentException("Invalid profile length:" + size);
+
+ // Check version number
+ if (majorVersion != 2)
+ throw new IllegalArgumentException("Wrong major version number:"
+ + majorVersion);
+
+ // Profile/Device class
+ if (profileClass == -1)
+ throw new IllegalArgumentException("Invalid profile/device class");
+
+ // get the data color space
+ if (colorSpace == -1)
+ throw new IllegalArgumentException("Invalid colorspace");
+
+ // profile color space
+ if (profileColorSpace == -1)
+ throw new IllegalArgumentException("Invalid PCS.");
+
+ // check magic number
+ if (magic != icMagicNumber)
+ throw new IllegalArgumentException("Invalid magic number!");
+ }
+
+ /**
+ * Creates a header, setting the header file size at the same time.
+ * @param size the profile file size.
+ */
+ public byte[] getData(int size)
+ {
+ byte[] data = new byte[HEADERSIZE];
+ ByteBuffer buf = ByteBuffer.wrap(data);
+ buf.putInt(ICC_Profile.icHdrSize, size);
+ buf.putInt(ICC_Profile.icHdrCmmId, cmmId);
+ buf.putShort(ICC_Profile.icHdrVersion,
+ (short) (majorVersion << 8 | minorVersion));
+ for (int i = 1; i < classMap.length; i += 2)
+ if (profileClass == classMap[i])
+ buf.putInt(ICC_Profile.icHdrDeviceClass, classMap[i - 1]);
+ for (int i = 1; i < csTypeMap.length; i += 2)
+ if (csTypeMap[i] == colorSpace)
+ buf.putInt(ICC_Profile.icHdrColorSpace, csTypeMap[i - 1]);
+ for (int i = 1; i < csTypeMap.length; i += 2)
+ if (csTypeMap[i] == profileColorSpace)
+ buf.putInt(ICC_Profile.icHdrPcs, csTypeMap[i - 1]);
+
+ System.arraycopy(timestamp, 0, data, ICC_Profile.icHdrDate,
+ timestamp.length);
+ buf.putInt(ICC_Profile.icHdrMagic, icMagicNumber);
+ buf.putInt(ICC_Profile.icHdrPlatform, platform);
+ buf.putInt(ICC_Profile.icHdrFlags, flags);
+ buf.putInt(ICC_Profile.icHdrManufacturer, manufacturerSig);
+ buf.putInt(ICC_Profile.icHdrModel, modelSig);
+ System.arraycopy(attributes, 0, data, ICC_Profile.icHdrAttributes,
+ attributes.length);
+ buf.putInt(ICC_Profile.icHdrRenderingIntent, intent);
+ System.arraycopy(illuminant, 0, data, ICC_Profile.icHdrIlluminant,
+ illuminant.length);
+ buf.putInt(ICC_Profile.icHdrCreator, creatorSig);
+ return buf.array();
+ }
+
+ public int getSize()
+ {
+ return size;
+ }
+
+ public void setSize(int s)
+ {
+ size = s;
+ }
+
+ public int getMajorVersion()
+ {
+ return majorVersion;
+ }
+
+ public int getMinorVersion()
+ {
+ return minorVersion;
+ }
+
+ public int getProfileClass()
+ {
+ return profileClass;
+ }
+
+ public void setProfileClass(int pc)
+ {
+ profileClass = pc;
+ }
+
+ public int getColorSpace()
+ {
+ return colorSpace;
+ }
+
+ public int getProfileColorSpace()
+ {
+ return profileColorSpace;
+ }
+
+ public void setColorSpace(int cs)
+ {
+ colorSpace = cs;
+ }
+
+ public void setProfileColorSpace(int pcs)
+ {
+ profileColorSpace = pcs;
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/awt/color/PyccConverter.java b/libjava/classpath/gnu/java/awt/color/PyccConverter.java
new file mode 100644
index 0000000..cd50d87
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/PyccConverter.java
@@ -0,0 +1,72 @@
+/* PyccConverter.java -- PhotoYCC conversion class
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+
+/**
+ * PyccConverter - conversion routines for the PhotoYCC colorspace
+ *
+ * Also known as PhotoCD YCC, it is an expansion of the conventional
+ * YCC color space to also include colors with over 100% white.
+ *
+ * XXX FIXME: Not yet implemented, implementation pending.
+ *
+ * @author Sven de Marothy
+ */
+public class PyccConverter implements ColorSpaceConverter
+{
+ public float[] toRGB(float[] in)
+ {
+ return null;
+ }
+
+ public float[] fromRGB(float[] in)
+ {
+ return null;
+ }
+
+ public float[] toCIEXYZ(float[] in)
+ {
+ return null;
+ }
+
+ public float[] fromCIEXYZ(float[] in)
+ {
+ return null;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/color/RgbProfileConverter.java b/libjava/classpath/gnu/java/awt/color/RgbProfileConverter.java
new file mode 100644
index 0000000..0cbd28f
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/RgbProfileConverter.java
@@ -0,0 +1,244 @@
+/* RgbProfileConverter.java -- RGB Profile conversion class
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+import java.awt.color.ICC_Profile;
+import java.awt.color.ICC_ProfileRGB;
+import java.awt.color.ProfileDataException;
+
+/**
+ * RgbProfileConverter - converts RGB profiles (ICC_ProfileRGB)
+ *
+ * This type of profile contains a matrix and three
+ * tone reproduction curves (TRCs).
+ *
+ * Device RGB --&gt; CIE XYZ is done through first multiplying with
+ * a matrix, then each component is looked-up against it's TRC.
+ *
+ * The opposite transform is done using the inverse of the matrix,
+ * and TRC:s.
+ *
+ * @author Sven de Marothy
+ */
+public class RgbProfileConverter implements ColorSpaceConverter
+{
+ private float[][] matrix;
+ private float[][] inv_matrix;
+ private ToneReproductionCurve rTRC;
+ private ToneReproductionCurve gTRC;
+ private ToneReproductionCurve bTRC;
+ private ColorLookUpTable toPCS;
+ private ColorLookUpTable fromPCS;
+
+ /**
+ * CIE 1931 D50 white point (in Lab coordinates)
+ */
+ private static float[] D50 = { 0.96422f, 1.00f, 0.82521f };
+
+ /**
+ * Constructs an RgbProfileConverter from a given ICC_ProfileRGB
+ */
+ public RgbProfileConverter(ICC_ProfileRGB profile)
+ {
+ toPCS = fromPCS = null;
+ matrix = profile.getMatrix();
+
+ // get TRCs
+ try
+ {
+ rTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.REDCOMPONENT));
+ }
+ catch (ProfileDataException e)
+ {
+ rTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.REDCOMPONENT));
+ }
+ try
+ {
+ gTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.GREENCOMPONENT));
+ }
+ catch (ProfileDataException e)
+ {
+ gTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.GREENCOMPONENT));
+ }
+ try
+ {
+ bTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.BLUECOMPONENT));
+ }
+ catch (ProfileDataException e)
+ {
+ bTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.BLUECOMPONENT));
+ }
+
+ // If a CLUT is available, it should be used, and the TRCs ignored.
+ // Note: A valid profile may only have CLUTs in one direction, and
+ // TRC:s without useful info, making reverse-transforms impossible.
+ // In this case the TRC will be used for the reverse-transform with
+ // unpredictable results. This is in line with the Java specification,
+ try
+ {
+ toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB0Tag);
+ }
+ catch (Exception e)
+ {
+ toPCS = null;
+ }
+
+ try
+ {
+ fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA0Tag);
+ }
+ catch (Exception e)
+ {
+ fromPCS = null;
+ }
+
+ // Calculate the inverse matrix if no reverse CLUT is available
+ if(fromPCS == null)
+ inv_matrix = invertMatrix(matrix);
+ else
+ {
+ // otherwise just set it to an identity matrix
+ inv_matrix = new float[3][3];
+ inv_matrix[0][0] = inv_matrix[1][1] = inv_matrix[2][2] = 1.0f;
+ }
+ }
+
+ public float[] toCIEXYZ(float[] in)
+ {
+ // CLUT takes precedence
+ if (toPCS != null)
+ return toPCS.lookup(in);
+
+ float[] temp = new float[3];
+ float[] out = new float[3];
+
+ // device space --> linear gamma
+ temp[0] = rTRC.lookup(in[0]);
+ temp[1] = gTRC.lookup(in[1]);
+ temp[2] = bTRC.lookup(in[2]);
+
+ // matrix multiplication
+ out[0] = matrix[0][0] * temp[0] + matrix[0][1] * temp[1]
+ + matrix[0][2] * temp[2];
+ out[1] = matrix[1][0] * temp[0] + matrix[1][1] * temp[1]
+ + matrix[1][2] * temp[2];
+ out[2] = matrix[2][0] * temp[0] + matrix[2][1] * temp[1]
+ + matrix[2][2] * temp[2];
+
+ return out;
+ }
+
+ public float[] toRGB(float[] in)
+ {
+ return SrgbConverter.XYZtoRGB(toCIEXYZ(in));
+ }
+
+ public float[] fromCIEXYZ(float[] in)
+ {
+ if (fromPCS != null)
+ return fromPCS.lookup(in);
+
+ float[] temp = new float[3];
+ float[] out = new float[3];
+
+ // matrix multiplication
+ temp[0] = inv_matrix[0][0] * in[0] + inv_matrix[0][1] * in[1]
+ + inv_matrix[0][2] * in[2];
+ temp[1] = inv_matrix[1][0] * in[0] + inv_matrix[1][1] * in[1]
+ + inv_matrix[1][2] * in[2];
+ temp[2] = inv_matrix[2][0] * in[0] + inv_matrix[2][1] * in[1]
+ + inv_matrix[2][2] * in[2];
+
+ // device space --> linear gamma
+ out[0] = rTRC.reverseLookup(temp[0]);
+ out[1] = gTRC.reverseLookup(temp[1]);
+ out[2] = bTRC.reverseLookup(temp[2]);
+
+ // FIXME: Sun appears to clip the return values to [0,1]
+ // I don't believe that is a Good Thing,
+ // (some colorspaces may allow values outside that range.)
+ // So we return the actual values here.
+ return out;
+ }
+
+ public float[] fromRGB(float[] in)
+ {
+ return fromCIEXYZ(SrgbConverter.RGBtoXYZ(in));
+ }
+
+ /**
+ * Inverts a 3x3 matrix, returns the inverse,
+ * throws an IllegalArgumentException if the matrix is not
+ * invertible (this shouldn't happen for a valid profile)
+ */
+ private float[][] invertMatrix(float[][] matrix)
+ {
+ float[][] out = new float[3][3];
+ double determinant = matrix[0][0] * (matrix[1][1] * matrix[2][2]
+ - matrix[2][1] * matrix[1][2])
+ - matrix[0][1] * (matrix[1][0] * matrix[2][2]
+ - matrix[2][0] * matrix[1][2])
+ + matrix[0][2] * (matrix[1][0] * matrix[2][1]
+ - matrix[2][0] * matrix[1][1]);
+
+ if (determinant == 0.0)
+ throw new IllegalArgumentException("Can't invert conversion matrix.");
+ float invdet = (float) (1.0 / determinant);
+
+ out[0][0] = invdet * (matrix[1][1] * matrix[2][2]
+ - matrix[1][2] * matrix[2][1]);
+ out[0][1] = invdet * (matrix[0][2] * matrix[2][1]
+ - matrix[0][1] * matrix[2][2]);
+ out[0][2] = invdet * (matrix[0][1] * matrix[1][2]
+ - matrix[0][2] * matrix[1][1]);
+ out[1][0] = invdet * (matrix[1][2] * matrix[2][0]
+ - matrix[1][0] * matrix[2][2]);
+ out[1][1] = invdet * (matrix[0][0] * matrix[2][2]
+ - matrix[0][2] * matrix[2][0]);
+ out[1][2] = invdet * (matrix[0][2] * matrix[1][0]
+ - matrix[0][0] * matrix[1][2]);
+ out[2][0] = invdet * (matrix[1][0] * matrix[2][1]
+ - matrix[1][1] * matrix[2][0]);
+ out[2][1] = invdet * (matrix[0][1] * matrix[2][0]
+ - matrix[0][0] * matrix[2][1]);
+ out[2][2] = invdet * (matrix[0][0] * matrix[1][1]
+ - matrix[0][1] * matrix[1][0]);
+ return out;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/color/SrgbConverter.java b/libjava/classpath/gnu/java/awt/color/SrgbConverter.java
new file mode 100644
index 0000000..a30a0db
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/SrgbConverter.java
@@ -0,0 +1,152 @@
+/* SrgbConverter.java -- sRGB conversion class
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+
+/**
+ * SrgbConverter - conversion routines for the sRGB colorspace
+ * sRGB is a standard for RGB colorspaces, adopted by the w3c.
+ *
+ * The specification is available at:
+ * http://www.w3.org/Graphics/Color/sRGB.html
+ *
+ * @author Sven de Marothy
+ */
+/**
+ *
+ * Note the matrix numbers used here are NOT identical to those in the
+ * w3 spec, as those numbers are CIE XYZ relative a D65 white point.
+ * The CIE XYZ we use is relative a D50 white point, so therefore a
+ * linear Bradford transform matrix for D65->D50 mapping has been applied.
+ * (The ICC documents describe this transform)
+ *
+ * Linearized Bradford transform:
+ * 0.8951 0.2664 -0.1614
+ * -0.7502 1.7135 0.0367
+ * 0.0389 -0.0685 1.0296
+ *
+ * Inverse:
+ * 0.9870 -0.1471 0.1600
+ * 0.4323 0.5184 0.0493
+ * -0.00853 0.0400 0.9685
+ */
+public class SrgbConverter implements ColorSpaceConverter
+{
+ public float[] fromCIEXYZ(float[] in)
+ {
+ return XYZtoRGB(in);
+ }
+
+ public float[] toCIEXYZ(float[] in)
+ {
+ return RGBtoXYZ(in);
+ }
+
+ public float[] toRGB(float[] in)
+ {
+ float[] out = new float[3];
+ System.arraycopy(in, 0, out, 0, 3);
+ return out;
+ }
+
+ public float[] fromRGB(float[] in)
+ {
+ float[] out = new float[3];
+ System.arraycopy(in, 0, out, 0, 3);
+ return out;
+ }
+
+ /**
+ * CIE XYZ (D50 relative) --> sRGB
+ *
+ * Static as it's used by other ColorSpaceConverters to
+ * convert to sRGB if the color space is defined in XYZ.
+ */
+ public static float[] XYZtoRGB(float[] in)
+ {
+ float[] temp = new float[3];
+ temp[0] = 3.1338f * in[0] - 1.6171f * in[1] - 0.4907f * in[2];
+ temp[1] = -0.9785f * in[0] + 1.9160f * in[1] + 0.0334f * in[2];
+ temp[2] = 0.0720f * in[0] - 0.2290f * in[1] + 1.4056f * in[2];
+
+ float[] out = new float[3];
+ for (int i = 0; i < 3; i++)
+ {
+ if (temp[i] < 0)
+ temp[i] = 0.0f;
+ if (temp[i] > 1)
+ temp[i] = 1.0f;
+ if (temp[i] <= 0.00304f)
+ out[i] = temp[i] * 12.92f;
+ else
+ out[i] = 1.055f * ((float) Math.exp((1 / 2.4) * Math.log(temp[i])))
+ - 0.055f;
+ }
+ return out;
+ }
+
+ /**
+ * sRGB --> CIE XYZ (D50 relative)
+ *
+ * Static as it's used by other ColorSpaceConverters to
+ * convert to XYZ if the color space is defined in RGB.
+ */
+ public static float[] RGBtoXYZ(float[] in)
+ {
+ float[] temp = new float[3];
+ float[] out = new float[3];
+ for (int i = 0; i < 3; i++)
+ if (in[i] <= 0.03928f)
+ temp[i] = in[i] / 12.92f;
+ else
+ temp[i] = (float) Math.exp(2.4 * Math.log((in[i] + 0.055) / 1.055));
+
+ /*
+ * Note: The numbers which were used to calculate this only had four
+ * digits of accuracy. So don't be fooled by the number of digits here.
+ * If someone has more accurate source, feel free to update this.
+ */
+ out[0] = (float) (0.436063750222 * temp[0] + 0.385149601465 * temp[1]
+ + 0.143086418888 * temp[2]);
+ out[1] = (float) (0.222450894035 * temp[0] + 0.71692584775 * temp[1]
+ + 0.060624511256 * temp[2]);
+ out[2] = (float) (0.0138985186 * temp[0] + 0.097079690112 * temp[1]
+ + 0.713996045725 * temp[2]);
+ return out;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/color/TagEntry.java b/libjava/classpath/gnu/java/awt/color/TagEntry.java
new file mode 100644
index 0000000..a978646
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/TagEntry.java
@@ -0,0 +1,121 @@
+/* TagEntry.java -- A utility class used for storing the tags in ICC_Profile
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+
+/**
+ * TagEntry - stores a profile tag.
+ * These are conveniently stored in a hashtable with the tag signature
+ * as a key. A legal profile can only have one tag with a given sig,
+ * so we can conveniently ignore collisions.
+ *
+ * @author Sven de Marothy
+ */
+public class TagEntry
+{
+ // tag table entry size
+ public static final int entrySize = 12;
+ private int signature;
+ private int size;
+ private int offset;
+ private byte[] data;
+
+ public TagEntry(int sig, int offset, int size, byte[] data)
+ {
+ this.signature = sig;
+ this.offset = offset;
+ this.size = size;
+ this.data = new byte[size];
+ System.arraycopy(data, offset, this.data, 0, size);
+ }
+
+ public TagEntry(int sig, byte[] data)
+ {
+ this.signature = sig;
+ this.size = data.length;
+ this.data = new byte[size];
+ System.arraycopy(data, offset, this.data, 0, size);
+ }
+
+ public byte[] getData()
+ {
+ byte[] d = new byte[size];
+ System.arraycopy(this.data, 0, d, 0, size);
+ return d;
+ }
+
+ public String hashKey()
+ {
+ return tagHashKey(signature);
+ }
+
+ public String toString()
+ {
+ String s = "";
+ s = s + (char) ((byte) ((signature >> 24) & 0xFF));
+ s = s + (char) ((byte) ((signature >> 16) & 0xFF));
+ s = s + (char) ((byte) ((signature >> 8) & 0xFF));
+ s = s + (char) ((byte) (signature & 0xFF));
+ return s;
+ }
+
+ public int getSignature()
+ {
+ return signature;
+ }
+
+ public int getSize()
+ {
+ return size;
+ }
+
+ public int getOffset()
+ {
+ return offset;
+ }
+
+ public void setOffset(int offset)
+ {
+ this.offset = offset;
+ }
+
+ public static String tagHashKey(int sig)
+ {
+ return "" + sig;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/color/ToneReproductionCurve.java b/libjava/classpath/gnu/java/awt/color/ToneReproductionCurve.java
new file mode 100644
index 0000000..a1bccbd
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/ToneReproductionCurve.java
@@ -0,0 +1,177 @@
+/* ToneReproductionCurve.java -- Representation of an ICC 'curv' type TRC
+ Copyright (C) 2004 Free Software Foundation
+
+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.color;
+
+
+/**
+ * ToneReproductionCurve - TRCs are used to describe RGB
+ * and Grayscale profiles. The TRC is essentially the gamma
+ * function of the color space.
+ *
+ * For example, Apple RGB has a gamma of 1.8, most monitors are ~2.2,
+ * sRGB is 2.4 with a small linear part near 0.
+ * Linear spaces are of course 1.0.
+ * (The exact function is implemented in SrgbConverter)
+ *
+ * The ICC specification allows the TRC to be described as a single
+ * Gamma value, where the function is thus out = in**gamma.
+ * Alternatively, the gamma function may be represented by a lookup table
+ * of values, in which case linear interpolation is used.
+ *
+ * @author Sven de Marothy
+ */
+public class ToneReproductionCurve
+{
+ private float[] trc;
+ private float gamma;
+ private float[] reverseTrc;
+
+ /**
+ * Constructs a TRC from a gamma values
+ */
+ public ToneReproductionCurve(float gamma)
+ {
+ trc = null;
+ reverseTrc = null;
+ this.gamma = gamma;
+ }
+
+ /**
+ * Constructs a TRC from a set of float values
+ */
+ public ToneReproductionCurve(float[] trcValues)
+ {
+ trc = new float[trcValues.length];
+ System.arraycopy(trcValues, 0, trc, 0, trcValues.length);
+ setupReverseTrc();
+ }
+
+ /**
+ * Constructs a TRC from a set of short values normalized to
+ * the 0-65535 range (as in the ICC profile file).
+ * (Note the values are treated as unsigned)
+ */
+ public ToneReproductionCurve(short[] trcValues)
+ {
+ trc = new float[trcValues.length];
+ for (int i = 0; i < trcValues.length; i++)
+ trc[i] = (float) ((int) trcValues[i] & (0xFFFF)) / 65535.0f;
+ setupReverseTrc();
+ }
+
+ /**
+ * Performs a TRC lookup
+ */
+ public float lookup(float in)
+ {
+ float out;
+
+ if (trc == null)
+ {
+ if (in == 0f)
+ return 0.0f;
+ return (float) Math.exp(gamma * Math.log(in));
+ }
+ else
+ {
+ double alpha = in * (trc.length - 1);
+ int index = (int) Math.floor(alpha);
+ alpha = alpha - (double) index;
+ if (index >= trc.length - 1)
+ return trc[trc.length - 1];
+ if (index <= 0)
+ return trc[0];
+ out = (float) (trc[index] * (1.0 - alpha) + trc[index + 1] * alpha);
+ }
+ return out;
+ }
+
+ /**
+ * Performs an reverse lookup
+ */
+ public float reverseLookup(float in)
+ {
+ float out;
+
+ if (trc == null)
+ {
+ if (in == 0f)
+ return 0.0f;
+ return (float) Math.exp((1.0 / gamma) * Math.log(in));
+ }
+ else
+ {
+ double alpha = in * (reverseTrc.length - 1);
+ int index = (int) Math.floor(alpha);
+ alpha = alpha - (double) index;
+ if (index >= reverseTrc.length - 1)
+ return reverseTrc[reverseTrc.length - 1];
+ if (index <= 0)
+ return reverseTrc[0];
+ out = (float) (reverseTrc[index] * (1.0 - alpha)
+ + reverseTrc[index + 1] * alpha);
+ }
+ return out;
+ }
+
+ /**
+ * Calculates a reverse-lookup table.
+ * We use a whopping 10,000 entries.. This is should be more than any
+ * real-life TRC table (typically around 256-1024) so we won't be losing
+ * any precision.
+ *
+ * This will of course generate completely invalid results if the curve
+ * is not monotonic and invertable. But what's the alternative?
+ */
+ public void setupReverseTrc()
+ {
+ reverseTrc = new float[10000];
+ int j = 0;
+ for (int i = 0; i < 10000; i++)
+ {
+ float n = ((float) i) / 10000f;
+ while (trc[j + 1] < n && j < trc.length - 2)
+ j++;
+
+ if (j == trc.length - 2)
+ reverseTrc[i] = trc[trc.length - 1];
+ else
+ reverseTrc[i] = (j + (n - trc[j]) / (trc[j + 1] - trc[j])) / ((float) trc.length);
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/color/package.html b/libjava/classpath/gnu/java/awt/color/package.html
new file mode 100644
index 0000000..c4705cc
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/color/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in gnu.java.awt.color package.
+ Copyright (C) 2005 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. -->
+
+<html>
+<head><title>GNU Classpath - gnu.java.awt.color</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/classpath/gnu/java/awt/doc-files/BitwiseXORComposite-1.png b/libjava/classpath/gnu/java/awt/doc-files/BitwiseXORComposite-1.png
new file mode 100644
index 0000000..588c910
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/doc-files/BitwiseXORComposite-1.png
Binary files differ
diff --git a/libjava/classpath/gnu/java/awt/image/ImageDecoder.java b/libjava/classpath/gnu/java/awt/image/ImageDecoder.java
new file mode 100644
index 0000000..141c854
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/image/ImageDecoder.java
@@ -0,0 +1,156 @@
+/* ImageDecoder.java --
+ Copyright (C) 1999, 2000, 2004 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.image;
+
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Vector;
+
+public abstract class ImageDecoder implements ImageProducer
+{
+ Vector consumers = new Vector ();
+ String filename;
+ URL url;
+ byte[] data;
+ int offset;
+ int length;
+ InputStream input;
+
+ static
+ {
+ // FIXME: there was some broken code here that looked like
+ // it wanted to rely on this property. I don't have any idea
+ // what it was intended to do.
+ // String endian = System.getProperties ().getProperty ("gnu.cpu.endian");
+ }
+
+ public ImageDecoder (String filename)
+ {
+ this.filename = filename;
+ }
+
+ public ImageDecoder (URL url)
+ {
+ this.url = url;
+ }
+
+ public ImageDecoder (InputStream is)
+ {
+ this.input = is;
+ }
+
+ public ImageDecoder (byte[] imagedata, int imageoffset, int imagelength)
+ {
+ data = imagedata;
+ offset = imageoffset;
+ length = imagelength;
+ }
+
+ public void addConsumer (ImageConsumer ic)
+ {
+ consumers.addElement (ic);
+ }
+
+ public boolean isConsumer (ImageConsumer ic)
+ {
+ return consumers.contains (ic);
+ }
+
+ public void removeConsumer (ImageConsumer ic)
+ {
+ consumers.removeElement (ic);
+ }
+
+ public void startProduction (ImageConsumer ic)
+ {
+ if (!isConsumer(ic))
+ addConsumer(ic);
+
+ Vector list = (Vector) consumers.clone ();
+ try
+ {
+ // Create the input stream here rather than in the
+ // ImageDecoder constructors so that exceptions cause
+ // imageComplete to be called with an appropriate error
+ // status.
+ if (input == null)
+ {
+ try
+ {
+ if (url != null)
+ input = url.openStream();
+ else
+ {
+ if (filename != null)
+ input = new FileInputStream (filename);
+ else
+ input = new ByteArrayInputStream (data, offset, length);
+ }
+ produce (list, input);
+ }
+ finally
+ {
+ input = null;
+ }
+ }
+ else
+ {
+ produce (list, input);
+ }
+ }
+ catch (Exception e)
+ {
+ for (int i = 0; i < list.size (); i++)
+ {
+ ImageConsumer ic2 = (ImageConsumer) list.elementAt (i);
+ ic2.imageComplete (ImageConsumer.IMAGEERROR);
+ }
+ }
+ }
+
+ public void requestTopDownLeftRightResend (ImageConsumer ic)
+ {
+ }
+
+ public abstract void produce (Vector v, InputStream is) throws IOException;
+}
diff --git a/libjava/classpath/gnu/java/awt/image/XBMDecoder.java b/libjava/classpath/gnu/java/awt/image/XBMDecoder.java
new file mode 100644
index 0000000..0793d8e
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/image/XBMDecoder.java
@@ -0,0 +1,155 @@
+/* XBMDecoder.java -- Decodes X-bitmaps
+ Copyright (C) 1999, 2004 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.image;
+
+import java.awt.image.ColorModel;
+import java.awt.image.ImageConsumer;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+public class XBMDecoder extends ImageDecoder
+{
+ BufferedReader reader;
+ static final ColorModel cm = ColorModel.getRGBdefault ();
+ static final int black = 0xff000000;
+ static final int transparent = 0x00000000;
+ static final int masktable[] = { 0x01, 0x02, 0x04, 0x08,
+ 0x10, 0x20, 0x40, 0x80 };
+
+ public XBMDecoder (String filename)
+ {
+ super (filename);
+ }
+
+ public XBMDecoder (URL url)
+ {
+ super (url);
+ }
+
+ public void produce (Vector v, InputStream is) throws IOException
+ {
+ reader = new BufferedReader (new InputStreamReader (is));
+ int width = -1, height = -1;
+
+ for (int i = 0; i < 2; i++)
+ {
+ String line = reader.readLine ();
+ StringTokenizer st = new StringTokenizer (line);
+
+ st.nextToken (); // #define
+ st.nextToken (); // name_[width|height]
+ if (i == 0)
+ width = Integer.parseInt (st.nextToken (), 10);
+ else
+ height = Integer.parseInt (st.nextToken (), 10);
+ }
+
+ for (int i = 0; i < v.size (); i++)
+ {
+ ImageConsumer ic = (ImageConsumer) v.elementAt (i);
+
+ ic.setDimensions (width, height);
+ ic.setColorModel (cm);
+ ic.setHints (ImageConsumer.COMPLETESCANLINES
+ | ImageConsumer.SINGLEFRAME
+ | ImageConsumer.SINGLEPASS
+ | ImageConsumer.TOPDOWNLEFTRIGHT);
+ }
+
+ /* skip to the byte array */
+ while (reader.read () != '{') { }
+
+ /* loop through each scanline */
+ for (int line = 0; line < height; line++)
+ {
+ int scanline[] = getScanline (reader, width);
+
+ for (int i = 0; i < v.size (); i++)
+ {
+ ImageConsumer ic = (ImageConsumer) v.elementAt (i);
+ ic.setPixels (0, 0 + line, width, 1, cm, scanline, 0, width);
+ }
+ }
+
+ /* tell each ImageConsumer that we're finished */
+ for (int i = 0; i < v.size (); i++)
+ {
+ ImageConsumer ic = (ImageConsumer) v.elementAt (i);
+ ic.imageComplete (ImageConsumer.STATICIMAGEDONE);
+ }
+ }
+
+ public static int[] getScanline (Reader in, int len) throws IOException
+ {
+ char byteStr[] = new char[2];
+ int scanline[] = new int[len];
+ int x = 0;
+
+ while (x < len)
+ {
+ int ch = in.read ();
+ if (ch == '0')
+ {
+ in.read (); // 'x'
+
+ byteStr[0] = (char) in.read ();
+ byteStr[1] = (char) in.read ();
+
+ int byteVal = Integer.parseInt (new String (byteStr), 16);
+
+ for (int i = 0; i < 8; i++, x++)
+ {
+ if (x == len) // condition occurs if bitmap is padded
+ return scanline;
+
+ scanline[x] = ((byteVal & masktable[i]) != 0) ?
+ black : transparent;
+ }
+ }
+ }
+
+ return scanline;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/image/package.html b/libjava/classpath/gnu/java/awt/image/package.html
new file mode 100644
index 0000000..8823367
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/image/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in gnu.java.awt.image package.
+ Copyright (C) 2005 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. -->
+
+<html>
+<head><title>GNU Classpath - gnu.java.awt.image</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/classpath/gnu/java/awt/package.html b/libjava/classpath/gnu/java/awt/package.html
new file mode 100644
index 0000000..1661685
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in gnu.java.awt package.
+ Copyright (C) 2005 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. -->
+
+<html>
+<head><title>GNU Classpath - gnu.java.awt</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java b/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java
new file mode 100644
index 0000000..78ab3a9
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java
@@ -0,0 +1,846 @@
+/* ClasspathFontPeer.java -- Font peer used by GNU Classpath.
+ Copyright (C) 2003, 2004 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;
+
+import gnu.java.awt.ClasspathToolkit;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Toolkit;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.LineMetrics;
+import java.awt.font.TextAttribute;
+import java.awt.font.TransformAttribute;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.peer.FontPeer;
+import java.text.AttributedCharacterIterator;
+import java.text.CharacterIterator;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * A peer for fonts that are used inside Classpath. The purpose of
+ * this interface is to abstract from platform-specific font handling
+ * in the Classpath implementation of java.awt.Font and related
+ * classes.
+ *
+ * <p><b>State kept by the peer:</b> a peer is generated for each Font
+ * object in the default implementation. If you wish to share peers between
+ * fonts, you will need to subclass both ClasspathFontPeer and
+ * {@link ClasspathToolKit}.</p>
+ *
+ * <p><b>Thread Safety:</b> Methods of this interface may be called
+ * from arbitrary threads at any time. Implementations of the
+ * <code>ClasspathFontPeer</code> interface are required to perform
+ * the necessary synchronization.</p>
+ *
+ * @see java.awt.Font#getPeer
+ * @see java.awt.Toolkit#getFontPeer
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ * @author Graydon Hoare (graydon@redhat.com)
+ */
+public abstract class ClasspathFontPeer
+ implements FontPeer
+{
+
+ /*************************************************************************/
+
+ /*
+ * Instance Variables
+ */
+
+ /**
+ * The 3 names of this font. all fonts have 3 names, some of which
+ * may be equal:
+ *
+ * logical -- name the font was constructed from
+ * family -- a designer or brand name (Helvetica)
+ * face -- specific instance of a design (Helvetica Regular)
+ *
+ * @see isLogicalFontName
+ */
+
+ protected String logicalName;
+ protected String familyName;
+ protected String faceName;
+
+ /**
+ * The font style, which is a combination (by OR-ing) of the font style
+ * constants PLAIN, BOLD and ITALIC, in this class.
+ */
+ protected int style;
+
+ /**
+ * The font point size. A point is 1/72 of an inch.
+ */
+ protected float size;
+
+ /**
+ * The affine transformation the font is currently subject to.
+ */
+ protected AffineTransform transform;
+
+ protected static ClasspathToolkit tk()
+ {
+ return (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
+ }
+
+ /*
+ * Confusingly, a Logical Font is a concept unrelated to
+ * a Font's Logical Name.
+ *
+ * A Logical Font is one of 6 built-in, abstract font types
+ * which must be supported by any java environment: SansSerif,
+ * Serif, Monospaced, Dialog, and DialogInput.
+ *
+ * A Font's Logical Name is the name the font was constructed
+ * from. This might be the name of a Logical Font, or it might
+ * be the name of a Font Face.
+ */
+
+ protected static boolean isLogicalFontName(String name)
+ {
+ String uname = name.toUpperCase ();
+ return (uname.equals ("SANSSERIF") ||
+ uname.equals ("SERIF") ||
+ uname.equals ("MONOSPACED") ||
+ uname.equals ("DIALOG") ||
+ uname.equals ("DIALOGINPUT"));
+ }
+
+ protected static String logicalFontNameToFaceName (String name)
+ {
+ String uname = name.toUpperCase ();
+ if (uname.equals("SANSSERIF"))
+ return "Helvetica";
+ else if (uname.equals ("SERIF"))
+ return "Times";
+ else if (uname.equals ("MONOSPACED"))
+ return "Courier";
+ else if (uname.equals ("DIALOG"))
+ return "Helvetica";
+ else if (uname.equals ("DIALOGINPUT"))
+ return "Helvetica";
+ else
+ return "Helvetica";
+ }
+
+ protected static String faceNameToFamilyName (String name)
+ {
+ return name;
+ }
+
+ public static void copyStyleToAttrs (int style, Map attrs)
+ {
+ if ((style & Font.BOLD) == Font.BOLD)
+ attrs.put (TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
+ else
+ attrs.put (TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
+
+ if ((style & Font.ITALIC) == Font.ITALIC)
+ attrs.put (TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+ else
+ attrs.put (TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
+ }
+
+ protected static void copyFamilyToAttrs (String fam, Map attrs)
+ {
+ if (fam != null)
+ attrs.put (TextAttribute.FAMILY, fam);
+ }
+
+ public static void copySizeToAttrs (float size, Map attrs)
+ {
+ attrs.put (TextAttribute.SIZE, new Float (size));
+ }
+
+ protected static void copyTransformToAttrs (AffineTransform trans, Map attrs)
+ {
+ if (trans != null)
+ attrs.put(TextAttribute.TRANSFORM, new TransformAttribute (trans));
+ }
+
+
+ protected void setStandardAttributes (String name, String family, int style,
+ float size, AffineTransform trans)
+ {
+ this.logicalName = name;
+
+ if (isLogicalFontName (name))
+ this.faceName = logicalFontNameToFaceName (name);
+ else
+ this.faceName = name;
+
+ if (family != null)
+ this.familyName = family;
+ else
+ this.familyName = faceNameToFamilyName (faceName);
+
+ this.style = style;
+ this.size = size;
+ this.transform = trans;
+ }
+
+
+ protected void setStandardAttributes (String name, Map attribs)
+ {
+ String family = this.familyName;
+ AffineTransform trans = this.transform;
+ float size = this.size;
+ int style = this.style;
+
+ if (attribs.containsKey (TextAttribute.FAMILY))
+ family = (String) attribs.get (TextAttribute.FAMILY);
+
+ if (name == null)
+ name = "SansSerif";
+
+ if (attribs.containsKey (TextAttribute.WEIGHT))
+ {
+ Float weight = (Float) attribs.get (TextAttribute.WEIGHT);
+ if (weight.floatValue () >= TextAttribute.WEIGHT_BOLD.floatValue ())
+ style += Font.BOLD;
+ }
+
+ if (attribs.containsKey (TextAttribute.POSTURE))
+ {
+ Float posture = (Float) attribs.get (TextAttribute.POSTURE);
+ if (posture.floatValue () >= TextAttribute.POSTURE_OBLIQUE.floatValue ())
+ style += Font.ITALIC;
+ }
+
+ if (attribs.containsKey (TextAttribute.SIZE))
+ {
+ Float sz = (Float) attribs.get (TextAttribute.SIZE);
+ size = sz.floatValue ();
+
+ // Pango doesn't accept 0 as a font size.
+ if (size < 1)
+ size = 1;
+ }
+ else
+ size = 12;
+
+ if (attribs.containsKey (TextAttribute.TRANSFORM))
+ {
+ TransformAttribute ta = (TransformAttribute)
+ attribs.get(TextAttribute.TRANSFORM);
+ trans = ta.getTransform ();
+ }
+
+ setStandardAttributes (name, family, style, size, trans);
+ }
+
+ protected void getStandardAttributes (Map attrs)
+ {
+ copyFamilyToAttrs (this.familyName, attrs);
+ copySizeToAttrs (this.size, attrs);
+ copyStyleToAttrs (this.style, attrs);
+ copyTransformToAttrs (this.transform, attrs);
+ }
+
+
+ /* Begin public API */
+
+ public ClasspathFontPeer (String name, Map attrs)
+ {
+ setStandardAttributes (name, attrs);
+ }
+
+ public ClasspathFontPeer (String name, int style, int size)
+ {
+ setStandardAttributes (name, (String)null, style,
+ (float)size, (AffineTransform)null);
+ }
+
+ /**
+ * Implementation of {@link Font#getName}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public String getName (Font font)
+ {
+ return logicalName;
+ }
+
+ /**
+ * Implementation of {@link Font#getFamily()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public String getFamily (Font font)
+ {
+ return familyName;
+ }
+
+ /**
+ * Implementation of {@link Font#getFamily(Locale)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public String getFamily (Font font, Locale lc)
+ {
+ return familyName;
+ }
+
+ /**
+ * Implementation of {@link Font#getFontName()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public String getFontName (Font font)
+ {
+ return faceName;
+ }
+
+ /**
+ * Implementation of {@link Font#getFontName(Locale)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public String getFontName (Font font, Locale lc)
+ {
+ return faceName;
+ }
+
+ /**
+ * Implementation of {@link Font#getSize}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public float getSize (Font font)
+ {
+ return size;
+ }
+
+ /**
+ * Implementation of {@link Font#isPlain}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public boolean isPlain (Font font)
+ {
+ return style == Font.PLAIN;
+ }
+
+ /**
+ * Implementation of {@link Font#isBold}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public boolean isBold (Font font)
+ {
+ return ((style & Font.BOLD) == Font.BOLD);
+ }
+
+ /**
+ * Implementation of {@link Font#isItalic}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public boolean isItalic (Font font)
+ {
+ return ((style & Font.ITALIC) == Font.ITALIC);
+ }
+
+ /**
+ * Implementation of {@link Font#deriveFont(int, float)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, int style, float size)
+ {
+ Map attrs = new HashMap ();
+ getStandardAttributes (attrs);
+ copyStyleToAttrs (style, attrs);
+ copySizeToAttrs (size, attrs);
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
+ * Implementation of {@link Font#deriveFont(float)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, float size)
+ {
+ Map attrs = new HashMap ();
+ getStandardAttributes (attrs);
+ copySizeToAttrs (size, attrs);
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
+ * Implementation of {@link Font#deriveFont(int)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, int style)
+ {
+ Map attrs = new HashMap ();
+ getStandardAttributes (attrs);
+ copyStyleToAttrs (style, attrs);
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
+ * Implementation of {@link Font#deriveFont(int, AffineTransform)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, int style, AffineTransform t)
+ {
+ Map attrs = new HashMap ();
+ getStandardAttributes (attrs);
+ copyStyleToAttrs (style, attrs);
+ copyTransformToAttrs (t, attrs);
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
+ * Implementation of {@link Font#deriveFont(AffineTransform)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, AffineTransform t)
+ {
+ Map attrs = new HashMap ();
+ getStandardAttributes (attrs);
+ copyTransformToAttrs (t, attrs);
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
+ * Implementation of {@link Font#deriveFont(Map)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, Map attrs)
+ {
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
+ * Implementation of {@link Font#getAttributes()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Map getAttributes (Font font)
+ {
+ HashMap h = new HashMap ();
+ getStandardAttributes (h);
+ return h;
+ }
+
+ /**
+ * Implementation of {@link Font#getAvailableAttributes()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public AttributedCharacterIterator.Attribute[] getAvailableAttributes(Font font)
+ {
+ AttributedCharacterIterator.Attribute a[] =
+ new AttributedCharacterIterator.Attribute[5];
+ a[0] = TextAttribute.FAMILY;
+ a[1] = TextAttribute.SIZE;
+ a[2] = TextAttribute.POSTURE;
+ a[3] = TextAttribute.WEIGHT;
+ a[4] = TextAttribute.TRANSFORM;
+ return a;
+ }
+
+ /**
+ * Implementation of {@link Font#getTransform()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public AffineTransform getTransform (Font font)
+ {
+ if (transform == null)
+ transform = new AffineTransform ();
+ return transform;
+ }
+
+ /**
+ * Implementation of {@link Font#isTransformed()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public boolean isTransformed (Font font)
+ {
+ return ! transform.isIdentity ();
+ }
+
+ /**
+ * Implementation of {@link Font#getItalicAngle()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public float getItalicAngle (Font font)
+ {
+ if ((style & Font.ITALIC) == Font.ITALIC)
+ return TextAttribute.POSTURE_OBLIQUE.floatValue ();
+ else
+ return TextAttribute.POSTURE_REGULAR.floatValue ();
+ }
+
+
+ /**
+ * Implementation of {@link Font#getStyle()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public int getStyle (Font font)
+ {
+ return style;
+ }
+
+
+
+
+ /* Remaining methods are abstract */
+
+ /**
+ * Implementation of {@link Font#canDisplay(char)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract boolean canDisplay (Font font, char c);
+
+ /**
+ * Implementation of {@link Font#canDisplay(String)},
+ * {@link Font#canDisplay(char [], int, int)}, and
+ * {@link Font#canDisplay(CharacterIterator, int, int)}.
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit);
+
+
+ /**
+ * Returns the name of this font face inside the family, for example
+ * <i>&#x201c;Light&#x201d;</i>.
+ *
+ * <p>This method is currently not used by {@link Font}. However,
+ * this name would be needed by any serious desktop publishing
+ * application.
+ *
+ * @param font the font whose sub-family name is requested.
+ *
+ * @param locale the locale for which to localize the name. If
+ * <code>locale</code> is <code>null</code>, the returned name is
+ * localized to the user&#x2019;s default locale.
+ *
+ * @return the name of the face inside its family, or
+ * <code>null</code> if the font does not provide a sub-family name.
+ */
+
+ public abstract String getSubFamilyName (Font font, Locale locale);
+
+
+ /**
+ * Implementation of {@link Font#getPSName()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract String getPostScriptName (Font font);
+
+
+ /**
+ * Implementation of {@link Font#getNumGlyphs()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract int getNumGlyphs (Font font);
+
+
+ /**
+ * Implementation of {@link Font#getMissingGlyphCode()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract int getMissingGlyphCode (Font font);
+
+
+ /**
+ * Implementation of {@link Font#getBaselineFor(char)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract byte getBaselineFor (Font font, char c);
+
+
+ /**
+ * Returns a name for the specified glyph. This is useful for
+ * generating PostScript or PDF files that embed some glyphs of a
+ * font. If the implementation follows glyph naming conventions
+ * specified by Adobe, search engines can extract the original text
+ * from the generated PostScript and PDF files.
+ *
+ * <p>This method is currently not used by GNU Classpath. However,
+ * it would be very useful for someone wishing to write a good
+ * PostScript or PDF stream provider for the
+ * <code>javax.print</code> package.
+ *
+ * <p><b>Names are not unique:</b> Under some rare circumstances,
+ * the same name can be returned for different glyphs. It is
+ * therefore recommended that printer drivers check whether the same
+ * name has already been returned for antoher glyph, and make the
+ * name unique by adding the string ".alt" followed by the glyph
+ * index.</p>
+ *
+ * <p>This situation would occur for an OpenType or TrueType font
+ * that has a <code>post</code> table of format 3 and provides a
+ * mapping from glyph IDs to Unicode sequences through a
+ * <code>Zapf</code> table. If the same sequence of Unicode
+ * codepoints leads to different glyphs (depending on contextual
+ * position, for example, or on typographic sophistication level),
+ * the same name would get synthesized for those glyphs. To avoid
+ * this, the font peer would have to go through the names of all
+ * glyphs, which would make this operation very inefficient with
+ * large fonts.
+ *
+ * @param font the font containing the glyph whose name is
+ * requested.
+ *
+ * @param glyphIndex the glyph whose name the caller wants to
+ * retrieve.
+ *
+ * @return the glyph name, or <code>null</code> if a font does not
+ * provide glyph names.
+ */
+
+ public abstract String getGlyphName (Font font, int glyphIndex);
+
+
+ /**
+ * Implementation of {@link
+ * Font#createGlyphVector(FontRenderContext, String)}, {@link
+ * Font#createGlyphVector(FontRenderContext, char[])}, and {@link
+ * Font#createGlyphVector(FontRenderContext, CharacterIterator)}.
+ *
+ * @param font the font object that the created GlyphVector will return
+ * when it gets asked for its font. This argument is needed because the
+ * public API of {@link GlyphVector} works with {@link java.awt.Font},
+ * not with font peers.
+ */
+
+ public abstract GlyphVector createGlyphVector (Font font,
+ FontRenderContext frc,
+ CharacterIterator ci);
+
+
+ /**
+ * Implementation of {@link Font#createGlyphVector(FontRenderContext,
+ * int[])}.
+ *
+ * @param font the font object that the created GlyphVector will return
+ * when it gets asked for its font. This argument is needed because the
+ * public API of {@link GlyphVector} works with {@link java.awt.Font},
+ * not with font peers.
+ */
+
+ public abstract GlyphVector createGlyphVector (Font font,
+ FontRenderContext ctx,
+ int[] glyphCodes);
+
+
+ /**
+ * Implementation of {@link Font#layoutGlyphVector(FontRenderContext,
+ * char[], int, int, int)}.
+ *
+ * @param font the font object that the created GlyphVector will return
+ * when it gets asked for its font. This argument is needed because the
+ * public API of {@link GlyphVector} works with {@link java.awt.Font},
+ * not with font peers.
+ */
+
+ public abstract GlyphVector layoutGlyphVector (Font font,
+ FontRenderContext frc,
+ char[] chars, int start,
+ int limit, int flags);
+
+
+ /**
+ * Implementation of {@link Font#getFontMetrics()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract FontMetrics getFontMetrics (Font font);
+
+
+ /**
+ * Implementation of {@link Font#hasUniformLineMetrics()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract boolean hasUniformLineMetrics (Font font);
+
+
+ /**
+ * Implementation of {@link Font#getLineMetrics(CharacterIterator, int,
+ * int, FontRenderContext)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract LineMetrics getLineMetrics (Font font,
+ CharacterIterator ci,
+ int begin, int limit,
+ FontRenderContext rc);
+
+ /**
+ * Implementation of {@link Font#getMaxCharBounds(FontRenderContext)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract Rectangle2D getMaxCharBounds (Font font,
+ FontRenderContext rc);
+
+ /**
+ * Implementation of {@link Font#getStringBounds(CharacterIterator, int,
+ * int, FontRenderContext)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract Rectangle2D getStringBounds (Font font,
+ CharacterIterator ci,
+ int begin, int limit,
+ FontRenderContext frc);
+
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java b/libjava/classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java
new file mode 100644
index 0000000..70df2ef
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java
@@ -0,0 +1,104 @@
+/* ClasspathTextLayoutPeer.java
+ Copyright (C) 2003 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;
+
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.font.TextHitInfo;
+import java.awt.font.TextLayout;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * @author Graydon Hoare
+ */
+
+public interface ClasspathTextLayoutPeer
+{
+ TextHitInfo getStrongCaret (TextHitInfo hit1,
+ TextHitInfo hit2);
+
+ void draw (Graphics2D g2, float x, float y);
+
+ byte getBaseline ();
+
+ boolean isLeftToRight ();
+ boolean isVertical ();
+
+ float getAdvance ();
+ float getAscent ();
+ float getDescent ();
+ float getLeading ();
+
+ int getCharacterCount ();
+ byte getCharacterLevel (int index);
+
+ float[] getBaselineOffsets ();
+ Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint);
+ Rectangle2D getBounds ();
+
+ float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds);
+ Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds);
+ Shape[] getCaretShapes (int offset, Rectangle2D bounds,
+ TextLayout.CaretPolicy policy);
+
+ Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint,
+ Rectangle2D bounds);
+ int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint,
+ TextHitInfo secondEndpoint);
+
+ TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy);
+ TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy);
+ TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds);
+ TextHitInfo getVisualOtherHit (TextHitInfo hit);
+
+ float getVisibleAdvance ();
+ Shape getOutline (AffineTransform tx);
+ Shape getVisualHighlightShape (TextHitInfo firstEndpoint,
+ TextHitInfo secondEndpoint,
+ Rectangle2D bounds);
+
+ TextLayout getJustifiedLayout (float justificationWidth);
+ void handleJustify (float justificationWidth);
+
+ Object clone ();
+ int hashCode ();
+ boolean equals (ClasspathTextLayoutPeer tl);
+ String toString ();
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/EmbeddedWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/EmbeddedWindowPeer.java
new file mode 100644
index 0000000..4c64a1d
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/EmbeddedWindowPeer.java
@@ -0,0 +1,47 @@
+/* EmbeddedWindowPeer.java -- Interface for window peers that may be
+ embedded into other applications
+ Copyright (C) 2003 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;
+
+import java.awt.peer.FramePeer;
+
+public interface EmbeddedWindowPeer extends FramePeer
+{
+ void embed (long handle);
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java b/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java
new file mode 100644
index 0000000..3bcaebc
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java
@@ -0,0 +1,298 @@
+/* GLightweightPeer.java --
+ Copyright (C) 2003, 2004 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;
+
+import java.awt.AWTEvent;
+import java.awt.AWTException;
+import java.awt.BufferCapabilities;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Toolkit;
+import java.awt.event.PaintEvent;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.VolatileImage;
+import java.awt.peer.ContainerPeer;
+import java.awt.peer.LightweightPeer;
+
+/*
+ * Another possible implementation strategy for lightweight peers is
+ * to make GLightweightPeer a placeholder class that implements
+ * LightweightPeer. Then the Component and Container classes could
+ * identify a peer as lightweight and handle it specially. The
+ * current approach is probably more clear but less efficient.
+ */
+
+/**
+ * A stub class that implements the ComponentPeer and ContainerPeer
+ * interfaces using callbacks into the Component and Container
+ * classes. GLightweightPeer allows the Component and Container
+ * classes to treat lightweight and heavyweight peers in the same way.
+ *
+ * Lightweight components are painted directly onto their parent
+ * containers through an Image object provided by the toolkit.
+ */
+public class GLightweightPeer
+ implements LightweightPeer, ContainerPeer
+{
+ private Component comp;
+
+ private Insets containerInsets;
+
+ public GLightweightPeer(Component comp)
+ {
+ this.comp = comp;
+ }
+
+ // -------- java.awt.peer.ContainerPeer implementation:
+
+ public Insets insets()
+ {
+ return getInsets ();
+ }
+
+ public Insets getInsets()
+ {
+ if (containerInsets == null)
+ containerInsets = new Insets (0,0,0,0);
+ return containerInsets;
+ }
+
+ public void beginValidate()
+ {
+ }
+
+ public void endValidate()
+ {
+ }
+
+ public void beginLayout()
+ {
+ }
+
+ public void endLayout()
+ {
+ }
+
+ public boolean isPaintPending()
+ {
+ return false;
+ }
+
+ // -------- java.awt.peer.ComponentPeer implementation:
+
+ public int checkImage(Image img, int width, int height, ImageObserver o)
+ {
+ return comp.getToolkit().checkImage(img, width, height, o);
+ }
+
+ public Image createImage(ImageProducer prod)
+ {
+ return comp.getToolkit().createImage(prod);
+ }
+
+ /* This method is not called. */
+ public Image createImage(int width, int height)
+ {
+ return null;
+ }
+
+ public void disable() {}
+
+ public void dispose() {}
+
+ public void enable() {}
+
+ public GraphicsConfiguration getGraphicsConfiguration()
+ {
+ return null;
+ }
+
+ public FontMetrics getFontMetrics(Font f)
+ {
+ return comp.getToolkit().getFontMetrics(f);
+ }
+
+ /* Returning null here tells the Component object that called us to
+ * use its parent's Graphics. */
+ public Graphics getGraphics()
+ {
+ return null;
+ }
+
+ public Point getLocationOnScreen()
+ {
+ Point parentLocation = comp.getParent().getLocationOnScreen();
+ return new Point (parentLocation.x + comp.getX(),
+ parentLocation.y + comp.getY());
+ }
+
+ public Dimension getMinimumSize()
+ {
+ return new Dimension(comp.getWidth(), comp.getHeight());
+ }
+
+ /* A lightweight component's preferred size is equivalent to its
+ * Component width and height values. */
+ public Dimension getPreferredSize()
+ {
+ return new Dimension(comp.getWidth(), comp.getHeight());
+ }
+
+ /* Returning null here tells the Component object that called us to
+ * use its parent's Toolkit. */
+ public Toolkit getToolkit()
+ {
+ return null;
+ }
+
+ public void handleEvent(AWTEvent e) {}
+
+ public void hide() {}
+
+ public boolean isFocusable()
+ {
+ return false;
+ }
+
+ public boolean isFocusTraversable()
+ {
+ return false;
+ }
+
+ public Dimension minimumSize()
+ {
+ return getMinimumSize();
+ }
+
+ public Dimension preferredSize()
+ {
+ return getPreferredSize();
+ }
+
+ public void paint(Graphics graphics) {}
+
+ public boolean prepareImage(Image img, int width, int height,
+ ImageObserver o)
+ {
+ return comp.getToolkit().prepareImage(img, width, height, o);
+ }
+
+ public void print(Graphics graphics) {}
+
+ public void repaint(long tm, int x, int y, int width, int height) {}
+
+ public void requestFocus() {}
+
+ public boolean requestFocus(Component source, boolean bool1, boolean bool2, long x)
+ {
+ return false;
+ }
+
+ public void reshape(int x, int y, int width, int height) {}
+
+ public void setBackground(Color color) {}
+
+ public void setBounds(int x, int y, int width, int height) {}
+
+ public void setCursor(Cursor cursor) {}
+
+ public void setEnabled(boolean enabled) {}
+
+ public void setEventMask(long eventMask) {}
+
+ public void setFont(Font font) {}
+
+ public void setForeground(Color color) {}
+
+ public void setVisible(boolean visible) {}
+
+ public void show() {}
+
+ public ColorModel getColorModel ()
+ {
+ return comp.getColorModel ();
+ }
+
+ public boolean isObscured()
+ {
+ return false;
+ }
+
+ public boolean canDetermineObscurity()
+ {
+ return false;
+ }
+
+ public void coalescePaintEvent(PaintEvent e) { }
+
+ public void updateCursorImmediately() { }
+
+ public VolatileImage createVolatileImage(int width, int height)
+ {
+ return null;
+ }
+
+ public boolean handlesWheelScrolling()
+ {
+ return false;
+ }
+
+ public void createBuffers(int x, BufferCapabilities capabilities)
+ throws AWTException { }
+
+ public Image getBackBuffer()
+ {
+ return null;
+ }
+
+ public void flip(BufferCapabilities.FlipContents contents) { }
+
+ public void destroyBuffers() { }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GThreadMutex.java b/libjava/classpath/gnu/java/awt/peer/gtk/GThreadMutex.java
new file mode 100644
index 0000000..e73df9e
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GThreadMutex.java
@@ -0,0 +1,109 @@
+/* GThreadMutex.java -- Implements a mutex object for glib's gthread
+ abstraction, for use with GNU Classpath's --portable-native-sync option.
+ This is used in gthread-jni.c
+
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.awt.peer.gtk;
+
+/** Implements a mutex object for glib's gthread
+ abstraction, for use with GNU Classpath's --portable-native-sync option.
+ This is used in gthread-jni.c.
+
+ We use this object to implement the POSIX semantics for Mutexes. They are
+ needed are needed for the function vector that is passed to glib's
+ g_thread subpackage's initialization function.
+
+ The GThreadMutex object itself serves as the Real Lock; if code has
+ entered the monitor for this GThreadMutex object (in Java language, if
+ it's synchronized on this object) then it holds the lock that this object
+ represents.
+
+ @author Steven Augart
+ May, 2004
+
+
+*/
+
+class GThreadMutex
+{
+ /** Might "lock" be locked? Is anyone waiting
+ to get that lock? How long is the queue?
+
+ If zero, nobody holds a lock on this GThreadMutex object, and nobody is
+ trying to get one. Before someone attempts to acquire a lock on this
+ object, they must increment potentialLockers. After they release their
+ lock on this object, they must decrement potentialLockers.
+
+ Access to this field is guarded by synchronizing on the object
+ <code>lockForPotentialLockers</code>.
+
+ After construction, we only access this field via JNI.
+ */
+ volatile int potentialLockers;
+
+ /** An object to synchronize to if you want to examine or modify the
+ <code>potentialLockers</code> field. Only hold this lock for brief
+ moments, just long enough to check or set the value of
+ <code>lockForPotentialLockers</code>.
+
+ We use this representation so that g_thread_mutex_trylock() will work
+ with the POSIX semantics. This is the only case in which you ever hold a
+ lock on <code>lockForPotentialLockers</code> while trying to get another
+ lock -- if you are the mutex_trylock() implementation, and you have just
+ checked that <code>potentialLockers</code> has the value zero. In that
+ case, mutex_trylock() holds the lock on lockForPotentialLockers so that
+ another thread calling mutex_trylock() or mutex_lock() won't increment
+ potentialLockers after we've checked it and before we've gained the lock
+ on the POSIX mutex. Of course, in that case the operation of gaining
+ the POSIX lock itself will succeed immediately, and once it has
+ succeeded, trylock releases lockForPotentialLockers right away,
+ incremented to 1 (one).
+
+ After construction, we only access this field via JNI.
+ */
+ Object lockForPotentialLockers;
+
+ GThreadMutex()
+ {
+ potentialLockers = 0;
+ lockForPotentialLockers = new Object();
+ }
+}
+// Local Variables:
+// c-file-style: "gnu"
+// End:
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java b/libjava/classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java
new file mode 100644
index 0000000..9a1b8e3
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java
@@ -0,0 +1,303 @@
+/* GThreadNativeMethodRunner.java -- Implements pthread_create(), under
+ glib's gthread abstraction, for use with GNU Classpath's
+ --portable-native-sync option.
+ This is used by gthread-jni.c
+
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.awt.peer.gtk;
+
+import java.lang.ref.WeakReference;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/** Implements pthread_create(), under glib's gthread abstraction, for use
+ with GNU Classpath's --portable-native-sync option. This is used in
+ gthread-jni.c
+
+ Also implements a registry for threads, mapping Thread objects to small
+ integers. The registry uses weak references for threads that aren't
+ joinable, so that they will be garbage collected.
+
+ There are a number of possible alternative implementations.
+
+
+ The rest of this comment consists of an answer to a question that was
+ raised on the commit-classpath mailing list:
+
+ Mark Wielaard wrote:
+
+ > Can't we assume that jobject and gpointer are both (void *) so we don't
+ > need the int <-> Thread (global jobject ref) mapping?
+ > Maybe there are platforms where jobject and gpointer aren't the same,
+ > but I guess that is pretty unlikely.
+
+
+ I agree with you on the pointer size issues. A gpointer is a void *, so
+ it's certainly guaranteed to be at least as large as any other
+ pointer. And a jobject is implicitly an opaque pointer (in Jikes RVM, we
+ use small integers, but we coerce them into the representation of a
+ pointer).
+
+ The int <==> Thread mapping addresses a different issue. I realize that I
+ did not document this properly (two and a half lines in thread_create),
+ and the point is subtle (at least to me; took me a while to figure out).
+
+ The int => Thread mapping always returns jobjects that are local
+ references, not global ones. This is because Thread objects need to be
+ able to go away and be garbage collected after the thread they refer to
+ has died.
+
+ If we keep a global object reference to a thread, then when do we delete
+ that global object reference? We have an answer in the case of GThread
+ objects that were explicitly created with the joinable attribute. It is
+ safe for us to maintain a global reference to any joinable thread, since
+ the joinable thread must linger (even if only in a zombie state)
+ until it's explicitly joined via a g_thread_join() call. The global ref
+ could be cleaned up at that point too.
+
+ However, in the case of GThreads that were created non-joinable by
+ g_thread_create(), and in the case of Java threads that were created
+ within pure Java code (not via g_thread_create()), we don't want them to
+ linger forever, and there is no way to tell when the last reference
+ to such threads needs to expire. In the case of this application -- AWT
+ with GTK peers -- it would probably be safe anyway, since there are not
+ very many threads we create, but I was going for correctness even in the
+ case of long-running programs that might set up and tear down AWT
+ interfaces many times.
+
+ So, I duplicated the POSIX thread-ID semantics. The thread ID of a
+ non-joinable thread remains valid as long as that thread is still alive.
+ Once that thread dies, the old thread ID may be reused at any moment. And
+ that's why the array indexed by thread ID numbers is an array of weak
+ references.
+
+ That's also why the int => Thread jobject mapping function always returns
+ local references, since global references would lock the Thread in memory
+ forever.
+
+ I would dearly love there to be a cleaner solution. I dislike the
+ repeated dips from C code into Java that are necessary to look up thread
+ ID numbers. If anyone can think of one, I'm all ears.
+*/
+
+class GThreadNativeMethodRunner
+ extends Thread
+{
+ /** The C function pointer that was passed to g_thread_create().
+ Specifically, this the numeric address of an object of
+ C type "void *(*funcPtr)(void *funcArg)".
+ */
+ private final long funcPtr;
+
+ /** The argument for the function "funcPtr(funcArg)". */
+ private final long funcArg;
+
+ GThreadNativeMethodRunner(long funcPtr, long funcArg, boolean joinable)
+ {
+ this.funcPtr = funcPtr;
+ this.funcArg = funcArg;
+
+ if (joinable)
+ registerSelfJoinable();
+ }
+
+ public void run()
+ {
+ nativeRun(funcPtr, funcArg);
+ }
+
+ private native void nativeRun(long funcPtr, long funcArg);
+
+ /** THREADS is an array of threads, indexed by thread ID codes. Not sure
+ whether this is the "best" approach but it does make it O(1) to look up a
+ thread by its ID.
+
+ Zero is a valid thread ID code. Any negative number is invalid.
+
+ Possible future fixes (TODO?)
+
+ - The THREADS array will only grow. probably not a problem.
+ But we could keep count when nulling entries and shrink when we have
+ lots of nulls at the end. Probably not worth it. --mjw
+
+ - Could make this a set of Object; see the comment on "joinable" below.
+
+ The initial size of 17 is just a starting point. Any number will do,
+ including zero.
+ */
+ private static WeakReference[] threads = new WeakReference[17];
+
+ /** Used by threadToThreadID, below. Returns the registration number of
+ the newly-registered thread.
+ */
+ private static synchronized int registerThread(Thread t)
+ {
+ int i;
+
+ for (i = 0; i < threads.length; ++i)
+ {
+ WeakReference ref = threads[i];
+ if (ref == null)
+ break; // found an empty spot.
+ }
+
+ if (i == threads.length)
+ {
+ /* expand the array */
+ WeakReference[] bigger = new WeakReference[threads.length * 2];
+ System.arraycopy(threads, 0, bigger, 0, threads.length);
+ threads = bigger;
+ }
+
+ threads[i] = new WeakReference(t);
+
+ return i;
+ }
+
+ /** Look up the Thread ID # for a Thread. Assign a Thread ID # if none
+ exists. This is a general routine for handling all threads, including
+ the VM's main thread, if appropriate.
+
+
+ Runs in O(n/2) time.
+
+ We can't just issue a threadID upon thread creation. If we were to do
+ that, not all threads would have a threadID, because not all threads
+ are launched by GThreadNativeMethodRunner.
+ */
+ static synchronized int threadToThreadID(Thread t)
+ {
+ for (int i = 0; i < threads.length; ++i )
+ {
+ if (threads[i] == null)
+ continue;
+ Thread referent = (Thread) threads[i].get();
+ if (referent == null)
+ {
+ threads[i] = null; // Purge the dead WeakReference.
+ continue;
+ }
+ if (referent.equals(t))
+ return i;
+ } // for()
+
+ /* No match found. */
+ return registerThread(t);
+ }
+
+ /** @param threadID Must be a non-negative integer.
+
+ Used to return null if the thread number was out of range or if
+ the thread was unregistered. Now we throw an exception.
+
+ Possible Alternative Interface: We could go back to returning null in
+ some sort of check-free mode, so code that calls this function must
+ be prepared to get null.
+ */
+ static Thread threadIDToThread(int threadID)
+ throws IllegalArgumentException
+ {
+ if (threadID < 0)
+ throw new IllegalArgumentException("Received a negative threadID, "
+ + threadID);
+ if (threadID >= threads.length)
+ throw new IllegalArgumentException("Received a threadID (" + threadID
+ + ") higher than was"
+ + " ever issued");
+
+ /* Note: if the user is using a stale reference, things will just
+ break. We might end up getting a different thread than the one
+ expected.
+
+ TODO: Add an error-checking mode where the user's problems with threads
+ are announced. For instance, if the user asks for the thread
+ associated with a threadID that was never issued, we could print a
+ warning or even abort.
+
+ TODO: Consider optionally disabling all of the error-checking we
+ already have; it probably slows down the implementation. We could
+ just return NULL. This is just the reverse of the above TODO item.
+ */
+
+ WeakReference threadRef = threads[threadID];
+
+ if (threadRef == null)
+ throw new IllegalArgumentException("Asked to look up a stale or unissued"
+ + "threadID (" + threadID + ")" );
+
+
+ Thread referent = (Thread) threadRef.get();
+ if (referent == null)
+ throw new IllegalArgumentException ("Asked to look up a stale threadID ("
+ + threadID + ")");
+ return referent;
+ }
+
+ /** Joinable threads need a hard reference, so that they won't go away when
+ they die. That is because their thread IDs need to stay valid until the
+ thread is joined via thread_join(threadID). Joinable threads have to be
+ explicitly joined before they are allowed to go away completely.
+
+ Possible Alternative Implementation: Eliminate the Joinable set. When
+ calling getThreadIDFromThread() you know whether or not the thread
+ is joinable. So just store the Thread itself in the threads array?
+ Make that array an Object array and check with instanceof. This
+ looks cleaner and more robust to me and it saves a native -> Java
+ call. But instanceof might be expensive. --mjw
+ */
+ private static final Set joinable =
+ Collections.synchronizedSet(new HashSet());
+
+ /** Only called from the constructor. */
+ private void registerSelfJoinable()
+ {
+ joinable.add(this);
+ }
+
+ /** This method is only called from JNI, and only after we have succeeded in
+ a thread_join() operation. */
+ static void deRegisterJoinable(Thread thread)
+ {
+ joinable.remove(thread);
+ }
+}
+
+// Local Variables:
+// c-file-style: "gnu"
+// End:
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java
new file mode 100644
index 0000000..7a439e8
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java
@@ -0,0 +1,134 @@
+/* GdkFontMetrics.java
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import gnu.java.awt.ClasspathToolkit;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Toolkit;
+
+public class GdkFontMetrics extends FontMetrics
+{
+
+ private int[] font_metrics;
+ GdkFontPeer peer;
+
+ static final int FONT_METRICS_ASCENT = 0;
+ static final int FONT_METRICS_MAX_ASCENT = 1;
+ static final int FONT_METRICS_DESCENT = 2;
+ static final int FONT_METRICS_MAX_DESCENT = 3;
+ static final int FONT_METRICS_MAX_ADVANCE = 4;
+
+ static final int TEXT_METRICS_X_BEARING = 0;
+ static final int TEXT_METRICS_Y_BEARING = 1;
+ static final int TEXT_METRICS_WIDTH = 2;
+ static final int TEXT_METRICS_HEIGHT = 3;
+ static final int TEXT_METRICS_X_ADVANCE = 4;
+ static final int TEXT_METRICS_Y_ADVANCE = 5;
+
+
+ public GdkFontMetrics (Font font)
+ {
+ super (font.getPeer() instanceof GdkFontPeer
+ ? font
+ : ((ClasspathToolkit)(Toolkit.getDefaultToolkit ()))
+ .getFont (font.getName(), font.getAttributes ()));
+
+ peer = (GdkFontPeer) this.font.getPeer();
+
+ font_metrics = new int[5];
+ double [] hires = new double[5];
+ peer.getFontMetrics (hires);
+ for (int i = 0; i < 5; ++i)
+ font_metrics[i] = (int) hires[i];
+ }
+
+ public int stringWidth (String str)
+ {
+ double [] hires = new double[6];
+ peer.getTextMetrics(str, hires);
+ return (int) hires [TEXT_METRICS_WIDTH];
+ }
+
+ public int charWidth (char ch)
+ {
+ return stringWidth (new String (new char[] { ch }));
+ }
+
+ public int charsWidth (char data[], int off, int len)
+ {
+ return stringWidth (new String (data, off, len));
+ }
+
+ /*
+ Sun's Motif implementation always returns 0 or 1 here (???), but
+ going by the X11 man pages, it seems as though we should return
+ font.ascent + font.descent.
+ */
+ public int getLeading ()
+ {
+ return 1;
+ }
+
+ public int getAscent ()
+ {
+ return font_metrics[FONT_METRICS_ASCENT];
+ }
+
+ public int getMaxAscent ()
+ {
+ return font_metrics[FONT_METRICS_MAX_ASCENT];
+ }
+
+ public int getDescent ()
+ {
+ return font_metrics[FONT_METRICS_DESCENT];
+ }
+
+ public int getMaxDescent ()
+ {
+ return font_metrics[FONT_METRICS_MAX_DESCENT];
+ }
+
+ public int getMaxAdvance ()
+ {
+ return font_metrics[FONT_METRICS_MAX_ADVANCE];
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java
new file mode 100644
index 0000000..c6d42b3
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java
@@ -0,0 +1,307 @@
+/* GdkFontPeer.java -- Implements FontPeer with GTK+
+ Copyright (C) 1999, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import gnu.classpath.Configuration;
+import gnu.java.awt.peer.ClasspathFontPeer;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.LineMetrics;
+import java.awt.geom.Rectangle2D;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+public class GdkFontPeer extends ClasspathFontPeer
+{
+ static native void initStaticState();
+ private final int native_state = GtkGenericPeer.getUniqueInteger ();
+ private static ResourceBundle bundle;
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("gtkpeer");
+ }
+
+ initStaticState ();
+
+ try
+ {
+ bundle = ResourceBundle.getBundle ("gnu.java.awt.peer.gtk.font");
+ }
+ catch (Throwable ignored)
+ {
+ bundle = null;
+ }
+ }
+
+ private native void initState ();
+ private native void dispose ();
+ private native void setFont (String family, int style, int size, boolean useGraphics2D);
+
+ native void getFontMetrics(double [] metrics);
+ native void getTextMetrics(String str, double [] metrics);
+
+ protected void finalize ()
+ {
+ if (GtkToolkit.useGraphics2D ())
+ GdkGraphics2D.releasePeerGraphicsResource(this);
+ dispose ();
+ }
+
+ /*
+ * Helpers for the 3-way overloading that this class seems to suffer
+ * from. Remove them if you feel like they're a performance bottleneck,
+ * for the time being I prefer my code not be written and debugged in
+ * triplicate.
+ */
+
+ private String buildString(CharacterIterator iter)
+ {
+ StringBuffer sb = new StringBuffer();
+ for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next())
+ sb.append(c);
+ return sb.toString();
+ }
+
+ private String buildString(CharacterIterator iter, int begin, int limit)
+ {
+ StringBuffer sb = new StringBuffer();
+ int i = 0;
+ for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next(), i++)
+ {
+ if (begin <= i)
+ sb.append(c);
+ if (limit <= i)
+ break;
+ }
+ return sb.toString();
+ }
+
+ private String buildString(char[] chars, int begin, int limit)
+ {
+ return new String(chars, begin, limit - begin);
+ }
+
+ /* Public API */
+
+ public GdkFontPeer (String name, int style)
+ {
+ // All fonts get a default size of 12 if size is not specified.
+ this(name, style, 12);
+ }
+
+ public GdkFontPeer (String name, int style, int size)
+ {
+ super(name, style, size);
+ initState ();
+ setFont (this.familyName, this.style, (int)this.size,
+ GtkToolkit.useGraphics2D());
+ }
+
+ public GdkFontPeer (String name, Map attributes)
+ {
+ super(name, attributes);
+ initState ();
+ setFont (this.familyName, this.style, (int)this.size,
+ GtkToolkit.useGraphics2D());
+ }
+
+ public String getSubFamilyName(Font font, Locale locale)
+ {
+ return null;
+ }
+
+ public String getPostScriptName(Font font)
+ {
+ return null;
+ }
+
+ public boolean canDisplay (Font font, char c)
+ {
+ // FIXME: inquire with pango
+ return true;
+ }
+
+ public int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit)
+ {
+ // FIXME: inquire with pango
+ return -1;
+ }
+
+ private native GdkGlyphVector getGlyphVector(String txt,
+ Font f,
+ FontRenderContext ctx);
+
+ public GlyphVector createGlyphVector (Font font,
+ FontRenderContext ctx,
+ CharacterIterator i)
+ {
+ return getGlyphVector(buildString (i), font, ctx);
+ }
+
+ public GlyphVector createGlyphVector (Font font,
+ FontRenderContext ctx,
+ int[] glyphCodes)
+ {
+ return null;
+ // return new GdkGlyphVector (font, this, ctx, glyphCodes);
+ }
+
+ public byte getBaselineFor (Font font, char c)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ protected class GdkFontLineMetrics extends LineMetrics
+ {
+ FontMetrics fm;
+ int nchars;
+
+ public GdkFontLineMetrics (FontMetrics m, int n)
+ {
+ fm = m;
+ nchars = n;
+ }
+
+ public float getAscent()
+ {
+ return (float) fm.getAscent ();
+ }
+
+ public int getBaselineIndex()
+ {
+ return Font.ROMAN_BASELINE;
+ }
+
+ public float[] getBaselineOffsets()
+ {
+ return new float[3];
+ }
+
+ public float getDescent()
+ {
+ return (float) fm.getDescent ();
+ }
+
+ public float getHeight()
+ {
+ return (float) fm.getHeight ();
+ }
+
+ public float getLeading() { return 0.f; }
+ public int getNumChars() { return nchars; }
+ public float getStrikethroughOffset() { return 0.f; }
+ public float getStrikethroughThickness() { return 0.f; }
+ public float getUnderlineOffset() { return 0.f; }
+ public float getUnderlineThickness() { return 0.f; }
+
+ }
+
+ public LineMetrics getLineMetrics (Font font, CharacterIterator ci,
+ int begin, int limit, FontRenderContext rc)
+ {
+ return new GdkFontLineMetrics (getFontMetrics (font), limit - begin);
+ }
+
+ public Rectangle2D getMaxCharBounds (Font font, FontRenderContext rc)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public int getMissingGlyphCode (Font font)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public String getGlyphName (Font font, int glyphIndex)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public int getNumGlyphs (Font font)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public Rectangle2D getStringBounds (Font font, CharacterIterator ci,
+ int begin, int limit, FontRenderContext frc)
+ {
+ GdkGlyphVector gv = getGlyphVector(buildString (ci, begin, limit), font, frc);
+ return gv.getVisualBounds();
+ }
+
+ public boolean hasUniformLineMetrics (Font font)
+ {
+ return true;
+ }
+
+ public GlyphVector layoutGlyphVector (Font font, FontRenderContext frc,
+ char[] chars, int start, int limit,
+ int flags)
+ {
+ int nchars = (limit - start) + 1;
+ char[] nc = new char[nchars];
+
+ for (int i = 0; i < nchars; ++i)
+ nc[i] = chars[start + i];
+
+ return createGlyphVector (font, frc,
+ new StringCharacterIterator (new String (nc)));
+ }
+
+ public LineMetrics getLineMetrics (Font font, String str,
+ FontRenderContext frc)
+ {
+ return new GdkFontLineMetrics (getFontMetrics (font), str.length ());
+ }
+
+ public FontMetrics getFontMetrics (Font font)
+ {
+ return new GdkFontMetrics (font);
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGlyphVector.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGlyphVector.java
new file mode 100644
index 0000000..f0ddea4
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGlyphVector.java
@@ -0,0 +1,359 @@
+/* GdkGlyphVector.java -- Glyph vector object
+ Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Font;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+public class GdkGlyphVector extends GlyphVector
+{
+
+ /* We use a simple representation for glyph vectors here. Glyph i
+ * consumes 8 doubles:
+ *
+ * logical x: extents[ 10*i ]
+ * logical y: extents[ 10*i + 1 ]
+ * logical width: extents[ 10*i + 2 ]
+ * logical height: extents[ 10*i + 3 ]
+ *
+ * visual x: extents[ 10*i + 4 ]
+ * visual y: extents[ 10*i + 5 ]
+ * visual width: extents[ 10*i + 6 ]
+ * visual height: extents[ 10*i + 7 ]
+ *
+ * origin pos x: extents[ 10*i + 8 ]
+ * origin pos y: extents[ 10*i + 9 ]
+ *
+ * as well as one int, code[i], representing the glyph code in the font.
+ */
+
+ double [] extents;
+ int [] codes;
+
+ Font font;
+ FontRenderContext fontRenderContext;
+
+ Rectangle2D allLogical;
+ Rectangle2D allVisual;
+
+ public GdkGlyphVector(double[] extents, int[] codes, Font font, FontRenderContext frc)
+ {
+ this.extents = extents;
+ this.codes = codes;
+ this.font = font;
+ this.fontRenderContext = frc;
+
+ allLogical = new Rectangle2D.Double();
+ allVisual = new Rectangle2D.Double();
+
+ for (int i = 0; i < codes.length; ++i)
+ {
+ allLogical.add (new Rectangle2D.Double(extents[10*i ] + extents[10*i + 8],
+ extents[10*i + 1] + extents[10*i + 9],
+ extents[10*i + 2],
+ extents[10*i + 3]));
+
+ allVisual.add (new Rectangle2D.Double(extents[10*i + 4] + extents[10*i + 8],
+ extents[10*i + 5] + extents[10*i + 9],
+ extents[10*i + 6],
+ extents[10*i + 7]));
+ }
+ }
+
+ /*
+ geometric notes:
+
+ the FRC contains a mapping from points -> pixels.
+
+ typographics points are typically 1/72 of an inch.
+
+ pixel displays are often around 72 dpi.
+
+ so the FRC can get away with using an identity transform on a screen,
+ often. behavior is documented by sun to fall back to an identity
+ transform if the internal transformation is null.
+
+ coordinates coming up from pango are expressed as floats -- in device
+ space, so basically pixels-with-fractional-bits -- derived from their
+ storage format in pango (1024ths of pixels).
+
+ it is not clear from the javadocs whether the results of methods like
+ getGlyphPositions ought to return coordinates in device space, or
+ "point" space, or what. for now I'm returning them in device space.
+
+ */
+
+ public double[] getExtents()
+ {
+ return extents;
+ }
+
+ public int[] getCodes()
+ {
+ return codes;
+ }
+
+ public Font getFont ()
+ {
+ return font;
+ }
+
+ public FontRenderContext getFontRenderContext ()
+ {
+ return fontRenderContext;
+ }
+
+ public int getGlyphCharIndex (int glyphIndex)
+ {
+ // FIXME: currently pango does not provide glyph-by-glyph
+ // reverse mapping information, so we assume a broken 1:1
+ // glyph model here. This is plainly wrong.
+ return glyphIndex;
+ }
+
+ public int[] getGlyphCharIndices (int beginGlyphIndex,
+ int numEntries,
+ int[] codeReturn)
+ {
+ int ix[] = codeReturn;
+ if (ix == null)
+ ix = new int[numEntries];
+
+ for (int i = 0; i < numEntries; i++)
+ ix[i] = getGlyphCharIndex (beginGlyphIndex + i);
+ return ix;
+ }
+
+ public int getGlyphCode (int glyphIndex)
+ {
+ return codes[glyphIndex];
+ }
+
+ public int[] getGlyphCodes (int beginGlyphIndex, int numEntries,
+ int[] codeReturn)
+ {
+ if (codeReturn == null)
+ codeReturn = new int[numEntries];
+
+ System.arraycopy(codes, beginGlyphIndex, codeReturn, 0, numEntries);
+ return codeReturn;
+ }
+
+ public Shape getGlyphLogicalBounds (int i)
+ {
+ return new Rectangle2D.Double (extents[8*i], extents[8*i + 1],
+ extents[8*i + 2], extents[8*i + 3]);
+ }
+
+ public GlyphMetrics getGlyphMetrics (int i)
+ {
+ // FIXME: pango does not yield vertical layout information at the
+ // moment.
+
+ boolean is_horizontal = true;
+ double advanceX = extents[8*i + 2]; // "logical width" == advanceX
+ double advanceY = 0;
+
+ return new GlyphMetrics (is_horizontal,
+ (float) advanceX, (float) advanceY,
+ (Rectangle2D) getGlyphVisualBounds(i),
+ GlyphMetrics.STANDARD);
+ }
+
+ public Shape getGlyphOutline (int glyphIndex)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public Shape getGlyphOutline (int glyphIndex, float x, float y)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public Rectangle getGlyphPixelBounds (int i,
+ FontRenderContext renderFRC,
+ float x, float y)
+ {
+ return new Rectangle((int) x, (int) y,
+ (int) extents[8*i + 6], (int) extents[8*i + 7]);
+ }
+
+ public Point2D getGlyphPosition (int i)
+ {
+ return new Point2D.Double (extents[10*i + 8],
+ extents[10*i + 9]);
+ }
+
+ public float[] getGlyphPositions (int beginGlyphIndex,
+ int numEntries,
+ float[] positionReturn)
+ {
+ float fx[] = positionReturn;
+ if (fx == null)
+ fx = new float[numEntries * 2];
+
+ for (int i = 0; i < numEntries; ++i)
+ {
+ fx[2*i ] = (float) extents[10*i + 8];
+ fx[2*i + 1] = (float) extents[10*i + 9];
+ }
+ return fx;
+ }
+
+ public AffineTransform getGlyphTransform (int glyphIndex)
+ {
+ // Glyphs don't have independent transforms in these simple glyph
+ // vectors; docs specify null is an ok return here.
+ return null;
+ }
+
+ public Shape getGlyphVisualBounds (int i)
+ {
+ return new Rectangle2D.Double(extents[8*i + 4], extents[8*i + 5],
+ extents[8*i + 6], extents[8*i + 7]);
+ }
+
+ public int getLayoutFlags ()
+ {
+ return 0;
+ }
+
+ public Rectangle2D getLogicalBounds ()
+ {
+ return allLogical;
+ }
+
+ public int getNumGlyphs ()
+ {
+ return codes.length;
+ }
+
+ public Shape getOutline ()
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public Rectangle getPixelBounds (FontRenderContext renderFRC,
+ float x, float y)
+ {
+ return new Rectangle((int)x,
+ (int)y,
+ (int) allVisual.getWidth(),
+ (int) allVisual.getHeight());
+ }
+
+ public Rectangle2D getVisualBounds ()
+ {
+ return allVisual;
+ }
+
+ public void performDefaultLayout ()
+ {
+ }
+
+ public void setGlyphPosition (int i, Point2D newPos)
+ {
+ extents[8*i ] = newPos.getX();
+ extents[8*i + 1] = newPos.getY();
+
+ extents[8*i + 4] = newPos.getX();
+ extents[8*i + 5] = newPos.getY();
+ }
+
+ public void setGlyphTransform (int glyphIndex,
+ AffineTransform newTX)
+ {
+ // not yet.. maybe not ever?
+ throw new UnsupportedOperationException ();
+ }
+
+ public boolean equals(GlyphVector gv)
+ {
+ if (gv == null)
+ return false;
+
+ if (! (gv instanceof GdkGlyphVector))
+ return false;
+
+ GdkGlyphVector ggv = (GdkGlyphVector) gv;
+
+ if ((ggv.codes.length != this.codes.length)
+ || (ggv.extents.length != this.extents.length))
+ return false;
+
+ if ((ggv.font == null && this.font != null)
+ || (ggv.font != null && this.font == null)
+ || (!ggv.font.equals(this.font)))
+ return false;
+
+ if ((ggv.fontRenderContext == null && this.fontRenderContext != null)
+ || (ggv.fontRenderContext != null && this.fontRenderContext == null)
+ || (!ggv.fontRenderContext.equals(this.fontRenderContext)))
+ return false;
+
+ for (int i = 0; i < ggv.codes.length; ++i)
+ if (ggv.codes[i] != this.codes[i])
+ return false;
+
+ for (int i = 0; i < ggv.extents.length; ++i)
+ if (ggv.extents[i] != this.extents[i])
+ return false;
+
+ return true;
+ }
+
+ public GlyphJustificationInfo getGlyphJustificationInfo(int idx)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public Shape getOutline(float x, float y)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java
new file mode 100644
index 0000000..a125be7
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java
@@ -0,0 +1,388 @@
+/* GdkGraphics.java
+ Copyright (C) 1998, 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Color;
+import java.awt.Dimension;
+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.SystemColor;
+import java.awt.image.ImageObserver;
+import java.text.AttributedCharacterIterator;
+
+public class GdkGraphics extends Graphics
+{
+ private final int native_state = GtkGenericPeer.getUniqueInteger();
+
+ Color color, xorColor;
+ GtkComponentPeer component;
+ Font font;
+ Rectangle clip;
+ GtkImage image;
+
+ int xOffset = 0;
+ int yOffset = 0;
+
+ static final int GDK_COPY = 0, GDK_XOR = 2;
+
+ native void initState (GtkComponentPeer component);
+ native void initState (int width, int height);
+ native void initFromImage (GtkImage image);
+ native void copyState (GdkGraphics g);
+
+ GdkGraphics (GdkGraphics g)
+ {
+ color = g.color;
+ xorColor = g.xorColor;
+ font = g.font;
+ clip = new Rectangle (g.clip);
+ component = g.component;
+
+ copyState (g);
+ }
+
+ GdkGraphics (int width, int height)
+ {
+ initState (width, height);
+ color = Color.black;
+ clip = new Rectangle (0, 0, width, height);
+ font = new Font ("Dialog", Font.PLAIN, 12);
+ }
+
+ GdkGraphics (GtkImage image)
+ {
+ this.image = image;
+ initFromImage (image);
+ color = Color.black;
+ clip = new Rectangle (0, 0,
+ image.getWidth(null), image.getHeight(null));
+ font = new Font ("Dialog", Font.PLAIN, 12);
+ }
+
+ GdkGraphics (GtkComponentPeer component)
+ {
+ this.component = component;
+ font = component.awtComponent.getFont ();
+ color = Color.black;
+
+ if (component.isRealized ())
+ initComponentGraphics ();
+ else
+ connectSignals (component);
+ }
+
+ void initComponentGraphics ()
+ {
+ initState (component);
+ color = component.awtComponent.getForeground ();
+ Dimension d = component.awtComponent.getSize ();
+ clip = new Rectangle (0, 0, d.width, d.height);
+ }
+
+ native void connectSignals (GtkComponentPeer component);
+
+ public native void clearRect(int x, int y, int width, int height);
+
+ public void clipRect (int x, int y, int width, int height)
+ {
+ if (component != null && ! component.isRealized ())
+ return;
+
+ clip = clip.intersection (new Rectangle (x, y, width, height));
+ setClipRectangle (clip.x, clip.y, clip.width, clip.height);
+ }
+
+ public native void copyArea(int x, int y, int width, int height,
+ int dx, int dy);
+
+ public Graphics create ()
+ {
+ return new GdkGraphics (this);
+ }
+
+ public native void dispose();
+
+ public boolean drawImage (Image img, int x, int y,
+ Color bgcolor, ImageObserver observer)
+ {
+ return drawImage(img, x, y, img.getWidth(null), img.getHeight(null),
+ bgcolor, observer);
+ }
+
+ public boolean drawImage (Image img, int x, int y, ImageObserver observer)
+ {
+ return drawImage (img, x, y, null, observer);
+ }
+
+ public boolean drawImage (Image img, int x, int y, int width, int height,
+ Color bgcolor, ImageObserver observer)
+ {
+ if (img instanceof GtkImage)
+ return ((GtkImage)img).drawImage (this, x, y, width, height,
+ bgcolor, observer);
+ else
+ return (new GtkImage(img.getSource())).drawImage (this, x, y,
+ width, height,
+ bgcolor, observer);
+ }
+
+ public boolean drawImage (Image img, int x, int y, int width, int height,
+ ImageObserver observer)
+ {
+ return drawImage (img, x, y, width, height, null, observer);
+ }
+
+ public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2,
+ Color bgcolor, ImageObserver observer)
+ {
+ if (img instanceof GtkImage)
+ return ((GtkImage)img).drawImage(this, dx1, dy1, dx2, dy2,
+ sx1, sy1, sx2, sy2, bgcolor, observer);
+ else
+ return (new GtkImage(img.getSource())).drawImage(this, dx1, dy1,
+ dx2, dy2,
+ sx1, sy1, sx2, sy2,
+ bgcolor, observer);
+ }
+
+ public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2,
+ ImageObserver observer)
+ {
+ return drawImage (img, dx1, dy1, dx2, dy2,
+ sx1, sy1, sx2, sy2,
+ null, observer);
+ }
+
+ public native void drawLine(int x1, int y1, int x2, int y2);
+
+ public native void drawArc(int x, int y, int width, int height,
+ int startAngle, int arcAngle);
+ public native void fillArc(int x, int y, int width, int height,
+ int startAngle, int arcAngle);
+ public native void drawOval(int x, int y, int width, int height);
+ public native void fillOval(int x, int y, int width, int height);
+
+ public native void drawPolygon(int[] xPoints, int[] yPoints, int nPoints);
+ public native void fillPolygon(int[] xPoints, int[] yPoints, int nPoints);
+
+ public native void drawPolyline(int[] xPoints, int[] yPoints, int nPoints);
+
+ public native void drawRect(int x, int y, int width, int height);
+ public native void fillRect(int x, int y, int width, int height);
+
+ GdkFontPeer getFontPeer()
+ {
+ return (GdkFontPeer) getFont().getPeer();
+ }
+
+ native void drawString (GdkFontPeer f, String str, int x, int y);
+ public void drawString (String str, int x, int y)
+ {
+ drawString(getFontPeer(), str, x, y);
+ }
+
+
+ public void drawString (AttributedCharacterIterator ci, int x, int y)
+ {
+ throw new Error ("not implemented");
+ }
+
+ public void drawRoundRect(int x, int y, int width, int height,
+ int arcWidth, int arcHeight)
+ {
+ if (arcWidth > width)
+ arcWidth = width;
+ if (arcHeight > height)
+ arcHeight = height;
+
+ int xx = x + width - arcWidth;
+ int yy = y + height - arcHeight;
+
+ drawArc (x, y, arcWidth, arcHeight, 90, 90);
+ drawArc (xx, y, arcWidth, arcHeight, 0, 90);
+ drawArc (xx, yy, arcWidth, arcHeight, 270, 90);
+ drawArc (x, yy, arcWidth, arcHeight, 180, 90);
+
+ int y1 = y + arcHeight / 2;
+ int y2 = y + height - arcHeight / 2;
+ drawLine (x, y1, x, y2);
+ drawLine (x + width, y1, x + width, y2);
+
+ int x1 = x + arcWidth / 2;
+ int x2 = x + width - arcWidth / 2;
+ drawLine (x1, y, x2, y);
+ drawLine (x1, y + height, x2, y + height);
+ }
+
+ public void fillRoundRect (int x, int y, int width, int height,
+ int arcWidth, int arcHeight)
+ {
+ if (arcWidth > width)
+ arcWidth = width;
+ if (arcHeight > height)
+ arcHeight = height;
+
+ int xx = x + width - arcWidth;
+ int yy = y + height - arcHeight;
+
+ fillArc (x, y, arcWidth, arcHeight, 90, 90);
+ fillArc (xx, y, arcWidth, arcHeight, 0, 90);
+ fillArc (xx, yy, arcWidth, arcHeight, 270, 90);
+ fillArc (x, yy, arcWidth, arcHeight, 180, 90);
+
+ fillRect (x, y + arcHeight / 2, width, height - arcHeight + 1);
+ fillRect (x + arcWidth / 2, y, width - arcWidth + 1, height);
+ }
+
+ public Shape getClip ()
+ {
+ return getClipBounds ();
+ }
+
+ public Rectangle getClipBounds ()
+ {
+ if (clip == null)
+ return null;
+ else
+ return clip.getBounds();
+ }
+
+ public Color getColor ()
+ {
+ return color;
+ }
+
+ public Font getFont ()
+ {
+ return font;
+ }
+
+ public FontMetrics getFontMetrics (Font font)
+ {
+ return new GdkFontMetrics (font);
+ }
+
+ native void setClipRectangle (int x, int y, int width, int height);
+
+ public void setClip (int x, int y, int width, int height)
+ {
+ if ((component != null && ! component.isRealized ())
+ || clip == null)
+ return;
+
+ clip.x = x;
+ clip.y = y;
+ clip.width = width;
+ clip.height = height;
+
+ setClipRectangle (x, y, width, height);
+ }
+
+ public void setClip (Rectangle clip)
+ {
+ setClip (clip.x, clip.y, clip.width, clip.height);
+ }
+
+ public void setClip (Shape clip)
+ {
+ if (clip != null)
+ setClip(clip.getBounds());
+ }
+
+ private native void setFGColor(int red, int green, int blue);
+
+ public void setColor (Color c)
+ {
+ if (c == null)
+ color = Color.BLACK;
+ else
+ color = c;
+
+ if (xorColor == null) /* paint mode */
+ setFGColor (color.getRed (), color.getGreen (), color.getBlue ());
+ else /* xor mode */
+ setFGColor (color.getRed () ^ xorColor.getRed (),
+ color.getGreen () ^ xorColor.getGreen (),
+ color.getBlue () ^ xorColor.getBlue ());
+ }
+
+ public void setFont (Font font)
+ {
+ this.font = font;
+ }
+
+ native void setFunction (int gdk_func);
+
+ public void setPaintMode ()
+ {
+ xorColor = null;
+
+ setFunction (GDK_COPY);
+ setFGColor (color.getRed (), color.getGreen (), color.getBlue ());
+ }
+
+ public void setXORMode (Color c)
+ {
+ xorColor = c;
+
+ setFunction (GDK_XOR);
+ setFGColor (color.getRed () ^ xorColor.getRed (),
+ color.getGreen () ^ xorColor.getGreen (),
+ color.getBlue () ^ xorColor.getBlue ());
+ }
+
+ public native void translateNative(int x, int y);
+
+ public void translate (int x, int y)
+ {
+ if (component != null && ! component.isRealized ())
+ return;
+
+ clip.x -= x;
+ clip.y -= y;
+
+ translateNative (x, y);
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java
new file mode 100644
index 0000000..b820317
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java
@@ -0,0 +1,1453 @@
+/* GdkGraphics2D.java --
+ Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import gnu.classpath.Configuration;
+import gnu.java.awt.ClasspathToolkit;
+
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.GradientPaint;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Paint;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.TexturePaint;
+import java.awt.Toolkit;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ColorModel;
+import java.awt.image.CropImageFilter;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DirectColorModel;
+import java.awt.image.FilteredImageSource;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImagingOpException;
+import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.awt.image.renderable.RenderContext;
+import java.awt.image.renderable.RenderableImage;
+import java.text.AttributedCharacterIterator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+
+public class GdkGraphics2D extends Graphics2D
+{
+ //////////////////////////////////////
+ ////// State Management Methods //////
+ //////////////////////////////////////
+
+ static
+ {
+ if (! Configuration.GTK_CAIRO_ENABLED)
+ throw new Error("Grahics2D not implemented. "
+ + "Cairo was not found or disabled at configure time");
+
+ if (Configuration.INIT_LOAD_LIBRARY)
+ System.loadLibrary("gtkpeer");
+
+ if (GtkToolkit.useGraphics2D())
+ initStaticState();
+ }
+
+ static native void initStaticState();
+
+ private final int native_state = GtkGenericPeer.getUniqueInteger();
+
+ // These are package-private to avoid accessor methods.
+ Paint paint;
+ Stroke stroke;
+ Color fg;
+ Color bg;
+ Shape clip;
+ AffineTransform transform;
+ private GtkComponentPeer component;
+ // This is package-private to avoid an accessor method.
+ Font font;
+ private RenderingHints hints;
+ private BufferedImage bimage;
+ private boolean pixelConversionRequired;
+ private int[] pixelBuffer;
+ // This is package-private to avoid an accessor method.
+ Composite comp;
+ private Stack stateStack;
+
+ private native void initState(GtkComponentPeer component);
+ private native void initState(int width, int height);
+ private native void initState(int[] pixes, int width, int height);
+ private native void copyState(GdkGraphics2D g);
+ public native void dispose();
+ private native void cairoSurfaceSetFilter(int filter);
+ native void connectSignals(GtkComponentPeer component);
+
+ public void finalize()
+ {
+ dispose();
+ }
+
+ public Graphics create()
+ {
+ return new GdkGraphics2D(this);
+ }
+
+ public Graphics create(int x, int y, int width, int height)
+ {
+ return new GdkGraphics2D(width, height);
+ }
+
+ GdkGraphics2D(GdkGraphics2D g)
+ {
+ paint = g.paint;
+ stroke = g.stroke;
+ setRenderingHints(g.hints);
+
+ if (g.fg.getAlpha() != -1)
+ fg = new Color(g.fg.getRed(), g.fg.getGreen(), g.fg.getBlue(),
+ g.fg.getAlpha());
+ else
+ fg = new Color(g.fg.getRGB());
+
+ if (g.bg.getAlpha() != -1)
+ bg = new Color(g.bg.getRed(), g.bg.getGreen(), g.bg.getBlue(),
+ g.bg.getAlpha());
+ else
+ bg = new Color(g.bg.getRGB());
+
+ if (g.clip == null)
+ clip = null;
+ else
+ clip = new Rectangle(g.getClipBounds());
+
+ if (g.transform == null)
+ transform = new AffineTransform();
+ else
+ transform = new AffineTransform(g.transform);
+
+ font = g.font;
+ component = g.component;
+ copyState(g);
+
+ setColor(fg);
+ setBackground(bg);
+ setPaint(paint);
+ setStroke(stroke);
+ setTransform(transform);
+ setClip(clip);
+ stateStack = new Stack();
+ }
+
+ GdkGraphics2D(int width, int height)
+ {
+ initState(width, height);
+
+ setColor(Color.black);
+ setBackground(new Color(0, 0, 0, 0));
+ setPaint(getColor());
+ setFont(new Font("SansSerif", Font.PLAIN, 12));
+ setTransform(new AffineTransform());
+ setStroke(new BasicStroke());
+ setRenderingHints(getDefaultHints());
+
+ stateStack = new Stack();
+ }
+
+ GdkGraphics2D(GtkComponentPeer component)
+ {
+ this.component = component;
+
+ if (component.isRealized())
+ initComponentGraphics2D();
+ else
+ connectSignals(component);
+ }
+
+ void initComponentGraphics2D()
+ {
+ initState(component);
+
+ setColor(component.awtComponent.getForeground());
+ setBackground(component.awtComponent.getBackground());
+ setPaint(getColor());
+ setTransform(new AffineTransform());
+ setStroke(new BasicStroke());
+ setRenderingHints(getDefaultHints());
+ setFont(new Font("SansSerif", Font.PLAIN, 12));
+
+ stateStack = new Stack();
+ }
+
+ GdkGraphics2D(BufferedImage bimage)
+ {
+ this.bimage = bimage;
+ this.pixelBuffer = findSimpleIntegerArray(bimage.getColorModel(),
+ bimage.getRaster());
+ if (this.pixelBuffer == null)
+ {
+ this.pixelBuffer = new int[bimage.getRaster().getWidth() * bimage.getRaster()
+ .getHeight()];
+ this.pixelConversionRequired = true;
+ }
+ else
+ {
+ this.pixelConversionRequired = false;
+ }
+
+ initState(this.pixelBuffer, bimage.getWidth(), bimage.getHeight());
+
+ setColor(Color.black);
+ setBackground(new Color(0, 0, 0, 0));
+ setPaint(getColor());
+ setFont(new Font("SansSerif", Font.PLAIN, 12));
+ setTransform(new AffineTransform());
+ setStroke(new BasicStroke());
+ setRenderingHints(getDefaultHints());
+
+ stateStack = new Stack();
+
+ // draw current buffered image to the pixmap associated
+ // with it, if the image is not equal to our paint buffer.
+ if (pixelConversionRequired)
+ drawImage(bimage, new AffineTransform(1, 0, 0, 1, 0, 0), bg, null);
+ }
+
+ ////////////////////////////////////
+ ////// Native Drawing Methods //////
+ ////////////////////////////////////
+
+ // GDK drawing methods
+ private native void gdkDrawDrawable(GdkGraphics2D other, int x, int y);
+
+ // drawing utility methods
+ private native void drawPixels(int[] pixels, int w, int h, int stride,
+ double[] i2u);
+ private native void setTexturePixels(int[] pixels, int w, int h, int stride);
+ private native void setGradient(double x1, double y1, double x2, double y2,
+ int r1, int g1, int b1, int a1, int r2,
+ int g2, int b2, int a2, boolean cyclic);
+
+ // simple passthroughs to cairo
+ private native void cairoSave();
+ private native void cairoRestore();
+ private native void cairoSetMatrix(double[] m);
+ private native void cairoSetOperator(int cairoOperator);
+ private native void cairoSetRGBAColor(double red, double green,
+ double blue, double alpha);
+ private native void cairoSetFillRule(int cairoFillRule);
+ private native void cairoSetLineWidth(double width);
+ private native void cairoSetLineCap(int cairoLineCap);
+ private native void cairoSetLineJoin(int cairoLineJoin);
+ private native void cairoSetDash(double[] dashes, int ndash, double offset);
+
+ private native void cairoSetMiterLimit(double limit);
+ private native void cairoNewPath();
+ private native void cairoMoveTo(double x, double y);
+ private native void cairoLineTo(double x, double y);
+ private native void cairoCurveTo(double x1, double y1, double x2, double y2,
+ double x3, double y3);
+ private native void cairoRelMoveTo(double dx, double dy);
+ private native void cairoRelLineTo(double dx, double dy);
+ private native void cairoRelCurveTo(double dx1, double dy1, double dx2,
+ double dy2, double dx3, double dy3);
+ private native void cairoRectangle(double x, double y, double width,
+ double height);
+ private native void cairoClosePath();
+ private native void cairoStroke();
+ private native void cairoFill();
+ private native void cairoClip();
+
+ /////////////////////////////////////////////
+ ////// General Drawing Support Methods //////
+ /////////////////////////////////////////////
+
+ private class DrawState
+ {
+ private Paint paint;
+ private Stroke stroke;
+ private Color fg;
+ private Color bg;
+ private Shape clip;
+ private AffineTransform transform;
+ private Font font;
+ private Composite comp;
+
+ DrawState(GdkGraphics2D g)
+ {
+ this.paint = g.paint;
+ this.stroke = g.stroke;
+ this.fg = g.fg;
+ this.bg = g.bg;
+ this.clip = g.clip;
+ if (g.transform != null)
+ this.transform = (AffineTransform) g.transform.clone();
+ this.font = g.font;
+ this.comp = g.comp;
+ }
+
+ public void restore(GdkGraphics2D g)
+ {
+ g.paint = this.paint;
+ g.stroke = this.stroke;
+ g.fg = this.fg;
+ g.bg = this.bg;
+ g.clip = this.clip;
+ g.transform = this.transform;
+ g.font = this.font;
+ g.comp = this.comp;
+ }
+ }
+
+ private void stateSave()
+ {
+ stateStack.push(new DrawState(this));
+ cairoSave();
+ }
+
+ private void stateRestore()
+ {
+ ((DrawState) (stateStack.pop())).restore(this);
+ cairoRestore();
+ }
+
+ // Some operations (drawing rather than filling) require that their
+ // coords be shifted to land on 0.5-pixel boundaries, in order to land on
+ // "middle of pixel" coordinates and light up complete pixels.
+ private boolean shiftDrawCalls = false;
+
+ private double shifted(double coord, boolean doShift)
+ {
+ if (doShift)
+ return Math.floor(coord) + 0.5;
+ else
+ return coord;
+ }
+
+ private void walkPath(PathIterator p, boolean doShift)
+ {
+ double x = 0;
+ double y = 0;
+ double[] coords = new double[6];
+
+ cairoSetFillRule(p.getWindingRule());
+ for (; ! p.isDone(); p.next())
+ {
+ int seg = p.currentSegment(coords);
+ switch (seg)
+ {
+ case PathIterator.SEG_MOVETO:
+ x = shifted(coords[0], doShift);
+ y = shifted(coords[1], doShift);
+ cairoMoveTo(x, y);
+ break;
+ case PathIterator.SEG_LINETO:
+ x = shifted(coords[0], doShift);
+ y = shifted(coords[1], doShift);
+ cairoLineTo(x, y);
+ break;
+ case PathIterator.SEG_QUADTO:
+ // splitting a quadratic bezier into a cubic:
+ // see: http://pfaedit.sourceforge.net/bezier.html
+ double x1 = x + (2.0 / 3.0) * (shifted(coords[0], doShift) - x);
+ double y1 = y + (2.0 / 3.0) * (shifted(coords[1], doShift) - y);
+
+ double x2 = x1 + (1.0 / 3.0) * (shifted(coords[2], doShift) - x);
+ double y2 = y1 + (1.0 / 3.0) * (shifted(coords[3], doShift) - y);
+
+ x = shifted(coords[2], doShift);
+ y = shifted(coords[3], doShift);
+ cairoCurveTo(x1, y1, x2, y2, x, y);
+ break;
+ case PathIterator.SEG_CUBICTO:
+ x = shifted(coords[4], doShift);
+ y = shifted(coords[5], doShift);
+ cairoCurveTo(shifted(coords[0], doShift),
+ shifted(coords[1], doShift),
+ shifted(coords[2], doShift),
+ shifted(coords[3], doShift), x, y);
+ break;
+ case PathIterator.SEG_CLOSE:
+ cairoClosePath();
+ break;
+ }
+ }
+ }
+
+ private Map getDefaultHints()
+ {
+ HashMap defaultHints = new HashMap();
+
+ defaultHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
+
+ defaultHints.put(RenderingHints.KEY_STROKE_CONTROL,
+ RenderingHints.VALUE_STROKE_DEFAULT);
+
+ defaultHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
+ RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
+
+ defaultHints.put(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_OFF);
+
+ defaultHints.put(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_DEFAULT);
+
+ return defaultHints;
+ }
+
+ public static int[] findSimpleIntegerArray (ColorModel cm, Raster raster)
+ {
+ if (cm == null || raster == null)
+ return null;
+
+ if (! cm.getColorSpace().isCS_sRGB())
+ return null;
+
+ if (! (cm instanceof DirectColorModel))
+ return null;
+
+ DirectColorModel dcm = (DirectColorModel) cm;
+
+ if (dcm.getRedMask() != 0x00FF0000 || dcm.getGreenMask() != 0x0000FF00
+ || dcm.getBlueMask() != 0x000000FF)
+ return null;
+
+ if (! (raster instanceof WritableRaster))
+ return null;
+
+ if (raster.getSampleModel().getDataType() != DataBuffer.TYPE_INT)
+ return null;
+
+ if (! (raster.getDataBuffer() instanceof DataBufferInt))
+ return null;
+
+ DataBufferInt db = (DataBufferInt) raster.getDataBuffer();
+
+ if (db.getNumBanks() != 1)
+ return null;
+
+ // Finally, we have determined that this is a single bank, [A]RGB-int
+ // buffer in sRGB space. It's worth checking all this, because it means
+ // that cairo can paint directly into the data buffer, which is very
+ // fast compared to all the normal copying and converting.
+
+ return db.getData();
+ }
+
+ private void updateBufferedImage()
+ {
+ if (bimage != null && pixelConversionRequired)
+ {
+ int height = bimage.getHeight();
+ int width = bimage.getWidth();
+ int index = 0;
+ for (int y = 0; y < height; ++y)
+ for (int x = 0; x < width; ++x)
+ bimage.setRGB(x, y, pixelBuffer[index++]);
+ }
+ }
+
+ private boolean drawImage(Image img, AffineTransform xform,
+ Color bgcolor, ImageObserver obs)
+ {
+ if (img == null)
+ return false;
+
+ // FIXME: I'll fix this, /Sven
+// if (img instanceof GtkOffScreenImage
+// && img.getGraphics() instanceof GdkGraphics2D
+// && (xform == null || xform.getType() == AffineTransform.TYPE_IDENTITY
+// || xform.getType() == AffineTransform.TYPE_TRANSLATION))
+// {
+// // we are being asked to flush a double buffer from Gdk
+// GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics();
+// gdkDrawDrawable(g2, (int) xform.getTranslateX(),
+// (int) xform.getTranslateY());
+
+// updateBufferedImage();
+
+// return true;
+// }
+// else
+ {
+ // In this case, xform is an AffineTransform that transforms bounding
+ // box of the specified image from image space to user space. However
+ // when we pass this transform to cairo, cairo will use this transform
+ // to map "user coordinates" to "pixel" coordinates, which is the
+ // other way around. Therefore to get the "user -> pixel" transform
+ // that cairo wants from "image -> user" transform that we currently
+ // have, we will need to invert the transformation matrix.
+ AffineTransform invertedXform = new AffineTransform();
+
+ try
+ {
+ invertedXform = xform.createInverse();
+ if (img instanceof BufferedImage)
+ {
+ // draw an image which has actually been loaded
+ // into memory fully
+ BufferedImage b = (BufferedImage) img;
+ return drawRaster(b.getColorModel(), b.getTile(0, 0),
+ invertedXform, bgcolor);
+ }
+ else
+ return this.drawImage(GdkPixbufDecoder.createBufferedImage(img
+ .getSource()),
+ xform, bgcolor, obs);
+ }
+ catch (NoninvertibleTransformException e)
+ {
+ throw new ImagingOpException("Unable to invert transform "
+ + xform.toString());
+ }
+ }
+ }
+
+ //////////////////////////////////////////////////
+ ////// Implementation of Graphics2D Methods //////
+ //////////////////////////////////////////////////
+
+ public void draw(Shape s)
+ {
+ if (stroke != null && ! (stroke instanceof BasicStroke))
+ {
+ fill(stroke.createStrokedShape(s));
+ return;
+ }
+
+ cairoNewPath();
+
+ if (s instanceof Rectangle2D)
+ {
+ Rectangle2D r = (Rectangle2D) s;
+ cairoRectangle(shifted(r.getX(), shiftDrawCalls),
+ shifted(r.getY(), shiftDrawCalls), r.getWidth(),
+ r.getHeight());
+ }
+ else
+ walkPath(s.getPathIterator(null), shiftDrawCalls);
+ cairoStroke();
+
+ updateBufferedImage();
+ }
+
+ public void fill(Shape s)
+ {
+ cairoNewPath();
+ if (s instanceof Rectangle2D)
+ {
+ Rectangle2D r = (Rectangle2D) s;
+ cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+ else
+ walkPath(s.getPathIterator(null), false);
+
+ cairoFill();
+
+ updateBufferedImage();
+ }
+
+ public void clip(Shape s)
+ {
+ // update it
+ if (clip == null || s == null)
+ clip = s;
+ else if (s instanceof Rectangle2D && clip instanceof Rectangle2D)
+ {
+ Rectangle2D r = (Rectangle2D) s;
+ Rectangle2D curr = (Rectangle2D) clip;
+ clip = curr.createIntersection(r);
+ }
+ else
+ throw new UnsupportedOperationException();
+
+ // draw it
+ if (clip != null)
+ {
+ cairoNewPath();
+ if (clip instanceof Rectangle2D)
+ {
+ Rectangle2D r = (Rectangle2D) clip;
+ cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+ else
+ walkPath(clip.getPathIterator(null), false);
+
+ // cairoClosePath ();
+ cairoClip();
+ }
+ }
+
+ public Paint getPaint()
+ {
+ return paint;
+ }
+
+ public AffineTransform getTransform()
+ {
+ return (AffineTransform) transform.clone();
+ }
+
+ public void setPaint(Paint p)
+ {
+ if (paint == null)
+ return;
+
+ paint = p;
+ if (paint instanceof Color)
+ {
+ setColor((Color) paint);
+ }
+ else if (paint instanceof TexturePaint)
+ {
+ TexturePaint tp = (TexturePaint) paint;
+ BufferedImage img = tp.getImage();
+
+ // map the image to the anchor rectangle
+ int width = (int) tp.getAnchorRect().getWidth();
+ int height = (int) tp.getAnchorRect().getHeight();
+
+ double scaleX = width / (double) img.getWidth();
+ double scaleY = width / (double) img.getHeight();
+
+ AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0);
+ AffineTransformOp op = new AffineTransformOp(at, getRenderingHints());
+ BufferedImage texture = op.filter(img, null);
+ int[] pixels = texture.getRGB(0, 0, width, height, null, 0, width);
+ setTexturePixels(pixels, width, height, width);
+ }
+ else if (paint instanceof GradientPaint)
+ {
+ GradientPaint gp = (GradientPaint) paint;
+ Point2D p1 = gp.getPoint1();
+ Point2D p2 = gp.getPoint2();
+ Color c1 = gp.getColor1();
+ Color c2 = gp.getColor2();
+ setGradient(p1.getX(), p1.getY(), p2.getX(), p2.getY(), c1.getRed(),
+ c1.getGreen(), c1.getBlue(), c1.getAlpha(), c2.getRed(),
+ c2.getGreen(), c2.getBlue(), c2.getAlpha(), gp.isCyclic());
+ }
+ else
+ throw new java.lang.UnsupportedOperationException();
+ }
+
+ public void setTransform(AffineTransform tx)
+ {
+ transform = tx;
+ if (transform != null)
+ {
+ double[] m = new double[6];
+ transform.getMatrix(m);
+ cairoSetMatrix(m);
+ }
+ }
+
+ public void transform(AffineTransform tx)
+ {
+ if (transform == null)
+ transform = new AffineTransform(tx);
+ else
+ transform.concatenate(tx);
+ setTransform(transform);
+ if (clip != null)
+ {
+ // FIXME: this should actuall try to transform the shape
+ // rather than degrade to bounds.
+ Rectangle2D r = clip.getBounds2D();
+ double[] coords = new double[]
+ {
+ r.getX(), r.getY(), r.getX() + r.getWidth(),
+ r.getY() + r.getHeight()
+ };
+ try
+ {
+ tx.createInverse().transform(coords, 0, coords, 0, 2);
+ r.setRect(coords[0], coords[1], coords[2] - coords[0],
+ coords[3] - coords[1]);
+ clip = r;
+ }
+ catch (java.awt.geom.NoninvertibleTransformException e)
+ {
+ }
+ }
+ }
+
+ public void rotate(double theta)
+ {
+ transform(AffineTransform.getRotateInstance(theta));
+ }
+
+ public void rotate(double theta, double x, double y)
+ {
+ transform(AffineTransform.getRotateInstance(theta, x, y));
+ }
+
+ public void scale(double sx, double sy)
+ {
+ transform(AffineTransform.getScaleInstance(sx, sy));
+ }
+
+ public void translate(double tx, double ty)
+ {
+ transform(AffineTransform.getTranslateInstance(tx, ty));
+ }
+
+ public void translate(int x, int y)
+ {
+ translate((double) x, (double) y);
+ }
+
+ public void shear(double shearX, double shearY)
+ {
+ transform(AffineTransform.getShearInstance(shearX, shearY));
+ }
+
+ public Stroke getStroke()
+ {
+ return stroke;
+ }
+
+ public void setStroke(Stroke st)
+ {
+ stroke = st;
+ if (stroke instanceof BasicStroke)
+ {
+ BasicStroke bs = (BasicStroke) stroke;
+ cairoSetLineCap(bs.getEndCap());
+ cairoSetLineWidth(bs.getLineWidth());
+ cairoSetLineJoin(bs.getLineJoin());
+ cairoSetMiterLimit(bs.getMiterLimit());
+ float[] dashes = bs.getDashArray();
+ if (dashes != null)
+ {
+ double[] double_dashes = new double[dashes.length];
+ for (int i = 0; i < dashes.length; i++)
+ double_dashes[i] = dashes[i];
+ cairoSetDash(double_dashes, double_dashes.length,
+ (double) bs.getDashPhase());
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////
+ ////// Implementation of Graphics Methods //////
+ ////////////////////////////////////////////////
+
+ public void setPaintMode()
+ {
+ setComposite(java.awt.AlphaComposite.SrcOver);
+ }
+
+ public void setXORMode(Color c)
+ {
+ setComposite(new gnu.java.awt.BitwiseXORComposite(c));
+ }
+
+ public void setColor(Color c)
+ {
+ if (c == null)
+ c = Color.BLACK;
+
+ fg = c;
+ paint = c;
+ cairoSetRGBAColor(fg.getRed() / 255.0, fg.getGreen() / 255.0,
+ fg.getBlue() / 255.0, fg.getAlpha() / 255.0);
+ }
+
+ public Color getColor()
+ {
+ return fg;
+ }
+
+ public void clipRect(int x, int y, int width, int height)
+ {
+ clip(new Rectangle(x, y, width, height));
+ }
+
+ public Shape getClip()
+ {
+ return clip.getBounds2D(); //getClipInDevSpace();
+ }
+
+ public Rectangle getClipBounds()
+ {
+ if (clip == null)
+ return null;
+ else
+ return clip.getBounds();
+ }
+
+ protected Rectangle2D getClipInDevSpace()
+ {
+ Rectangle2D uclip = clip.getBounds2D();
+ if (transform == null)
+ return uclip;
+ else
+ {
+ Point2D pos = transform.transform(new Point2D.Double(uclip.getX(),
+ uclip.getY()),
+ (Point2D) null);
+ Point2D extent = transform.deltaTransform(new Point2D.Double(uclip
+ .getWidth(),
+ uclip
+ .getHeight()),
+ (Point2D) null);
+ return new Rectangle2D.Double(pos.getX(), pos.getY(), extent.getX(),
+ extent.getY());
+ }
+ }
+
+ public void setClip(int x, int y, int width, int height)
+ {
+ setClip(new Rectangle2D.Double((double) x, (double) y, (double) width,
+ (double) height));
+ }
+
+ public void setClip(Shape s)
+ {
+ clip = s;
+ if (s != null)
+ {
+ cairoNewPath();
+ if (s instanceof Rectangle2D)
+ {
+ Rectangle2D r = (Rectangle2D) s;
+ cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight());
+ }
+ else
+ walkPath(s.getPathIterator(null), false);
+
+ // cairoClosePath ();
+ cairoClip();
+ }
+ }
+
+ private static BasicStroke draw3DRectStroke = new BasicStroke();
+
+ public void draw3DRect(int x, int y, int width, int height, boolean raised)
+ {
+ Stroke tmp = stroke;
+ setStroke(draw3DRectStroke);
+ super.draw3DRect(x, y, width, height, raised);
+ setStroke(tmp);
+ updateBufferedImage();
+ }
+
+ public void fill3DRect(int x, int y, int width, int height, boolean raised)
+ {
+ Stroke tmp = stroke;
+ setStroke(draw3DRectStroke);
+ super.fill3DRect(x, y, width, height, raised);
+ setStroke(tmp);
+ updateBufferedImage();
+ }
+
+ public void drawRect(int x, int y, int width, int height)
+ {
+ draw(new Rectangle(x, y, width, height));
+ }
+
+ public void fillRect(int x, int y, int width, int height)
+ {
+ cairoNewPath();
+ cairoRectangle(x, y, width, height);
+ cairoFill();
+ }
+
+ public void clearRect(int x, int y, int width, int height)
+ {
+ cairoSetRGBAColor(bg.getRed() / 255.0, bg.getGreen() / 255.0,
+ bg.getBlue() / 255.0, 1.0);
+ cairoNewPath();
+ cairoRectangle(x, y, width, height);
+ cairoFill();
+ setColor(fg);
+
+ updateBufferedImage();
+ }
+
+ public void setBackground(Color c)
+ {
+ bg = c;
+ }
+
+ public Color getBackground()
+ {
+ return bg;
+ }
+
+ private void doPolygon(int[] xPoints, int[] yPoints, int nPoints,
+ boolean close, boolean fill)
+ {
+ if (nPoints < 1)
+ return;
+ GeneralPath gp = new GeneralPath(PathIterator.WIND_EVEN_ODD);
+ gp.moveTo((float) xPoints[0], (float) yPoints[0]);
+ for (int i = 1; i < nPoints; i++)
+ gp.lineTo((float) xPoints[i], (float) yPoints[i]);
+
+ if (close)
+ gp.closePath();
+
+ Shape sh = gp;
+ if (fill == false && stroke != null && ! (stroke instanceof BasicStroke))
+ {
+ sh = stroke.createStrokedShape(gp);
+ fill = true;
+ }
+
+ if (fill)
+ fill(sh);
+ else
+ draw(sh);
+ }
+
+ public void drawLine(int x1, int y1, int x2, int y2)
+ {
+ int[] xp = new int[2];
+ int[] yp = new int[2];
+
+ xp[0] = x1;
+ xp[1] = x2;
+ yp[0] = y1;
+ yp[1] = y2;
+
+ doPolygon(xp, yp, 2, false, false);
+ }
+
+ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ doPolygon(xPoints, yPoints, nPoints, true, true);
+ }
+
+ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ doPolygon(xPoints, yPoints, nPoints, true, false);
+ }
+
+ public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ doPolygon(xPoints, yPoints, nPoints, false, false);
+ }
+
+ private boolean drawRaster(ColorModel cm, Raster r,
+ AffineTransform imageToUser, Color bgcolor)
+ {
+ if (r == null)
+ return false;
+
+ SampleModel sm = r.getSampleModel();
+ DataBuffer db = r.getDataBuffer();
+
+ if (db == null || sm == null)
+ return false;
+
+ if (cm == null)
+ cm = ColorModel.getRGBdefault();
+
+ double[] i2u = new double[6];
+ if (imageToUser != null)
+ imageToUser.getMatrix(i2u);
+ else
+ {
+ i2u[0] = 1;
+ i2u[1] = 0;
+ i2u[2] = 0;
+ i2u[3] = 1;
+ i2u[4] = 0;
+ i2u[5] = 0;
+ }
+
+ int[] pixels = findSimpleIntegerArray(cm, r);
+
+ if (pixels == null)
+ {
+ // FIXME: I don't think this code will work correctly with a non-RGB
+ // MultiPixelPackedSampleModel. Although this entire method should
+ // probably be rewritten to better utilize Cairo's different supported
+ // data formats.
+ if (sm instanceof MultiPixelPackedSampleModel)
+ {
+ pixels = r.getPixels(0, 0, r.getWidth(), r.getHeight(), pixels);
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] = cm.getRGB(pixels[i]);
+ }
+ else
+ {
+ pixels = new int[r.getWidth() * r.getHeight()];
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] = cm.getRGB(db.getElem(i));
+ }
+ }
+
+ // Change all transparent pixels in the image to the specified bgcolor,
+ // or (if there's no alpha) fill in an alpha channel so that it paints
+ // correctly.
+ if (cm.hasAlpha())
+ {
+ if (bgcolor != null && cm.hasAlpha())
+ for (int i = 0; i < pixels.length; i++)
+ {
+ if (cm.getAlpha(pixels[i]) == 0)
+ pixels[i] = bgcolor.getRGB();
+ }
+ }
+ else
+ for (int i = 0; i < pixels.length; i++)
+ pixels[i] |= 0xFF000000;
+
+ drawPixels(pixels, r.getWidth(), r.getHeight(), r.getWidth(), i2u);
+
+ updateBufferedImage();
+
+ return true;
+ }
+
+ public void drawRenderedImage(RenderedImage image, AffineTransform xform)
+ {
+ drawRaster(image.getColorModel(), image.getData(), xform, bg);
+ }
+
+ public void drawRenderableImage(RenderableImage image, AffineTransform xform)
+ {
+ drawRenderedImage(image.createRendering(new RenderContext(xform)), xform);
+ }
+
+ public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs)
+ {
+ return drawImage(img, xform, bg, obs);
+ }
+
+ public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y)
+ {
+ Image filtered = op.filter(image, null);
+ drawImage(filtered, new AffineTransform(1f, 0f, 0f, 1f, x, y), bg, null);
+ }
+
+ public boolean drawImage(Image img, int x, int y, ImageObserver observer)
+ {
+ return drawImage(img, new AffineTransform(1f, 0f, 0f, 1f, x, y), bg,
+ observer);
+ }
+
+ ///////////////////////////////////////////////
+ ////// Unimplemented Stubs and Overloads //////
+ ///////////////////////////////////////////////
+
+ public boolean hit(Rectangle rect, Shape text, boolean onStroke)
+ {
+ throw new java.lang.UnsupportedOperationException();
+ }
+
+ public GraphicsConfiguration getDeviceConfiguration()
+ {
+ throw new java.lang.UnsupportedOperationException();
+ }
+
+ public void setComposite(Composite comp)
+ {
+ this.comp = comp;
+
+ if (comp instanceof AlphaComposite)
+ {
+ AlphaComposite a = (AlphaComposite) comp;
+ cairoSetOperator(a.getRule());
+ Color c = getColor();
+ setColor(new Color(c.getRed(), c.getGreen(), c.getBlue(),
+ (int) (a.getAlpha() * ((float) c.getAlpha()))));
+ }
+ else
+ throw new java.lang.UnsupportedOperationException();
+ }
+
+ public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)
+ {
+ hints.put(hintKey, hintValue);
+
+ if (hintKey.equals(RenderingHints.KEY_INTERPOLATION)
+ || hintKey.equals(RenderingHints.KEY_ALPHA_INTERPOLATION))
+ {
+ if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
+ cairoSurfaceSetFilter(0);
+
+ else if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
+ cairoSurfaceSetFilter(1);
+
+ else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
+ cairoSurfaceSetFilter(2);
+
+ else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
+ cairoSurfaceSetFilter(3);
+
+ else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
+ cairoSurfaceSetFilter(4);
+ }
+
+ shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
+ || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
+ }
+
+ public Object getRenderingHint(RenderingHints.Key hintKey)
+ {
+ return hints.get(hintKey);
+ }
+
+ public void setRenderingHints(Map hints)
+ {
+ this.hints = new RenderingHints(getDefaultHints());
+ this.hints.add(new RenderingHints(hints));
+
+ if (hints.containsKey(RenderingHints.KEY_INTERPOLATION))
+ {
+ if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
+ cairoSurfaceSetFilter(0);
+
+ else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
+ cairoSurfaceSetFilter(1);
+ }
+
+ if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION))
+ {
+ if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED))
+ cairoSurfaceSetFilter(2);
+
+ else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY))
+ cairoSurfaceSetFilter(3);
+
+ else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
+ cairoSurfaceSetFilter(4);
+ }
+
+ shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE)
+ || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT);
+ }
+
+ public void addRenderingHints(Map hints)
+ {
+ this.hints.add(new RenderingHints(hints));
+ }
+
+ public RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ public Composite getComposite()
+ {
+ if (comp == null)
+ return AlphaComposite.SrcOver;
+ else
+ return comp;
+ }
+
+ public FontRenderContext getFontRenderContext()
+ {
+ return new FontRenderContext(transform, true, true);
+ }
+
+ public void copyArea(int x, int y, int width, int height, int dx, int dy)
+ {
+ throw new java.lang.UnsupportedOperationException();
+ }
+
+ public void drawArc(int x, int y, int width, int height, int startAngle,
+ int arcAngle)
+ {
+ draw(new Arc2D.Double((double) x, (double) y, (double) width,
+ (double) height, (double) startAngle,
+ (double) arcAngle, Arc2D.OPEN));
+ }
+
+ public boolean drawImage(Image img, int x, int y, Color bgcolor,
+ ImageObserver observer)
+ {
+ return drawImage(img, x, y, img.getWidth(observer),
+ img.getHeight(observer), bgcolor, observer);
+ }
+
+ public boolean drawImage(Image img, int x, int y, int width, int height,
+ Color bgcolor, ImageObserver observer)
+ {
+ double scaleX = width / (double) img.getWidth(observer);
+ double scaleY = height / (double) img.getHeight(observer);
+
+ return drawImage(img, new AffineTransform(scaleX, 0f, 0f, scaleY, x, y),
+ bgcolor, observer);
+ }
+
+ public boolean drawImage(Image img, int x, int y, int width, int height,
+ ImageObserver observer)
+ {
+ return drawImage(img, x, y, width, height, bg, observer);
+ }
+
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2, Color bgcolor,
+ ImageObserver observer)
+ {
+ if (img == null)
+ return false;
+
+ Image subImage;
+
+ int sourceWidth = sx2 - sx1;
+ int sourceHeight = sy2 - sy1;
+
+ int destWidth = dx2 - dx1;
+ int destHeight = dy2 - dy1;
+
+ double scaleX = destWidth / (double) sourceWidth;
+ double scaleY = destHeight / (double) sourceHeight;
+
+ // Get the subimage of the source enclosed in the
+ // rectangle specified by sx1, sy1, sx2, sy2
+
+ if (img instanceof BufferedImage)
+ {
+ BufferedImage b = (BufferedImage) img;
+ subImage = b.getSubimage(sx1, sy1, sx2, sy2);
+ }
+ else
+ {
+ // FIXME: This code currently doesn't work. Null Pointer
+ // exception is thrown in this case. This happens
+ // because img.getSource() always returns null, since source gets
+ // never initialized when it is created with the help of
+ // createImage(int width, int height).
+ CropImageFilter filter = new CropImageFilter(sx1, sx2, sx2, sy2);
+ FilteredImageSource src = new FilteredImageSource(img.getSource(),
+ filter);
+
+ subImage = Toolkit.getDefaultToolkit().createImage(src);
+ }
+
+ return drawImage(subImage,
+ new AffineTransform(scaleX, 0, 0, scaleY, dx1, dy1),
+ bgcolor, observer);
+ }
+
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2,
+ ImageObserver observer)
+ {
+ return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bg, observer);
+ }
+
+ public void drawOval(int x, int y, int width, int height)
+ {
+ drawArc(x, y, width, height, 0, 360);
+ }
+
+ public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
+ int arcHeight)
+ {
+ if (arcWidth > width)
+ arcWidth = width;
+ if (arcHeight > height)
+ arcHeight = height;
+
+ int xx = x + width - arcWidth;
+ int yy = y + height - arcHeight;
+
+ drawArc(x, y, arcWidth, arcHeight, 90, 90);
+ drawArc(xx, y, arcWidth, arcHeight, 0, 90);
+ drawArc(xx, yy, arcWidth, arcHeight, 270, 90);
+ drawArc(x, yy, arcWidth, arcHeight, 180, 90);
+
+ int y1 = y + arcHeight / 2;
+ int y2 = y + height - arcHeight / 2;
+ drawLine(x, y1, x, y2);
+ drawLine(x + width, y1, x + width, y2);
+
+ int x1 = x + arcWidth / 2;
+ int x2 = x + width - arcWidth / 2;
+ drawLine(x1, y, x2, y);
+ drawLine(x1, y + height, x2, y + height);
+ }
+
+ // these are the most accelerated painting paths
+ native void cairoDrawGlyphVector(GdkFontPeer font,
+ float x, float y, int n,
+ int[] codes, float[] positions);
+
+ native void cairoDrawGdkTextLayout(GdkTextLayout gl,
+ float x, float y);
+
+ GdkFontPeer getFontPeer()
+ {
+ return (GdkFontPeer) getFont().getPeer();
+ }
+
+ public void drawGdkTextLayout(GdkTextLayout gl, float x, float y)
+ {
+ cairoDrawGdkTextLayout (gl, x, y);
+ updateBufferedImage ();
+ }
+
+ public void drawString(String str, float x, float y)
+ {
+ drawGlyphVector(getFont().createGlyphVector(null, str), x, y);
+ updateBufferedImage ();
+ }
+
+ public void drawString(String str, int x, int y)
+ {
+ drawString (str, (float) x, (float) y);
+ }
+
+ public void drawString(AttributedCharacterIterator ci, int x, int y)
+ {
+ drawString (ci, (float) x, (float) y);
+ }
+
+ public void drawGlyphVector(GlyphVector gv, float x, float y)
+ {
+ int n = gv.getNumGlyphs ();
+ int[] codes = gv.getGlyphCodes (0, n, null);
+ float[] positions = gv.getGlyphPositions (0, n, null);
+
+ setFont (gv.getFont ());
+ cairoDrawGlyphVector (getFontPeer(), x, y, n, codes, positions);
+ updateBufferedImage ();
+ }
+
+ public void drawString(AttributedCharacterIterator ci, float x, float y)
+ {
+ GlyphVector gv = getFont().createGlyphVector(getFontRenderContext(), ci);
+ drawGlyphVector(gv, x, y);
+ }
+
+ public void fillArc(int x, int y, int width, int height, int startAngle,
+ int arcAngle)
+ {
+ fill(new Arc2D.Double((double) x, (double) y, (double) width,
+ (double) height, (double) startAngle,
+ (double) arcAngle, Arc2D.OPEN));
+ }
+
+ public void fillOval(int x, int y, int width, int height)
+ {
+ fillArc(x, y, width, height, 0, 360);
+ }
+
+ public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
+ int arcHeight)
+ {
+ if (arcWidth > width)
+ arcWidth = width;
+ if (arcHeight > height)
+ arcHeight = height;
+
+ int xx = x + width - arcWidth;
+ int yy = y + height - arcHeight;
+
+ fillArc(x, y, arcWidth, arcHeight, 90, 90);
+ fillArc(xx, y, arcWidth, arcHeight, 0, 90);
+ fillArc(xx, yy, arcWidth, arcHeight, 270, 90);
+ fillArc(x, yy, arcWidth, arcHeight, 180, 90);
+
+ fillRect(x, y + arcHeight / 2, width, height - arcHeight + 1);
+ fillRect(x + arcWidth / 2, y, width - arcWidth + 1, height);
+ }
+
+ public Font getFont()
+ {
+ if (font == null)
+ return new Font("SansSerif", Font.PLAIN, 12);
+ return font;
+ }
+
+ // Until such time as pango is happy to talk directly to cairo, we
+ // actually need to redirect some calls from the GtkFontPeer and
+ // GtkFontMetrics into the drawing kit and ask cairo ourselves.
+
+ static native void releasePeerGraphicsResource(GdkFontPeer f);
+
+ public FontMetrics getFontMetrics()
+ {
+ return getFontMetrics(getFont());
+ }
+
+ public FontMetrics getFontMetrics(Font f)
+ {
+ // the reason we go via the toolkit here is to try to get
+ // a cached object. the toolkit keeps such a cache.
+ return Toolkit.getDefaultToolkit().getFontMetrics(f);
+ }
+
+ public void setFont(Font f)
+ {
+ if (f.getPeer() instanceof GdkFontPeer)
+ font = f;
+ else
+ font =
+ ((ClasspathToolkit)(Toolkit.getDefaultToolkit()))
+ .getFont(f.getName(), f.getAttributes());
+ }
+
+ public String toString()
+ {
+ return (getClass().getName()
+ + "[font=" + getFont().toString()
+ + ",color=" + fg.toString()
+ + "]");
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java
new file mode 100644
index 0000000..bfad87a
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java
@@ -0,0 +1,138 @@
+/* GdkGraphicsConfiguration.java -- describes characteristics of graphics
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.BufferCapabilities;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.ImageCapabilities;
+import java.awt.Rectangle;
+
+import java.awt.geom.AffineTransform;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.VolatileImage;
+
+public class GdkGraphicsConfiguration
+ extends GraphicsConfiguration
+{
+ GdkScreenGraphicsDevice gdkScreenGraphicsDevice;
+ ColorModel cm;
+ Rectangle bounds;
+
+ public GtkToolkit getToolkit()
+ {
+ return gdkScreenGraphicsDevice.getToolkit();
+ }
+
+ public GdkGraphicsConfiguration(GdkScreenGraphicsDevice dev)
+ {
+ this.gdkScreenGraphicsDevice = dev;
+ cm = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).getColorModel();
+ bounds = getToolkit().getBounds();
+ }
+
+ public GraphicsDevice getDevice()
+ {
+ return gdkScreenGraphicsDevice;
+ }
+
+ public BufferedImage createCompatibleImage(int w, int h)
+ {
+ return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+ }
+
+ public BufferedImage createCompatibleImage(int w, int h,
+ int transparency)
+ {
+ return createCompatibleImage(w, h);
+ }
+
+ public VolatileImage createCompatibleVolatileImage(int w, int h)
+ {
+ return new GtkVolatileImage(w, h);
+ }
+
+ public VolatileImage createCompatibleVolatileImage(int w, int h,
+ ImageCapabilities caps)
+ throws java.awt.AWTException
+ {
+ return new GtkVolatileImage(w, h, caps);
+ }
+
+ public ColorModel getColorModel()
+ {
+ return cm;
+ }
+
+ public ColorModel getColorModel(int transparency)
+ {
+ return getColorModel();
+ }
+
+ public AffineTransform getDefaultTransform()
+ {
+ // FIXME: extract the GDK DPI information here.
+ return new AffineTransform();
+ }
+
+ public AffineTransform getNormalizingTransform()
+ {
+ // FIXME: extract the GDK DPI information here.
+ return new AffineTransform();
+ }
+
+ public Rectangle getBounds()
+ {
+ return bounds;
+ }
+
+ public BufferCapabilities getBufferCapabilities()
+ {
+ return new BufferCapabilities(getImageCapabilities(),
+ getImageCapabilities(),
+ BufferCapabilities.FlipContents.UNDEFINED);
+ }
+
+ public ImageCapabilities getImageCapabilities()
+ {
+ return new ImageCapabilities(false);
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
new file mode 100644
index 0000000..4f9d1c2
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java
@@ -0,0 +1,107 @@
+/* GdkGraphicsEnvironment.java -- information about the graphics environment
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.image.BufferedImage;
+import java.util.Locale;
+
+public class GdkGraphicsEnvironment extends GraphicsEnvironment
+{
+ GtkToolkit gtkToolkit;
+
+ public GtkToolkit getToolkit()
+ {
+ return gtkToolkit;
+ }
+
+ public GdkGraphicsEnvironment (GtkToolkit tk)
+ {
+ super();
+ gtkToolkit = tk;
+ }
+
+ public GraphicsDevice[] getScreenDevices ()
+ {
+ // FIXME: Support multiple screens, since GDK can.
+ return new GraphicsDevice[] { new GdkScreenGraphicsDevice (this) };
+ }
+
+ public GraphicsDevice getDefaultScreenDevice ()
+ {
+ if (GraphicsEnvironment.isHeadless ())
+ throw new HeadlessException ();
+
+ return new GdkScreenGraphicsDevice (this);
+ }
+
+ public Graphics2D createGraphics (BufferedImage image)
+ {
+ return new GdkGraphics2D (image);
+ }
+
+ private native int nativeGetNumFontFamilies();
+ private native void nativeGetFontFamilies(String[] family_names);
+
+ public Font[] getAllFonts ()
+ {
+ throw new java.lang.UnsupportedOperationException ();
+ }
+
+ public String[] getAvailableFontFamilyNames ()
+ {
+ String[] family_names;
+ int array_size;
+
+ array_size = nativeGetNumFontFamilies();
+ family_names = new String[array_size];
+
+ nativeGetFontFamilies(family_names);
+ return family_names;
+ }
+
+ public String[] getAvailableFontFamilyNames (Locale l)
+ {
+ throw new java.lang.UnsupportedOperationException ();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
new file mode 100644
index 0000000..57d5a36
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java
@@ -0,0 +1,681 @@
+/* GdkPixbufDecoder.java -- Image data decoding object
+ Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import gnu.classpath.Configuration;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageProducer;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.imageio.IIOImage;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.ImageTypeSpecifier;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.spi.ImageWriterSpi;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.ImageOutputStream;
+
+public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
+{
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("gtkpeer");
+ }
+ initStaticState ();
+ }
+
+ static native void initStaticState();
+ private final int native_state = GtkGenericPeer.getUniqueInteger ();
+
+ // initState() has been called, but pumpDone() has not yet been called.
+ private boolean needsClose = false;
+
+ // the current set of ImageConsumers for this decoder
+ Vector curr;
+
+ // interface to GdkPixbuf
+ native void initState ();
+ native void pumpBytes (byte[] bytes, int len) throws IOException;
+ native void pumpDone () throws IOException;
+ native void finish (boolean needsClose);
+ static native void streamImage(int[] bytes, String format, int width, int height, boolean hasAlpha, DataOutput sink);
+
+ // gdk-pixbuf provids data in RGBA format
+ static final ColorModel cm = new DirectColorModel (32, 0xff000000,
+ 0x00ff0000,
+ 0x0000ff00,
+ 0x000000ff);
+ public GdkPixbufDecoder (InputStream in)
+ {
+ super (in);
+ }
+
+ public GdkPixbufDecoder (String filename)
+ {
+ super (filename);
+ }
+
+ public GdkPixbufDecoder (URL url)
+ {
+ super (url);
+ }
+
+ public GdkPixbufDecoder (byte[] imagedata, int imageoffset, int imagelength)
+ {
+ super (imagedata, imageoffset, imagelength);
+ }
+
+ // called back by native side
+ void areaPrepared (int width, int height)
+ {
+
+ if (curr == null)
+ return;
+
+ for (int i = 0; i < curr.size (); i++)
+ {
+ ImageConsumer ic = (ImageConsumer) curr.elementAt (i);
+ ic.setDimensions (width, height);
+ ic.setColorModel (cm);
+ ic.setHints (ImageConsumer.RANDOMPIXELORDER);
+ }
+ }
+
+ // called back by native side
+ void areaUpdated (int x, int y, int width, int height,
+ int pixels[], int scansize)
+ {
+ if (curr == null)
+ return;
+
+ for (int i = 0; i < curr.size (); i++)
+ {
+ ImageConsumer ic = (ImageConsumer) curr.elementAt (i);
+ ic.setPixels (x, y, width, height, cm, pixels, 0, scansize);
+ }
+ }
+
+ // called from an async image loader of one sort or another, this method
+ // repeatedly reads bytes from the input stream and passes them through a
+ // GdkPixbufLoader using the native method pumpBytes. pumpBytes in turn
+ // decodes the image data and calls back areaPrepared and areaUpdated on
+ // this object, feeding back decoded pixel blocks, which we pass to each
+ // of the ImageConsumers in the provided Vector.
+
+ public void produce (Vector v, InputStream is) throws IOException
+ {
+ curr = v;
+
+ byte bytes[] = new byte[4096];
+ int len = 0;
+ initState();
+ needsClose = true;
+ while ((len = is.read (bytes)) != -1)
+ pumpBytes (bytes, len);
+ pumpDone();
+ needsClose = false;
+
+ for (int i = 0; i < curr.size (); i++)
+ {
+ ImageConsumer ic = (ImageConsumer) curr.elementAt (i);
+ ic.imageComplete (ImageConsumer.STATICIMAGEDONE);
+ }
+
+ curr = null;
+ }
+
+ public void finalize()
+ {
+ finish(needsClose);
+ }
+
+
+ public static class ImageFormatSpec
+ {
+ public String name;
+ public boolean writable = false;
+ public ArrayList mimeTypes = new ArrayList();
+ public ArrayList extensions = new ArrayList();
+
+ public ImageFormatSpec(String name, boolean writable)
+ {
+ this.name = name;
+ this.writable = writable;
+ }
+
+ public synchronized void addMimeType(String m)
+ {
+ mimeTypes.add(m);
+ }
+
+ public synchronized void addExtension(String e)
+ {
+ extensions.add(e);
+ }
+ }
+
+ static ArrayList imageFormatSpecs;
+
+ public static ImageFormatSpec registerFormat(String name, boolean writable)
+ {
+ ImageFormatSpec ifs = new ImageFormatSpec(name, writable);
+ synchronized(GdkPixbufDecoder.class)
+ {
+ if (imageFormatSpecs == null)
+ imageFormatSpecs = new ArrayList();
+ imageFormatSpecs.add(ifs);
+ }
+ return ifs;
+ }
+
+ static String[] getFormatNames(boolean writable)
+ {
+ ArrayList names = new ArrayList();
+ synchronized (imageFormatSpecs)
+ {
+ Iterator i = imageFormatSpecs.iterator();
+ while (i.hasNext())
+ {
+ ImageFormatSpec ifs = (ImageFormatSpec) i.next();
+ if (writable && !ifs.writable)
+ continue;
+ names.add(ifs.name);
+
+ /*
+ * In order to make the filtering code work, we need to register
+ * this type under every "format name" likely to be used as a synonym.
+ * This generally means "all the extensions people might use".
+ */
+
+ Iterator j = ifs.extensions.iterator();
+ while (j.hasNext())
+ names.add((String) j.next());
+ }
+ }
+ Object[] objs = names.toArray();
+ String[] strings = new String[objs.length];
+ for (int i = 0; i < objs.length; ++i)
+ strings[i] = (String) objs[i];
+ return strings;
+ }
+
+ static String[] getFormatExtensions(boolean writable)
+ {
+ ArrayList extensions = new ArrayList();
+ synchronized (imageFormatSpecs)
+ {
+ Iterator i = imageFormatSpecs.iterator();
+ while (i.hasNext())
+ {
+ ImageFormatSpec ifs = (ImageFormatSpec) i.next();
+ if (writable && !ifs.writable)
+ continue;
+ Iterator j = ifs.extensions.iterator();
+ while (j.hasNext())
+ extensions.add((String) j.next());
+ }
+ }
+ Object[] objs = extensions.toArray();
+ String[] strings = new String[objs.length];
+ for (int i = 0; i < objs.length; ++i)
+ strings[i] = (String) objs[i];
+ return strings;
+ }
+
+ static String[] getFormatMimeTypes(boolean writable)
+ {
+ ArrayList mimeTypes = new ArrayList();
+ synchronized (imageFormatSpecs)
+ {
+ Iterator i = imageFormatSpecs.iterator();
+ while (i.hasNext())
+ {
+ ImageFormatSpec ifs = (ImageFormatSpec) i.next();
+ if (writable && !ifs.writable)
+ continue;
+ Iterator j = ifs.mimeTypes.iterator();
+ while (j.hasNext())
+ mimeTypes.add((String) j.next());
+ }
+ }
+ Object[] objs = mimeTypes.toArray();
+ String[] strings = new String[objs.length];
+ for (int i = 0; i < objs.length; ++i)
+ strings[i] = (String) objs[i];
+ return strings;
+ }
+
+
+ static String findFormatName(Object ext, boolean needWritable)
+ {
+ if (ext == null)
+ throw new IllegalArgumentException("extension is null");
+
+ if (!(ext instanceof String))
+ throw new IllegalArgumentException("extension is not a string");
+
+ String str = (String) ext;
+
+ Iterator i = imageFormatSpecs.iterator();
+ while (i.hasNext())
+ {
+ ImageFormatSpec ifs = (ImageFormatSpec) i.next();
+
+ if (needWritable && !ifs.writable)
+ continue;
+
+ if (ifs.name.equals(str))
+ return str;
+
+ Iterator j = ifs.extensions.iterator();
+ while (j.hasNext())
+ {
+ String extension = (String)j.next();
+ if (extension.equals(str))
+ return ifs.name;
+ }
+
+ j = ifs.mimeTypes.iterator();
+ while (j.hasNext())
+ {
+ String mimeType = (String)j.next();
+ if (mimeType.equals(str))
+ return ifs.name;
+ }
+ }
+ throw new IllegalArgumentException("unknown extension '" + str + "'");
+ }
+
+ private static GdkPixbufReaderSpi readerSpi;
+ private static GdkPixbufWriterSpi writerSpi;
+
+ public static synchronized GdkPixbufReaderSpi getReaderSpi()
+ {
+ if (readerSpi == null)
+ readerSpi = new GdkPixbufReaderSpi();
+ return readerSpi;
+ }
+
+ public static synchronized GdkPixbufWriterSpi getWriterSpi()
+ {
+ if (writerSpi == null)
+ writerSpi = new GdkPixbufWriterSpi();
+ return writerSpi;
+ }
+
+ public static void registerSpis(IIORegistry reg)
+ {
+ reg.registerServiceProvider(getReaderSpi(), ImageReaderSpi.class);
+ reg.registerServiceProvider(getWriterSpi(), ImageWriterSpi.class);
+ }
+
+ public static class GdkPixbufWriterSpi extends ImageWriterSpi
+ {
+ public GdkPixbufWriterSpi()
+ {
+ super("GdkPixbuf", "2.x",
+ GdkPixbufDecoder.getFormatNames(true),
+ GdkPixbufDecoder.getFormatExtensions(true),
+ GdkPixbufDecoder.getFormatMimeTypes(true),
+ "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufWriter",
+ new Class[] { ImageOutputStream.class },
+ new String[] { "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufReaderSpi" },
+ false, null, null, null, null,
+ false, null, null, null, null);
+ }
+
+ public boolean canEncodeImage(ImageTypeSpecifier ts)
+ {
+ return true;
+ }
+
+ public ImageWriter createWriterInstance(Object ext)
+ {
+ return new GdkPixbufWriter(this, ext);
+ }
+
+ public String getDescription(java.util.Locale loc)
+ {
+ return "GdkPixbuf Writer SPI";
+ }
+
+ }
+
+ public static class GdkPixbufReaderSpi extends ImageReaderSpi
+ {
+ public GdkPixbufReaderSpi()
+ {
+ super("GdkPixbuf", "2.x",
+ GdkPixbufDecoder.getFormatNames(false),
+ GdkPixbufDecoder.getFormatExtensions(false),
+ GdkPixbufDecoder.getFormatMimeTypes(false),
+ "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufReader",
+ new Class[] { ImageInputStream.class },
+ new String[] { "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufWriterSpi" },
+ false, null, null, null, null,
+ false, null, null, null, null);
+ }
+
+ public boolean canDecodeInput(Object obj)
+ {
+ return true;
+ }
+
+ public ImageReader createReaderInstance(Object ext)
+ {
+ return new GdkPixbufReader(this, ext);
+ }
+
+ public String getDescription(Locale loc)
+ {
+ return "GdkPixbuf Reader SPI";
+ }
+ }
+
+ private static class GdkPixbufWriter
+ extends ImageWriter
+ {
+ String ext;
+ public GdkPixbufWriter(GdkPixbufWriterSpi ownerSpi, Object ext)
+ {
+ super(ownerSpi);
+ this.ext = findFormatName(ext, true);
+ }
+
+ public IIOMetadata convertImageMetadata (IIOMetadata inData,
+ ImageTypeSpecifier imageType,
+ ImageWriteParam param)
+ {
+ return null;
+ }
+
+ public IIOMetadata convertStreamMetadata (IIOMetadata inData,
+ ImageWriteParam param)
+ {
+ return null;
+ }
+
+ public IIOMetadata getDefaultImageMetadata (ImageTypeSpecifier imageType,
+ ImageWriteParam param)
+ {
+ return null;
+ }
+
+ public IIOMetadata getDefaultStreamMetadata (ImageWriteParam param)
+ {
+ return null;
+ }
+
+ public void write (IIOMetadata streamMetadata, IIOImage i, ImageWriteParam param)
+ throws IOException
+ {
+ RenderedImage image = i.getRenderedImage();
+ Raster ras = image.getData();
+ int width = ras.getWidth();
+ int height = ras.getHeight();
+ ColorModel model = image.getColorModel();
+ int[] pixels = GdkGraphics2D.findSimpleIntegerArray (image.getColorModel(), ras);
+
+ if (pixels == null)
+ {
+ BufferedImage img = new BufferedImage(width, height,
+ (model != null && model.hasAlpha() ?
+ BufferedImage.TYPE_INT_ARGB
+ : BufferedImage.TYPE_INT_RGB));
+ int[] pix = new int[4];
+ for (int y = 0; y < height; ++y)
+ for (int x = 0; x < width; ++x)
+ img.setRGB(x, y, model.getRGB(ras.getPixel(x, y, pix)));
+ pixels = GdkGraphics2D.findSimpleIntegerArray (img.getColorModel(),
+ img.getRaster());
+ model = img.getColorModel();
+ }
+
+ processImageStarted(1);
+ streamImage(pixels, this.ext, width, height, model.hasAlpha(),
+ (DataOutput) this.getOutput());
+ processImageComplete();
+ }
+ }
+
+ private static class GdkPixbufReader
+ extends ImageReader
+ implements ImageConsumer
+ {
+ // ImageConsumer parts
+ GdkPixbufDecoder dec;
+ BufferedImage bufferedImage;
+ ColorModel defaultModel;
+ int width;
+ int height;
+ String ext;
+
+ public GdkPixbufReader(GdkPixbufReaderSpi ownerSpi, Object ext)
+ {
+ super(ownerSpi);
+ this.ext = findFormatName(ext, false);
+ }
+
+ public GdkPixbufReader(GdkPixbufReaderSpi ownerSpi, Object ext, GdkPixbufDecoder d)
+ {
+ this(ownerSpi, ext);
+ dec = d;
+ }
+
+ public void setDimensions(int w, int h)
+ {
+ processImageStarted(1);
+ width = w;
+ height = h;
+ }
+
+ public void setProperties(Hashtable props) {}
+
+ public void setColorModel(ColorModel model)
+ {
+ defaultModel = model;
+ }
+
+ public void setHints(int flags) {}
+
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, byte[] pixels,
+ int offset, int scansize)
+ {
+ }
+
+ public void setPixels(int x, int y, int w, int h,
+ ColorModel model, int[] pixels,
+ int offset, int scansize)
+ {
+ if (model == null)
+ model = defaultModel;
+
+ if (bufferedImage == null)
+ {
+ bufferedImage = new BufferedImage (width, height, (model != null && model.hasAlpha() ?
+ BufferedImage.TYPE_INT_ARGB
+ : BufferedImage.TYPE_INT_RGB));
+ }
+
+ int pixels2[];
+ if (model != null)
+ {
+ pixels2 = new int[pixels.length];
+ for (int yy = 0; yy < h; yy++)
+ for (int xx = 0; xx < w; xx++)
+ {
+ int i = yy * scansize + xx;
+ pixels2[i] = model.getRGB (pixels[i]);
+ }
+ }
+ else
+ pixels2 = pixels;
+
+ bufferedImage.setRGB (x, y, w, h, pixels2, offset, scansize);
+ processImageProgress(y / (height == 0 ? 1 : height));
+ }
+
+ public void imageComplete(int status)
+ {
+ processImageComplete();
+ }
+
+ public BufferedImage getBufferedImage()
+ {
+ if (bufferedImage == null && dec != null)
+ dec.startProduction (this);
+ return bufferedImage;
+ }
+
+ // ImageReader parts
+
+ public int getNumImages(boolean allowSearch)
+ throws IOException
+ {
+ return 1;
+ }
+
+ public IIOMetadata getImageMetadata(int i)
+ {
+ return null;
+ }
+
+ public IIOMetadata getStreamMetadata()
+ throws IOException
+ {
+ return null;
+ }
+
+ public Iterator getImageTypes(int imageIndex)
+ throws IOException
+ {
+ BufferedImage img = getBufferedImage();
+ Vector vec = new Vector();
+ vec.add(new ImageTypeSpecifier(img));
+ return vec.iterator();
+ }
+
+ public int getHeight(int imageIndex)
+ throws IOException
+ {
+ return getBufferedImage().getHeight();
+ }
+
+ public int getWidth(int imageIndex)
+ throws IOException
+ {
+ return getBufferedImage().getWidth();
+ }
+
+ public void setInput(Object input,
+ boolean seekForwardOnly,
+ boolean ignoreMetadata)
+ {
+ super.setInput(input, seekForwardOnly, ignoreMetadata);
+ dec = new GdkPixbufDecoder((InputStream) getInput());
+ }
+
+ public BufferedImage read(int imageIndex, ImageReadParam param)
+ throws IOException
+ {
+ return getBufferedImage ();
+ }
+ }
+
+ // remaining helper class and static method is a convenience for the Gtk
+ // peers, for loading a BufferedImage in off a disk file without going
+ // through the whole imageio system.
+
+ public static BufferedImage createBufferedImage (String filename)
+ {
+ GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
+ "png", // reader auto-detects, doesn't matter
+ new GdkPixbufDecoder (filename));
+ return r.getBufferedImage ();
+ }
+
+ public static BufferedImage createBufferedImage (URL u)
+ {
+ GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
+ "png", // reader auto-detects, doesn't matter
+ new GdkPixbufDecoder (u));
+ return r.getBufferedImage ();
+ }
+
+ public static BufferedImage createBufferedImage (byte[] imagedata, int imageoffset,
+ int imagelength)
+ {
+ GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
+ "png", // reader auto-detects, doesn't matter
+ new GdkPixbufDecoder (imagedata,
+ imageoffset,
+ imagelength));
+ return r.getBufferedImage ();
+ }
+
+ public static BufferedImage createBufferedImage (ImageProducer producer)
+ {
+ GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), "png" /* ignored */, null);
+ producer.startProduction(r);
+ return r.getBufferedImage ();
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkRobotPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkRobotPeer.java
new file mode 100644
index 0000000..6d0218d
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkRobotPeer.java
@@ -0,0 +1,94 @@
+/* GdkRobot.java -- an XTest implementation of RobotPeer
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.AWTException;
+import java.awt.GraphicsDevice;
+import java.awt.Rectangle;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.peer.RobotPeer;
+
+/**
+ * Implements the RobotPeer interface using the XTest extension.
+ *
+ * @author Thomas Fitzsimmons
+ */
+public class GdkRobotPeer implements RobotPeer
+{
+ // gdk-pixbuf provides data in RGBA format
+ static final ColorModel cm = new DirectColorModel (32, 0xff000000,
+ 0x00ff0000,
+ 0x0000ff00,
+ 0x000000ff);
+
+ public GdkRobotPeer (GraphicsDevice screen) throws AWTException
+ {
+ // FIXME: make use of screen parameter when GraphicsDevice is
+ // implemented.
+ if (!initXTest ())
+ throw new AWTException ("XTest extension not supported");
+ }
+
+ native boolean initXTest ();
+
+ // RobotPeer methods
+ public native void mouseMove (int x, int y);
+ public native void mousePress (int buttons);
+ public native void mouseRelease (int buttons);
+ public native void mouseWheel (int wheelAmt);
+ public native void keyPress (int keycode);
+ public native void keyRelease (int keycode);
+ native int[] nativeGetRGBPixels (int x, int y, int width, int height);
+
+ public int getRGBPixel (int x, int y)
+ {
+ return cm.getRGB (nativeGetRGBPixels (x, y, 1, 1)[0]);
+ }
+
+ public int[] getRGBPixels (Rectangle r)
+ {
+ int[] gdk_pixels = nativeGetRGBPixels (r.x, r.y, r.width, r.height);
+ int[] pixels = new int[r.width * r.height];
+
+ for (int i = 0; i < r.width * r.height; i++)
+ pixels[i] = cm.getRGB (gdk_pixels[i]);
+
+ return pixels;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java
new file mode 100644
index 0000000..2bf9d23
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java
@@ -0,0 +1,115 @@
+/* GdkScreenGraphicsDevice.java -- information about a screen device
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Dimension;
+import java.awt.DisplayMode;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+
+public class GdkScreenGraphicsDevice extends GraphicsDevice
+{
+ GdkGraphicsEnvironment env;
+
+ public GtkToolkit getToolkit()
+ {
+ return env.getToolkit();
+ }
+
+ public GdkScreenGraphicsDevice (GdkGraphicsEnvironment e)
+ {
+ super ();
+ env = e;
+ }
+
+ public int getType ()
+ {
+ return GraphicsDevice.TYPE_RASTER_SCREEN;
+ }
+
+ public String getIDstring ()
+ {
+ // FIXME: query X for this string
+ return "default GDK device ID string";
+ }
+
+ public GraphicsConfiguration[] getConfigurations ()
+ {
+ // FIXME: query X for the list of possible configurations
+ return new GraphicsConfiguration [] { new GdkGraphicsConfiguration(this) };
+ }
+
+ public GraphicsConfiguration getDefaultConfiguration ()
+ {
+
+ // FIXME: query X for default configuration
+ return new GdkGraphicsConfiguration(this);
+ }
+
+
+ /**
+ * Returns the current display mode of this device, or null if unknown.
+ *
+ * @return the current display mode
+ * @see #setDisplayMode(DisplayMode)
+ * @see #getDisplayModes()
+ * @since 1.4
+ */
+ public DisplayMode getDisplayMode()
+ {
+ // determine display mode
+ Dimension dim = getToolkit().getScreenSize();
+ DisplayMode mode = new DisplayMode(dim.width, dim.height, 0,
+ DisplayMode.REFRESH_RATE_UNKNOWN);
+ return mode;
+ }
+
+ /**
+ * This device does not yet support fullscreen exclusive mode, so this
+ * returns <code>false</code>.
+ *
+ * @return <code>false</code>
+ * @since 1.4
+ */
+ public boolean isFullScreenSupported()
+ {
+ return false;
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java
new file mode 100644
index 0000000..ff51745
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java
@@ -0,0 +1,434 @@
+/* GdkTextLayout.java
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import gnu.classpath.Configuration;
+import gnu.java.awt.peer.ClasspathTextLayoutPeer;
+
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphMetrics;
+import java.awt.font.GlyphVector;
+import java.awt.font.TextAttribute;
+import java.awt.font.TextHitInfo;
+import java.awt.font.TextLayout;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Rectangle2D;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.text.CharacterIterator;
+
+/**
+ * This is an implementation of the text layout peer interface which
+ * delegates all the hard work to pango.
+ *
+ * @author Graydon Hoare
+ */
+
+public class GdkTextLayout
+ implements ClasspathTextLayoutPeer
+{
+ // native side, plumbing, etc.
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("gtkpeer");
+ }
+ initStaticState ();
+ }
+ private native void setText(String str);
+ private native void getExtents(double[] inkExtents,
+ double[] logExtents);
+ private native void indexToPos(int idx, double[] pos);
+ private native void initState ();
+ private native void dispose ();
+ static native void initStaticState();
+ private final int native_state = GtkGenericPeer.getUniqueInteger ();
+ protected void finalize ()
+ {
+ dispose ();
+ }
+
+ // we hold on to these to make sure we can render when presented
+ // with non-GdkGraphics2D paint targets
+ private AttributedString attributedString;
+ private FontRenderContext fontRenderContext;
+
+ public GdkTextLayout(AttributedString str, FontRenderContext frc)
+ {
+ initState();
+ attributedString = str;
+ fontRenderContext = frc;
+ }
+
+ protected class CharacterIteratorProxy
+ implements CharacterIterator
+ {
+ public CharacterIterator target;
+ public int begin;
+ public int limit;
+ public int index;
+
+ public CharacterIteratorProxy (CharacterIterator ci)
+ {
+ target = ci;
+ }
+
+ public int getBeginIndex ()
+ {
+ return begin;
+ }
+
+ public int getEndIndex ()
+ {
+ return limit;
+ }
+
+ public int getIndex ()
+ {
+ return index;
+ }
+
+ public char setIndex (int idx)
+ throws IllegalArgumentException
+ {
+ if (idx < begin || idx >= limit)
+ throw new IllegalArgumentException ();
+ char ch = target.setIndex (idx);
+ index = idx;
+ return ch;
+ }
+
+ public char first ()
+ {
+ int save = target.getIndex ();
+ char ch = target.setIndex (begin);
+ target.setIndex (save);
+ return ch;
+ }
+
+ public char last ()
+ {
+ if (begin == limit)
+ return this.first ();
+
+ int save = target.getIndex ();
+ char ch = target.setIndex (limit - 1);
+ target.setIndex (save);
+ return ch;
+ }
+
+ public char current ()
+ {
+ return target.current();
+ }
+
+ public char next ()
+ {
+ if (index >= limit - 1)
+ return CharacterIterator.DONE;
+ else
+ {
+ index++;
+ return target.next();
+ }
+ }
+
+ public char previous ()
+ {
+ if (index <= begin)
+ return CharacterIterator.DONE;
+ else
+ {
+ index--;
+ return target.previous ();
+ }
+ }
+
+ public Object clone ()
+ {
+ CharacterIteratorProxy cip = new CharacterIteratorProxy (this.target);
+ cip.begin = this.begin;
+ cip.limit = this.limit;
+ cip.index = this.index;
+ return cip;
+ }
+
+ }
+
+
+ // public side
+
+ public void draw (Graphics2D g2, float x, float y)
+ {
+ if (g2 instanceof GdkGraphics2D)
+ {
+ // we share pango structures directly with GdkGraphics2D
+ // when legal
+ GdkGraphics2D gg2 = (GdkGraphics2D) g2;
+ gg2.drawGdkTextLayout(this, x, y);
+ }
+ else
+ {
+ // falling back to a rather tedious layout algorithm when
+ // not legal
+ AttributedCharacterIterator ci = attributedString.getIterator ();
+ CharacterIteratorProxy proxy = new CharacterIteratorProxy (ci);
+ Font defFont = g2.getFont ();
+
+ /* Note: this implementation currently only interprets FONT text
+ * attributes. There is a reasonable argument to be made for some
+ * attributes being interpreted out here, where we have control of the
+ * Graphics2D and can construct or derive new fonts, and some
+ * attributes being interpreted by the GlyphVector itself. So far, for
+ * all attributes except FONT we do neither.
+ */
+
+ for (char c = ci.first ();
+ c != CharacterIterator.DONE;
+ c = ci.next ())
+ {
+ proxy.begin = ci.getIndex ();
+ proxy.limit = ci.getRunLimit(TextAttribute.FONT);
+ if (proxy.limit <= proxy.begin)
+ continue;
+
+ proxy.index = proxy.begin;
+
+ Object fnt = ci.getAttribute(TextAttribute.FONT);
+ GlyphVector gv;
+ if (fnt instanceof Font)
+ gv = ((Font)fnt).createGlyphVector (fontRenderContext, proxy);
+ else
+ gv = defFont.createGlyphVector (fontRenderContext, proxy);
+
+ g2.drawGlyphVector (gv, x, y);
+
+ int n = gv.getNumGlyphs ();
+ for (int i = 0; i < n; ++i)
+ {
+ GlyphMetrics gm = gv.getGlyphMetrics (i);
+ if (gm.getAdvanceX() == gm.getAdvance ())
+ x += gm.getAdvanceX ();
+ else
+ y += gm.getAdvanceY ();
+ }
+ }
+ }
+ }
+
+ public TextHitInfo getStrongCaret (TextHitInfo hit1,
+ TextHitInfo hit2)
+ {
+ throw new Error("not implemented");
+ }
+
+ public byte getBaseline ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public boolean isLeftToRight ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public boolean isVertical ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public float getAdvance ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public float getAscent ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public float getDescent ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public float getLeading ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public int getCharacterCount ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public byte getCharacterLevel (int index)
+ {
+ throw new Error("not implemented");
+ }
+
+ public float[] getBaselineOffsets ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint)
+ {
+ throw new Error("not implemented");
+ }
+
+ public Rectangle2D getBounds ()
+ {
+ double[] inkExtents = new double[4];
+ double[] logExtents = new double[4];
+ getExtents(inkExtents, logExtents);
+ return new Rectangle2D.Double(logExtents[0], logExtents[1],
+ logExtents[2], logExtents[3]);
+ }
+
+ public float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds)
+ {
+ throw new Error("not implemented");
+ }
+
+ public Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds)
+ {
+ throw new Error("not implemented");
+ }
+
+ public Shape[] getCaretShapes (int offset, Rectangle2D bounds,
+ TextLayout.CaretPolicy policy)
+ {
+ throw new Error("not implemented");
+ }
+
+ public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint,
+ Rectangle2D bounds)
+ {
+ AffineTransform at = new AffineTransform();
+ GeneralPath gp = new GeneralPath();
+ double [] rect = new double[4];
+ Rectangle2D tmp = new Rectangle2D.Double();
+ for (int i = firstEndpoint; i <= secondEndpoint; ++i)
+ {
+ indexToPos(i, rect);
+ tmp.setRect(rect[0], rect[1], rect[2], rect[3]);
+ Rectangle2D.intersect(tmp, bounds, tmp);
+ gp.append(tmp.getPathIterator(at), false);
+ }
+ return gp;
+ }
+
+ public int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint,
+ TextHitInfo secondEndpoint)
+ {
+ throw new Error("not implemented");
+ }
+
+ public TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy)
+ {
+ throw new Error("not implemented");
+ }
+ public TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy)
+ {
+ throw new Error("not implemented");
+ }
+ public TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds)
+ {
+ throw new Error("not implemented");
+ }
+ public TextHitInfo getVisualOtherHit (TextHitInfo hit)
+ {
+ throw new Error("not implemented");
+ }
+
+ public float getVisibleAdvance ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public Shape getOutline (AffineTransform tx)
+ {
+ throw new Error("not implemented");
+ }
+
+ public Shape getVisualHighlightShape (TextHitInfo firstEndpoint,
+ TextHitInfo secondEndpoint,
+ Rectangle2D bounds)
+ {
+ throw new Error("not implemented");
+ }
+
+
+ public TextLayout getJustifiedLayout (float justificationWidth)
+ {
+ throw new Error("not implemented");
+ }
+
+ public void handleJustify (float justificationWidth)
+ {
+ throw new Error("not implemented");
+ }
+
+ public Object clone ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public int hashCode ()
+ {
+ throw new Error("not implemented");
+ }
+
+ public boolean equals (ClasspathTextLayoutPeer tl)
+ {
+ throw new Error("not implemented");
+ }
+
+ public String toString ()
+ {
+ throw new Error("not implemented");
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java
new file mode 100644
index 0000000..ab5df9f
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java
@@ -0,0 +1,107 @@
+/* GtkButtonPeer.java -- Implements ButtonPeer with GTK
+ Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.AWTEvent;
+import java.awt.Button;
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.peer.ButtonPeer;
+
+public class GtkButtonPeer extends GtkComponentPeer
+ implements ButtonPeer
+{
+ native void create (String label);
+
+ public native void connectSignals ();
+
+ native void gtkWidgetModifyFont (String name, int style, int size);
+ native void gtkSetLabel (String label);
+ native void gtkWidgetSetForeground (int red, int green, int blue);
+ native void gtkWidgetSetBackground (int red, int green, int blue);
+ native void gtkActivate ();
+ native void gtkWidgetRequestFocus ();
+ native void setNativeBounds (int x, int y, int width, int height);
+
+ public GtkButtonPeer (Button b)
+ {
+ super (b);
+ }
+
+ void create ()
+ {
+ create (((Button) awtComponent).getLabel ());
+ }
+
+ public void setLabel (String label)
+ {
+ gtkSetLabel(label);
+ }
+
+ public void handleEvent (AWTEvent e)
+ {
+ if (e.getID () == MouseEvent.MOUSE_RELEASED && isEnabled ())
+ {
+ MouseEvent me = (MouseEvent) e;
+ Point p = me.getPoint();
+ p.translate(((Component) me.getSource()).getX(),
+ ((Component) me.getSource()).getY());
+ if (!me.isConsumed ()
+ && (me.getModifiersEx () & MouseEvent.BUTTON1_DOWN_MASK) != 0
+ && awtComponent.getBounds().contains(p))
+ postActionEvent (((Button) awtComponent).getActionCommand (),
+ me.getModifiersEx ());
+ }
+
+ if (e.getID () == KeyEvent.KEY_PRESSED)
+ {
+ KeyEvent ke = (KeyEvent) e;
+ if (!ke.isConsumed () && ke.getKeyCode () == KeyEvent.VK_SPACE)
+ {
+ postActionEvent (((Button) awtComponent).getActionCommand (),
+ ke.getModifiersEx ());
+ gtkActivate ();
+ }
+ }
+
+ super.handleEvent (e);
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java
new file mode 100644
index 0000000..dc21761
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java
@@ -0,0 +1,100 @@
+/* GtkCanvasPeer.java
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.AWTEvent;
+import java.awt.Canvas;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.event.PaintEvent;
+import java.awt.peer.CanvasPeer;
+
+public class GtkCanvasPeer extends GtkComponentPeer implements CanvasPeer
+{
+ native void create ();
+
+ public GtkCanvasPeer (Canvas c)
+ {
+ super (c);
+ }
+
+ public Graphics getGraphics ()
+ {
+ if (GtkToolkit.useGraphics2D ())
+ return new GdkGraphics2D (this);
+ else
+ return new GdkGraphics (this);
+ }
+
+ public void handleEvent (AWTEvent event)
+ {
+ int id = event.getID();
+
+ switch (id)
+ {
+ case PaintEvent.PAINT:
+ case PaintEvent.UPDATE:
+ {
+ try
+ {
+ Graphics g = getGraphics ();
+ g.setClip (((PaintEvent)event).getUpdateRect());
+
+ if (id == PaintEvent.PAINT)
+ awtComponent.paint (g);
+ else
+ awtComponent.update (g);
+
+ g.dispose ();
+ }
+ catch (InternalError e)
+ {
+ System.err.println (e);
+ }
+ }
+ break;
+ }
+ }
+
+ /* Preferred size for a drawing widget is always what the user requested */
+ public Dimension getPreferredSize ()
+ {
+ return awtComponent.getSize ();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java
new file mode 100644
index 0000000..46b0733
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java
@@ -0,0 +1,86 @@
+/* GtkCheckboxGroupPeer.java - Wrap a CheckboxGroup
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.CheckboxGroup;
+import java.util.WeakHashMap;
+
+// Note that there is no peer interface for a CheckboxGroup. We
+// introduce our own in order to make it easier to keep a piece of
+// native state for each one.
+public class GtkCheckboxGroupPeer extends GtkGenericPeer
+{
+ // This maps from a CheckboxGroup to the native peer.
+ private static WeakHashMap map = new WeakHashMap ();
+
+ // Find the native peer corresponding to a CheckboxGroup.
+ public static synchronized GtkCheckboxGroupPeer
+ getCheckboxGroupPeer (CheckboxGroup group)
+ {
+ if (group == null)
+ return null;
+ GtkCheckboxGroupPeer nat = (GtkCheckboxGroupPeer) map.get (group);
+ if (nat == null)
+ {
+ nat = new GtkCheckboxGroupPeer ();
+ map.put (group, nat);
+ }
+ return nat;
+ }
+
+ private GtkCheckboxGroupPeer ()
+ {
+ // We don't need any special state here. Note that we can't store
+ // a reference to the java-side CheckboxGroup. That would mean
+ // they could never be collected.
+ super (null);
+ }
+
+ // Dispose of our native resources.
+ public native void dispose ();
+
+ // Remove a given checkbox from this group.
+ public native void remove (GtkCheckboxPeer box);
+
+ // When collected, clean up the native state.
+ protected void finalize ()
+ {
+ dispose ();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxMenuItemPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxMenuItemPeer.java
new file mode 100644
index 0000000..01a6e31
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxMenuItemPeer.java
@@ -0,0 +1,69 @@
+/* GtkCheckboxMenuItemPeer.java -- Implements CheckboxMenuItemPeer with GTK+
+ Copyright (C) 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.CheckboxMenuItem;
+import java.awt.ItemSelectable;
+import java.awt.event.ItemEvent;
+import java.awt.peer.CheckboxMenuItemPeer;
+
+public class GtkCheckboxMenuItemPeer extends GtkMenuItemPeer
+ implements CheckboxMenuItemPeer
+{
+ native void create (String label);
+
+ public GtkCheckboxMenuItemPeer (CheckboxMenuItem menu)
+ {
+ super (menu);
+ setState (menu.getState ());
+ }
+
+ public native void setState(boolean t);
+
+ protected void postMenuActionEvent ()
+ {
+ CheckboxMenuItem item = (CheckboxMenuItem)awtWidget;
+ q().postEvent (new ItemEvent ((ItemSelectable)awtWidget,
+ ItemEvent.ITEM_STATE_CHANGED,
+ item.getActionCommand(),
+ item.getState() ? ItemEvent.DESELECTED : ItemEvent.SELECTED));
+
+ super.postMenuActionEvent();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java
new file mode 100644
index 0000000..8517572
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java
@@ -0,0 +1,128 @@
+/* GtkCheckboxPeer.java -- Implements CheckboxPeer with GTK
+ Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Checkbox;
+import java.awt.CheckboxGroup;
+import java.awt.peer.CheckboxPeer;
+
+public class GtkCheckboxPeer extends GtkComponentPeer
+ implements CheckboxPeer
+{
+ // Group from last time it was set.
+ public GtkCheckboxGroupPeer old_group;
+ // The current state of the GTK checkbox.
+ private boolean currentState;
+
+ public native void create (GtkCheckboxGroupPeer group);
+ public native void nativeSetCheckboxGroup (GtkCheckboxGroupPeer group);
+ public native void connectSignals ();
+ native void gtkWidgetModifyFont (String name, int style, int size);
+ native void gtkButtonSetLabel (String label);
+ native void gtkToggleButtonSetActive (boolean is_active);
+
+ public GtkCheckboxPeer (Checkbox c)
+ {
+ super (c);
+ }
+
+ // FIXME: we must be able to switch between a checkbutton and a
+ // radiobutton dynamically.
+ public void create ()
+ {
+ Checkbox checkbox = (Checkbox) awtComponent;
+ CheckboxGroup g = checkbox.getCheckboxGroup ();
+ old_group = GtkCheckboxGroupPeer.getCheckboxGroupPeer (g);
+ create (old_group);
+ gtkToggleButtonSetActive (checkbox.getState ());
+ gtkButtonSetLabel (checkbox.getLabel ());
+ }
+
+ public void setState (boolean state)
+ {
+ if (currentState != state)
+ gtkToggleButtonSetActive (state);
+ }
+
+ public void setLabel (String label)
+ {
+ gtkButtonSetLabel (label);
+ }
+
+ public void setCheckboxGroup (CheckboxGroup group)
+ {
+ GtkCheckboxGroupPeer gp
+ = GtkCheckboxGroupPeer.getCheckboxGroupPeer (group);
+ if (gp != old_group)
+ {
+ if (old_group != null)
+ old_group.remove (this);
+ nativeSetCheckboxGroup (gp);
+ old_group = gp;
+ }
+ }
+
+ // Override the superclass postItemEvent so that the peer doesn't
+ // need information that we have.
+ public void postItemEvent (Object item, int stateChange)
+ {
+ Checkbox currentCheckBox = ((Checkbox)awtComponent);
+ // A firing of the event is only desired if the state has changed due to a
+ // button press. The currentCheckBox's state must be different from the
+ // one that the stateChange is changing to.
+ // stateChange = 1 if it goes from false -> true
+ // stateChange = 2 if it goes from true -> false
+ if (( !currentCheckBox.getState() && stateChange == 1)
+ || (currentCheckBox.getState() && stateChange == 2))
+ {
+ super.postItemEvent (awtComponent, stateChange);
+ currentState = !currentCheckBox.getState();
+ currentCheckBox.setState(currentState);
+ }
+ }
+
+ public void dispose ()
+ {
+ // Notify the group so that the native state can be cleaned up
+ // appropriately.
+ if (old_group != null)
+ old_group.remove (this);
+ super.dispose ();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java
new file mode 100644
index 0000000..5028ea7
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java
@@ -0,0 +1,130 @@
+/* GtkChoicePeer.java -- Implements ChoicePeer with GTK
+ Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Choice;
+import java.awt.event.ItemEvent;
+import java.awt.peer.ChoicePeer;
+
+public class GtkChoicePeer extends GtkComponentPeer
+ implements ChoicePeer
+{
+ public GtkChoicePeer (Choice c)
+ {
+ super (c);
+
+ int count = c.getItemCount ();
+ if (count > 0)
+ {
+ String items[] = new String[count];
+ for (int i = 0; i < count; i++)
+ items[i] = c.getItem (i);
+
+ append (items);
+ }
+
+ int selected = c.getSelectedIndex();
+ if (selected >= 0)
+ select(selected);
+ }
+
+ native void create ();
+
+ native void append (String items[]);
+ native int nativeGetSelected ();
+ native void nativeAdd (String item, int index);
+ native void nativeRemove (int index);
+ native void nativeRemoveAll ();
+
+ native void connectSignals ();
+
+ public native void select (int position);
+
+ public void add (String item, int index)
+ {
+ int before = nativeGetSelected();
+
+ nativeAdd (item, index);
+
+ /* Generate an ItemEvent if we added the first one or
+ if we inserted at or before the currently selected item. */
+ if ((before < 0) || (before >= index))
+ {
+ // Must set our state before notifying listeners
+ ((Choice) awtComponent).select (((Choice) awtComponent).getItem (0));
+ postItemEvent (((Choice) awtComponent).getItem (0), ItemEvent.SELECTED);
+ }
+ }
+
+ public void remove (int index)
+ {
+ int before = nativeGetSelected();
+ int after;
+
+ nativeRemove (index);
+ after = nativeGetSelected();
+
+ /* Generate an ItemEvent if we are removing the currently selected item
+ and there are at least one item left. */
+ if ((before == index) && (after >= 0))
+ {
+ // Must set our state before notifying listeners
+ ((Choice) awtComponent).select (((Choice) awtComponent).getItem (0));
+ postItemEvent (((Choice) awtComponent).getItem (0), ItemEvent.SELECTED);
+ }
+ }
+
+ public void removeAll ()
+ {
+ nativeRemoveAll();
+ }
+
+ public void addItem (String item, int position)
+ {
+ add (item, position);
+ }
+
+ protected void postChoiceItemEvent (String label, int stateChange)
+ {
+ // Must set our state before notifying listeners
+ if (stateChange == ItemEvent.SELECTED)
+ ((Choice) awtComponent).select (label);
+ postItemEvent (label, stateChange);
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java
new file mode 100644
index 0000000..c719cdd
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java
@@ -0,0 +1,170 @@
+/* GtkClipboard.java
+ Copyright (C) 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.ClipboardOwner;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class GtkClipboard extends Clipboard
+{
+ /* the number of milliseconds that we'll wait around for the
+ owner of the GDK_SELECTION_PRIMARY selection to convert
+ the requested data */
+ static final int SELECTION_RECEIVED_TIMEOUT = 5000;
+
+ /* We currently only support transferring of text between applications */
+ static String selection;
+ static Object selectionLock = new Object ();
+
+ static boolean hasSelection = false;
+
+ protected GtkClipboard()
+ {
+ super("System Clipboard");
+ initNativeState();
+ }
+
+ public Transferable getContents(Object requestor)
+ {
+ synchronized (this)
+ {
+ if (hasSelection)
+ return contents;
+ }
+
+ /* Java doesn't own the selection, so we need to ask X11 */
+ // XXX: Does this hold with Swing too ?
+ synchronized (selectionLock)
+ {
+ requestStringConversion();
+
+ try
+ {
+ selectionLock.wait(SELECTION_RECEIVED_TIMEOUT);
+ }
+ catch (InterruptedException e)
+ {
+ return null;
+ }
+
+ return selection == null ? null : new StringSelection(selection);
+ }
+ }
+
+ void stringSelectionReceived(String newSelection)
+ {
+ synchronized (selectionLock)
+ {
+ selection = newSelection;
+ selectionLock.notify();
+ }
+ }
+
+ /* convert Java clipboard data into a String suitable for sending
+ to another application */
+ synchronized String stringSelectionHandler() throws IOException
+ {
+ String selection = null;
+
+ try
+ {
+ if (contents.isDataFlavorSupported(DataFlavor.stringFlavor))
+ selection = (String)contents.getTransferData(DataFlavor.stringFlavor);
+ else if (contents.isDataFlavorSupported(DataFlavor.plainTextFlavor))
+ {
+ StringBuffer sbuf = new StringBuffer();
+ InputStreamReader reader;
+ char readBuf[] = new char[512];
+ int numChars;
+
+ reader = new InputStreamReader
+ ((InputStream)
+ contents.getTransferData(DataFlavor.plainTextFlavor), "UNICODE");
+
+ while (true)
+ {
+ numChars = reader.read(readBuf);
+ if (numChars == -1)
+ break;
+ sbuf.append(readBuf, 0, numChars);
+ }
+
+ selection = new String(sbuf);
+ }
+ }
+ catch (Exception e)
+ {
+ }
+
+ return selection;
+ }
+
+ public synchronized void setContents(Transferable contents,
+ ClipboardOwner owner)
+ {
+ selectionGet();
+
+ this.contents = contents;
+ this.owner = owner;
+
+ hasSelection = true;
+ }
+
+ synchronized void selectionClear()
+ {
+ hasSelection = false;
+
+ if (owner != null)
+ {
+ owner.lostOwnership(this, contents);
+ owner = null;
+ contents = null;
+ }
+ }
+
+ native void initNativeState();
+ static native void requestStringConversion();
+ static native void selectionGet();
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java
new file mode 100644
index 0000000..1578a9c
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java
@@ -0,0 +1,651 @@
+/* GtkComponentPeer.java -- Implements ComponentPeer with GTK
+ Copyright (C) 1998, 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.AWTEvent;
+import java.awt.AWTException;
+import java.awt.BufferCapabilities;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.ItemSelectable;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.Window;
+import java.awt.event.FocusEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.PaintEvent;
+import java.awt.event.TextEvent;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.image.VolatileImage;
+import java.awt.peer.ComponentPeer;
+
+public class GtkComponentPeer extends GtkGenericPeer
+ implements ComponentPeer
+{
+ VolatileImage backBuffer;
+ BufferCapabilities caps;
+
+ Component awtComponent;
+
+ Insets insets;
+
+ boolean isInRepaint;
+
+ /* this isEnabled differs from Component.isEnabled, in that it
+ knows if a parent is disabled. In that case Component.isEnabled
+ may return true, but our isEnabled will always return false */
+ native boolean isEnabled ();
+ static native boolean modalHasGrab();
+
+ native int[] gtkWidgetGetForeground ();
+ native int[] gtkWidgetGetBackground ();
+ native void gtkWidgetGetDimensions (int[] dim);
+ native void gtkWidgetGetPreferredDimensions (int[] dim);
+ native void gtkWidgetGetLocationOnScreen (int[] point);
+ native void gtkWidgetSetCursor (int type);
+ native void gtkWidgetSetBackground (int red, int green, int blue);
+ native void gtkWidgetSetForeground (int red, int green, int blue);
+ native void gtkWidgetSetSensitive (boolean sensitive);
+ native void gtkWidgetSetParent (ComponentPeer parent);
+ native void gtkWidgetRequestFocus ();
+ native void gtkWidgetDispatchKeyEvent (int id, long when, int mods,
+ int keyCode, int keyLocation);
+
+ native boolean isRealized ();
+
+ void realize ()
+ {
+ // Default implementation does nothing
+ }
+
+ native void setNativeEventMask ();
+
+ void create ()
+ {
+ throw new RuntimeException ();
+ }
+
+ native void connectSignals ();
+
+ protected GtkComponentPeer (Component awtComponent)
+ {
+ super (awtComponent);
+ this.awtComponent = awtComponent;
+ insets = new Insets (0, 0, 0, 0);
+
+ create ();
+
+ connectSignals ();
+
+ if (awtComponent.getForeground () != null)
+ setForeground (awtComponent.getForeground ());
+ if (awtComponent.getBackground () != null)
+ setBackground (awtComponent.getBackground ());
+ if (awtComponent.getFont() != null)
+ setFont(awtComponent.getFont());
+
+ Component parent = awtComponent.getParent ();
+
+ // Only set our parent on the GTK side if our parent on the AWT
+ // side is not showing. Otherwise the gtk peer will be shown
+ // before we've had a chance to position and size it properly.
+ if (awtComponent instanceof Window
+ || (parent != null && ! parent.isShowing ()))
+ setParentAndBounds ();
+
+ setNativeEventMask ();
+
+ realize ();
+ }
+
+ void setParentAndBounds ()
+ {
+ setParent ();
+
+ setComponentBounds ();
+
+ setVisibleAndEnabled ();
+ }
+
+ void setParent ()
+ {
+ ComponentPeer p;
+ Component component = awtComponent;
+ do
+ {
+ component = component.getParent ();
+ p = component.getPeer ();
+ }
+ while (p instanceof java.awt.peer.LightweightPeer);
+
+ if (p != null)
+ gtkWidgetSetParent (p);
+ }
+
+ void beginNativeRepaint ()
+ {
+ isInRepaint = true;
+ }
+
+ void endNativeRepaint ()
+ {
+ isInRepaint = false;
+ }
+
+ /*
+ * Set the bounds of this peer's AWT Component based on dimensions
+ * returned by the native windowing system. Most Components impose
+ * their dimensions on the peers which is what the default
+ * implementation does. However some peers, like GtkFileDialogPeer,
+ * need to pass their size back to the AWT Component.
+ */
+ void setComponentBounds ()
+ {
+ Rectangle bounds = awtComponent.getBounds ();
+
+ if (bounds.x == 0 && bounds.y == 0
+ && bounds.width == 0 && bounds.height == 0)
+ return;
+
+ setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
+ }
+
+ void setVisibleAndEnabled ()
+ {
+ setVisible (awtComponent.isVisible ());
+ setEnabled (awtComponent.isEnabled ());
+ }
+
+ public int checkImage (Image image, int width, int height,
+ ImageObserver observer)
+ {
+ return getToolkit().checkImage(image, width, height, observer);
+ }
+
+ public Image createImage (ImageProducer producer)
+ {
+ return new GtkImage (producer);
+ }
+
+ public Image createImage (int width, int height)
+ {
+ Image image;
+ if (GtkToolkit.useGraphics2D ())
+ image = new BufferedImage (width, height, BufferedImage.TYPE_INT_RGB);
+ else
+ image = new GtkImage (width, height);
+
+ Graphics g = image.getGraphics();
+ g.setColor(getBackground());
+ g.fillRect(0, 0, width, height);
+ return image;
+ }
+
+ public void disable ()
+ {
+ setEnabled (false);
+ }
+
+ public void enable ()
+ {
+ setEnabled (true);
+ }
+
+ public ColorModel getColorModel ()
+ {
+ return ColorModel.getRGBdefault ();
+ }
+
+ public FontMetrics getFontMetrics (Font font)
+ {
+ return getToolkit().getFontMetrics(font);
+ }
+
+ public Graphics getGraphics ()
+ {
+ if (GtkToolkit.useGraphics2D ())
+ return new GdkGraphics2D (this);
+ else
+ return new GdkGraphics (this);
+ }
+
+ public Point getLocationOnScreen ()
+ {
+ int point[] = new int[2];
+ gtkWidgetGetLocationOnScreen (point);
+ return new Point (point[0], point[1]);
+ }
+
+ public Dimension getMinimumSize ()
+ {
+ return minimumSize ();
+ }
+
+ public Dimension getPreferredSize ()
+ {
+ return preferredSize ();
+ }
+
+ public Toolkit getToolkit ()
+ {
+ return Toolkit.getDefaultToolkit();
+ }
+
+ public void handleEvent (AWTEvent event)
+ {
+ int id = event.getID();
+ KeyEvent ke = null;
+
+ switch (id)
+ {
+ case PaintEvent.PAINT:
+ case PaintEvent.UPDATE:
+ {
+ try
+ {
+ Graphics g = getGraphics ();
+
+ // Some peers like GtkFileDialogPeer are repainted by Gtk itself
+ if (g == null)
+ break;
+
+ g.setClip (((PaintEvent) event).getUpdateRect());
+
+ if (id == PaintEvent.PAINT)
+ awtComponent.paint (g);
+ else
+ awtComponent.update (g);
+
+ g.dispose ();
+ }
+ catch (InternalError e)
+ {
+ System.err.println (e);
+ }
+ }
+ break;
+ case KeyEvent.KEY_PRESSED:
+ ke = (KeyEvent) event;
+ gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (),
+ ke.getKeyCode (), ke.getKeyLocation ());
+ break;
+ case KeyEvent.KEY_RELEASED:
+ ke = (KeyEvent) event;
+ gtkWidgetDispatchKeyEvent (ke.getID (), ke.getWhen (), ke.getModifiersEx (),
+ ke.getKeyCode (), ke.getKeyLocation ());
+ break;
+ }
+ }
+
+ public boolean isFocusTraversable ()
+ {
+ return true;
+ }
+
+ public Dimension minimumSize ()
+ {
+ int dim[] = new int[2];
+
+ gtkWidgetGetPreferredDimensions (dim);
+
+ return new Dimension (dim[0], dim[1]);
+ }
+
+ public void paint (Graphics g)
+ {
+ }
+
+ public Dimension preferredSize ()
+ {
+ int dim[] = new int[2];
+
+ gtkWidgetGetPreferredDimensions (dim);
+
+ return new Dimension (dim[0], dim[1]);
+ }
+
+ public boolean prepareImage (Image image, int width, int height,
+ ImageObserver observer)
+ {
+ return getToolkit().prepareImage(image, width, height, observer);
+ }
+
+ public void print (Graphics g)
+ {
+ throw new RuntimeException ();
+ }
+
+ public void repaint (long tm, int x, int y, int width, int height)
+ {
+ if (x == 0 && y == 0 && width == 0 && height == 0)
+ return;
+
+ q().postEvent (new PaintEvent (awtComponent, PaintEvent.UPDATE,
+ new Rectangle (x, y, width, height)));
+ }
+
+ public void requestFocus ()
+ {
+ gtkWidgetRequestFocus();
+ postFocusEvent(FocusEvent.FOCUS_GAINED, false);
+ }
+
+ public void reshape (int x, int y, int width, int height)
+ {
+ setBounds (x, y, width, height);
+ }
+
+ public void setBackground (Color c)
+ {
+ gtkWidgetSetBackground (c.getRed(), c.getGreen(), c.getBlue());
+ }
+
+ native void setNativeBounds (int x, int y, int width, int height);
+
+ public void setBounds (int x, int y, int width, int height)
+ {
+ Component parent = awtComponent.getParent ();
+
+ // Heavyweight components that are children of one or more
+ // lightweight containers have to be handled specially. Because
+ // calls to GLightweightPeer.setBounds do nothing, GTK has no
+ // knowledge of the lightweight containers' positions. So we have
+ // to add the offsets manually when placing a heavyweight
+ // component within a lightweight container. The lightweight
+ // container may itself be in a lightweight container and so on,
+ // so we need to continue adding offsets until we reach a
+ // container whose position GTK knows -- that is, the first
+ // non-lightweight.
+ boolean lightweightChild = false;
+ Insets i;
+ while (parent.isLightweight ())
+ {
+ lightweightChild = true;
+
+ i = ((Container) parent).getInsets ();
+
+ x += parent.getX () + i.left;
+ y += parent.getY () + i.top;
+
+ parent = parent.getParent ();
+ }
+
+ // We only need to convert from Java to GTK coordinates if we're
+ // placing a heavyweight component in a Window.
+ if (parent instanceof Window && !lightweightChild)
+ {
+ Insets insets = ((Window) parent).getInsets ();
+ GtkWindowPeer peer = (GtkWindowPeer) parent.getPeer ();
+ int menuBarHeight = 0;
+ if (peer instanceof GtkFramePeer)
+ menuBarHeight = ((GtkFramePeer) peer).getMenuBarHeight ();
+
+ // Convert from Java coordinates to GTK coordinates.
+ setNativeBounds (x - insets.left, y - insets.top + menuBarHeight,
+ width, height);
+ }
+ else
+ setNativeBounds (x, y, width, height);
+ }
+
+ void setCursor ()
+ {
+ setCursor (awtComponent.getCursor ());
+ }
+
+ public void setCursor (Cursor cursor)
+ {
+ gtkWidgetSetCursor (cursor.getType ());
+ }
+
+ public void setEnabled (boolean b)
+ {
+ gtkWidgetSetSensitive (b);
+ }
+
+ public void setFont (Font f)
+ {
+ // FIXME: This should really affect the widget tree below me.
+ // Currently this is only handled if the call is made directly on
+ // a text widget, which implements setFont() itself.
+ gtkWidgetModifyFont(f.getName(), f.getStyle(), f.getSize());
+ }
+
+ public void setForeground (Color c)
+ {
+ gtkWidgetSetForeground (c.getRed(), c.getGreen(), c.getBlue());
+ }
+
+ public Color getForeground ()
+ {
+ int rgb[] = gtkWidgetGetForeground ();
+ return new Color (rgb[0], rgb[1], rgb[2]);
+ }
+
+ public Color getBackground ()
+ {
+ int rgb[] = gtkWidgetGetBackground ();
+ return new Color (rgb[0], rgb[1], rgb[2]);
+ }
+
+ public void setVisible (boolean b)
+ {
+ if (b)
+ show ();
+ else
+ hide ();
+ }
+
+ public native void hide ();
+ public native void show ();
+
+ 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));
+ }
+
+ protected void postExposeEvent (int x, int y, int width, int height)
+ {
+ if (!isInRepaint)
+ q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT,
+ new Rectangle (x, y, width, height)));
+ }
+
+ protected void postKeyEvent (int id, long when, int mods,
+ int keyCode, char keyChar, int keyLocation)
+ {
+ KeyEvent keyEvent = new KeyEvent (awtComponent, id, when, mods,
+ keyCode, keyChar, keyLocation);
+
+ // Also post a KEY_TYPED event if keyEvent is a key press that
+ // doesn't represent an action or modifier key.
+ if (keyEvent.getID () == KeyEvent.KEY_PRESSED
+ && (!keyEvent.isActionKey ()
+ && keyCode != KeyEvent.VK_SHIFT
+ && keyCode != KeyEvent.VK_CONTROL
+ && keyCode != KeyEvent.VK_ALT))
+ {
+ synchronized (q)
+ {
+ q().postEvent (keyEvent);
+ q().postEvent (new KeyEvent (awtComponent, KeyEvent.KEY_TYPED, when, mods,
+ KeyEvent.VK_UNDEFINED, keyChar, keyLocation));
+ }
+ }
+ else
+ q().postEvent (keyEvent);
+ }
+
+ protected void postFocusEvent (int id, boolean temporary)
+ {
+ q().postEvent (new FocusEvent (awtComponent, id, temporary));
+ }
+
+ protected void postItemEvent (Object item, int stateChange)
+ {
+ q().postEvent (new ItemEvent ((ItemSelectable)awtComponent,
+ ItemEvent.ITEM_STATE_CHANGED,
+ item, stateChange));
+ }
+
+ protected void postTextEvent ()
+ {
+ q().postEvent (new TextEvent (awtComponent, TextEvent.TEXT_VALUE_CHANGED));
+ }
+
+ public GraphicsConfiguration getGraphicsConfiguration ()
+ {
+ // FIXME: just a stub for now.
+ return null;
+ }
+
+ public void setEventMask (long mask)
+ {
+ // FIXME: just a stub for now.
+ }
+
+ public boolean isFocusable ()
+ {
+ return false;
+ }
+
+ public boolean requestFocus (Component source, boolean b1,
+ boolean b2, long x)
+ {
+ return false;
+ }
+
+ public boolean isObscured ()
+ {
+ return false;
+ }
+
+ public boolean canDetermineObscurity ()
+ {
+ return false;
+ }
+
+ public void coalescePaintEvent (PaintEvent e)
+ {
+
+ }
+
+ public void updateCursorImmediately ()
+ {
+
+ }
+
+ public boolean handlesWheelScrolling ()
+ {
+ return false;
+ }
+
+ // Convenience method to create a new volatile image on the screen
+ // on which this component is displayed.
+ public VolatileImage createVolatileImage (int width, int height)
+ {
+ return new GtkVolatileImage (width, height);
+ }
+
+ // Creates buffers used in a buffering strategy.
+ public void createBuffers (int numBuffers, BufferCapabilities caps)
+ throws AWTException
+ {
+ // numBuffers == 2 implies double-buffering, meaning one back
+ // buffer and one front buffer.
+ if (numBuffers == 2)
+ backBuffer = new GtkVolatileImage(awtComponent.getWidth(),
+ awtComponent.getHeight(),
+ caps.getBackBufferCapabilities());
+ else
+ throw new AWTException("GtkComponentPeer.createBuffers:"
+ + " multi-buffering not supported");
+ this.caps = caps;
+ }
+
+ // Return the back buffer.
+ public Image getBackBuffer ()
+ {
+ return backBuffer;
+ }
+
+ // FIXME: flip should be implemented as a fast native operation
+ public void flip (BufferCapabilities.FlipContents contents)
+ {
+ getGraphics().drawImage(backBuffer,
+ awtComponent.getWidth(),
+ awtComponent.getHeight(),
+ null);
+
+ // create new back buffer and clear it to the background color.
+ if (contents == BufferCapabilities.FlipContents.BACKGROUND)
+ {
+ backBuffer = createVolatileImage(awtComponent.getWidth(),
+ awtComponent.getHeight());
+ backBuffer.getGraphics().clearRect(0, 0,
+ awtComponent.getWidth(),
+ awtComponent.getHeight());
+ }
+ // FIXME: support BufferCapabilities.FlipContents.PRIOR
+ }
+
+ // Release the resources allocated to back buffers.
+ public void destroyBuffers ()
+ {
+ backBuffer.flush();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java
new file mode 100644
index 0000000..c2865f7
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java
@@ -0,0 +1,156 @@
+/* GtkContainerPeer.java -- Implements ContainerPeer with GTK
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Window;
+import java.awt.peer.ComponentPeer;
+import java.awt.peer.ContainerPeer;
+
+public class GtkContainerPeer extends GtkComponentPeer
+ implements ContainerPeer
+{
+ Container c;
+ boolean isValidating;
+
+ public GtkContainerPeer(Container c)
+ {
+ super (c);
+ this.c = c;
+ }
+
+ public void beginValidate ()
+ {
+ isValidating = true;
+ }
+
+ public void endValidate ()
+ {
+ Component parent = awtComponent.getParent ();
+
+ // Only set our parent on the GTK side if our parent on the AWT
+ // side is not showing. Otherwise the gtk peer will be shown
+ // before we've had a chance to position and size it properly.
+ if (parent != null && parent.isShowing ())
+ {
+ Component[] components = ((Container) awtComponent).getComponents ();
+ int ncomponents = components.length;
+
+ for (int i = 0; i < ncomponents; i++)
+ {
+ ComponentPeer peer = components[i].getPeer ();
+
+ // Skip lightweight peers.
+ if (peer instanceof GtkComponentPeer)
+ ((GtkComponentPeer) peer).setParentAndBounds ();
+ }
+
+ // GTK windows don't have parents.
+ if (!(awtComponent instanceof Window))
+ setParentAndBounds ();
+ }
+
+ isValidating = false;
+ }
+
+ public Insets getInsets()
+ {
+ return insets;
+ }
+
+ public Insets insets()
+ {
+ return getInsets ();
+ }
+
+ public void setBounds (int x, int y, int width, int height)
+ {
+ super.setBounds (x, y, width, height);
+ }
+
+ public void setFont(Font f)
+ {
+ super.setFont(f);
+ Component[] components = ((Container) awtComponent).getComponents();
+ for (int i = 0; i < components.length; i++)
+ {
+ if (components[i].isLightweight ())
+ components[i].setFont (f);
+ else
+ {
+ GtkComponentPeer peer = (GtkComponentPeer) components[i].getPeer();
+ if (peer != null && ! peer.awtComponent.isFontSet())
+ peer.setFont(f);
+ }
+ }
+ }
+
+ public Graphics getGraphics ()
+ {
+ return super.getGraphics();
+ }
+
+ public void beginLayout () { }
+ public void endLayout () { }
+ public boolean isPaintPending () { return false; }
+
+ public void setBackground (Color c)
+ {
+ super.setBackground(c);
+
+ Object components[] = ((Container) awtComponent).getComponents();
+ for (int i = 0; i < components.length; i++)
+ {
+ Component comp = (Component) components[i];
+
+ // If the child's background has not been explicitly set yet,
+ // it should inherit this container's background. This makes the
+ // child component appear as if it has a transparent background.
+ // Note that we do not alter the background property of the child,
+ // but only repaint the child with the parent's background color.
+ if (!comp.isBackgroundSet() && comp.getPeer() != null)
+ comp.getPeer().setBackground(c);
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java
new file mode 100644
index 0000000..c2cbc37
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java
@@ -0,0 +1,94 @@
+/* GtkDialogPeer.java -- Implements DialogPeer with GTK
+ Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Dialog;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.event.PaintEvent;
+import java.awt.peer.DialogPeer;
+
+public class GtkDialogPeer extends GtkWindowPeer
+ implements DialogPeer
+{
+ public GtkDialogPeer (Dialog dialog)
+ {
+ super (dialog);
+ }
+
+ public Graphics getGraphics ()
+ {
+ Graphics g;
+ if (GtkToolkit.useGraphics2D ())
+ g = new GdkGraphics2D (this);
+ else
+ g = new GdkGraphics (this);
+ g.translate (-insets.left, -insets.top);
+ return g;
+ }
+
+ protected void postMouseEvent(int id, long when, int mods, int x, int y,
+ int clickCount, boolean popupTrigger)
+ {
+ super.postMouseEvent (id, when, mods,
+ x + insets.left, y + insets.top,
+ clickCount, popupTrigger);
+ }
+
+ protected void postExposeEvent (int x, int y, int width, int height)
+ {
+ if (!isInRepaint)
+ q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT,
+ new Rectangle (x + insets.left,
+ y + insets.top,
+ width, height)));
+ }
+
+ void create ()
+ {
+ // Create a decorated dialog window.
+ create (GDK_WINDOW_TYPE_HINT_DIALOG, true);
+
+ Dialog dialog = (Dialog) awtComponent;
+
+ gtkWindowSetModal (dialog.isModal ());
+ setTitle (dialog.getTitle ());
+ setResizable (dialog.isResizable ());
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.java
new file mode 100644
index 0000000..0533d27
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkEmbeddedWindowPeer.java
@@ -0,0 +1,73 @@
+/* GtkEmbeddedWindowPeer.java -- Implements EmbeddedWindowPeer using a
+ GtkPlug
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import gnu.java.awt.EmbeddedWindow;
+import gnu.java.awt.peer.EmbeddedWindowPeer;
+
+public class GtkEmbeddedWindowPeer extends GtkFramePeer
+ implements EmbeddedWindowPeer
+{
+ native void create (long socket_id);
+
+ void create ()
+ {
+ create (((EmbeddedWindow) awtComponent).getHandle ());
+ }
+
+ native void construct (long socket_id);
+
+ // FIXME: embed doesn't work right now, though I believe it should.
+ // This means that you can't call setVisible (true) on an
+ // EmbeddedWindow before calling setHandle with a valid handle. The
+ // problem is that somewhere after the call to
+ // GtkEmbeddedWindow.create and before the call to
+ // GtkEmbeddedWindow.construct, the GtkPlug peer is being realized.
+ // GtkSocket silently fails to embed an already-realized GtkPlug.
+ public void embed (long handle)
+ {
+ construct (handle);
+ }
+
+ public GtkEmbeddedWindowPeer (EmbeddedWindow w)
+ {
+ super (w);
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java
new file mode 100644
index 0000000..bd1f077
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java
@@ -0,0 +1,219 @@
+/* GtkFileDialogPeer.java -- Implements FileDialogPeer with GTK
+ Copyright (C) 1998, 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Dialog;
+import java.awt.FileDialog;
+import java.awt.Graphics;
+import java.awt.Window;
+import java.awt.peer.FileDialogPeer;
+import java.io.File;
+import java.io.FilenameFilter;
+
+public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer
+{
+ static final String FS = System.getProperty("file.separator");
+
+ private String currentFile = null;
+ private String currentDirectory = null;
+ private FilenameFilter filter;
+
+ native void create (GtkContainerPeer parent);
+ native void connectSignals ();
+ native void nativeSetFile (String file);
+ public native String nativeGetDirectory();
+ public native void nativeSetDirectory(String directory);
+ native void nativeSetFilenameFilter (FilenameFilter filter);
+
+ public void create()
+ {
+ create((GtkContainerPeer) awtComponent.getParent().getPeer());
+
+ FileDialog fd = (FileDialog) awtComponent;
+
+ setDirectory(fd.getDirectory());
+ setFile(fd.getFile());
+
+ FilenameFilter filter = fd.getFilenameFilter();
+ if (filter != null)
+ setFilenameFilter(filter);
+ }
+
+ public GtkFileDialogPeer (FileDialog fd)
+ {
+ super (fd);
+ }
+
+ void setComponentBounds ()
+ {
+ if (awtComponent.getHeight () == 0
+ && awtComponent.getWidth () == 0)
+ {
+ int[] dims = new int[2];
+ gtkWidgetGetPreferredDimensions (dims);
+ ((GtkFileDialogPeer) this).setBoundsCallback ((Window) awtComponent,
+ awtComponent.getX (),
+ awtComponent.getY (),
+ dims[0], dims[1]);
+ }
+ super.setComponentBounds ();
+ }
+
+ public void setFile (String fileName)
+ {
+ /* If nothing changed do nothing. This usually happens because
+ the only way we have to set the file name in FileDialog is by
+ calling its SetFile which will call us back. */
+ if ((fileName == null && currentFile == null)
+ || (fileName != null && fileName.equals (currentFile)))
+ return;
+
+ if (fileName == null || fileName.equals (""))
+ {
+ currentFile = "";
+ nativeSetFile ("");
+ return;
+ }
+
+ // GtkFileChooser requires absolute filenames. If the given filename
+ // is not absolute, let's construct it based on current directory.
+ currentFile = fileName;
+ if (fileName.indexOf(FS) == 0)
+ {
+ nativeSetFile (fileName);
+ }
+ else
+ {
+ nativeSetFile (nativeGetDirectory() + FS + fileName);
+ }
+ }
+
+ public void setDirectory (String directory)
+ {
+ /* If nothing changed so nothing. This usually happens because
+ the only way we have to set the directory in FileDialog is by
+ calling its setDirectory which will call us back. */
+ if ((directory == null && currentDirectory == null)
+ || (directory != null && directory.equals (currentDirectory)))
+ return;
+
+ if (directory == null || directory.equals (""))
+ {
+ currentDirectory = FS;
+ nativeSetFile (FS);
+ return;
+ }
+
+ currentDirectory = directory;
+ nativeSetDirectory (directory);
+ }
+
+ public void setFilenameFilter (FilenameFilter filter)
+ {
+ this.filter = filter;
+ nativeSetFilenameFilter(filter);
+ }
+
+ /* This method interacts with the native callback function of the
+ same name. The native function will extract the filename from the
+ GtkFileFilterInfo object and send it to this method, which will
+ in turn call the filter's accept() method and give back the return
+ value. */
+ boolean filenameFilterCallback (String fullname) {
+ String filename = fullname.substring(fullname.lastIndexOf(FS) + 1);
+ String dirname = fullname.substring(0, fullname.lastIndexOf(FS));
+ File dir = new File(dirname);
+ return filter.accept(dir, filename);
+ }
+
+ public Graphics getGraphics ()
+ {
+ // GtkFileDialog will repaint by itself
+ return null;
+ }
+
+ void gtkHideFileDialog ()
+ {
+ ((Dialog) awtComponent).hide();
+ }
+
+ void gtkDisposeFileDialog ()
+ {
+ ((Dialog) awtComponent).dispose();
+ }
+
+ /* Callback to set the file and directory values when the user is finished
+ * with the dialog.
+ */
+ void gtkSetFilename (String fileName)
+ {
+ FileDialog fd = (FileDialog) awtWidget;
+ if (fileName == null)
+ {
+ currentFile = null;
+ fd.setFile(null);
+ return;
+ }
+
+ int sepIndex = fileName.lastIndexOf (FS);
+ if (sepIndex < 0)
+ {
+ /* This should never happen on Unix (all paths start with '/') */
+ currentFile = fileName;
+ }
+ else
+ {
+ if (fileName.length() > (sepIndex + 1))
+ {
+ String fn = fileName.substring (sepIndex + 1);
+ currentFile = fn;
+ }
+ else
+ {
+ currentFile = null;
+ }
+
+ String dn = fileName.substring (0, sepIndex + 1);
+ currentDirectory = dn;
+ fd.setDirectory(dn);
+ }
+
+ fd.setFile (currentFile);
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFontPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFontPeer.java
new file mode 100644
index 0000000..80ad158
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFontPeer.java
@@ -0,0 +1,225 @@
+/* GtkFontPeer.java -- Implements FontPeer with GTK+
+ Copyright (C) 1999, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import gnu.java.awt.peer.ClasspathFontPeer;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.LineMetrics;
+import java.awt.geom.Rectangle2D;
+import java.text.CharacterIterator;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class GtkFontPeer extends ClasspathFontPeer
+{
+ private static ResourceBundle bundle;
+
+ static
+ {
+ try
+ {
+ bundle = ResourceBundle.getBundle ("gnu.java.awt.peer.gtk.font");
+ }
+ catch (Throwable ignored)
+ {
+ bundle = null;
+ }
+ }
+
+ private final String Xname;
+
+ public GtkFontPeer (String name, int style)
+ {
+ // All fonts get a default size of 12 if size is not specified.
+ this(name, style, 12);
+ }
+
+ public GtkFontPeer (String name, int style, int size)
+ {
+ super(name, style, size);
+
+ String Xname = null;
+ if (bundle != null)
+ {
+ try
+ {
+ Xname = bundle.getString (name.toLowerCase () + "." + style);
+ }
+ catch (MissingResourceException mre)
+ {
+ // ignored
+ }
+ }
+
+ if (Xname == null)
+ {
+ String weight;
+ String slant;
+ String spacing;
+
+ if (style == Font.ITALIC || (style == (Font.BOLD+Font.ITALIC)))
+ slant = "i";
+ else
+ slant = "r";
+ if (style == Font.BOLD || (style == (Font.BOLD+Font.ITALIC)))
+ weight = "bold";
+ else
+ weight = "medium";
+ if (name.equals("Serif") || name.equals("SansSerif")
+ || name.equals("Helvetica") || name.equals("Times"))
+ spacing = "p";
+ else
+ spacing = "c";
+
+ Xname = "-*-*-" + weight + "-" + slant + "-normal-*-*-" + size + "-*-*-" + spacing + "-*-*-*";
+ }
+
+ this.Xname = Xname;
+ }
+
+ public String getXLFD ()
+ {
+ return Xname;
+ }
+
+
+ /* remaining methods are for static compatibility with the newer
+ ClasspathFontPeer superclass; none of these methods ever existed or
+ worked on the older FontPeer interface, but we need to pretend to
+ support them anyways. */
+
+ public boolean canDisplay (Font font, char c)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getSubFamilyName (Font font, Locale locale)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getPostScriptName (Font font)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getNumGlyphs (Font font)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int getMissingGlyphCode (Font font)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public byte getBaselineFor (Font font, char c)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getGlyphName (Font font, int glyphIndex)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public GlyphVector createGlyphVector (Font font,
+ FontRenderContext frc,
+ CharacterIterator ci)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public GlyphVector createGlyphVector (Font font,
+ FontRenderContext ctx,
+ int[] glyphCodes)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public GlyphVector layoutGlyphVector (Font font,
+ FontRenderContext frc,
+ char[] chars, int start,
+ int limit, int flags)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public FontMetrics getFontMetrics (Font font)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasUniformLineMetrics (Font font)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public LineMetrics getLineMetrics (Font font,
+ CharacterIterator ci,
+ int begin, int limit,
+ FontRenderContext rc)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Rectangle2D getMaxCharBounds (Font font,
+ FontRenderContext rc)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Rectangle2D getStringBounds (Font font,
+ CharacterIterator ci,
+ int begin, int limit,
+ FontRenderContext frc)
+ {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java
new file mode 100644
index 0000000..b242d66
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java
@@ -0,0 +1,256 @@
+/* GtkFramePeer.java -- Implements FramePeer with GTK
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.MenuBar;
+import java.awt.Rectangle;
+import java.awt.Window;
+import java.awt.event.PaintEvent;
+import java.awt.image.ColorModel;
+import java.awt.peer.FramePeer;
+import java.awt.peer.MenuBarPeer;
+
+public class GtkFramePeer extends GtkWindowPeer
+ implements FramePeer
+{
+ private int menuBarHeight;
+ private MenuBarPeer menuBar;
+ native int getMenuBarHeight (MenuBarPeer bar);
+ native void setMenuBarWidth (MenuBarPeer bar, int width);
+ native void setMenuBarPeer (MenuBarPeer bar);
+ native void removeMenuBarPeer ();
+ native void gtkFixedSetVisible (boolean visible);
+
+ int getMenuBarHeight ()
+ {
+ return menuBar == null ? 0 : getMenuBarHeight (menuBar);
+ }
+
+ public void setMenuBar (MenuBar bar)
+ {
+ if (bar == null && menuBar != null)
+ {
+ // We're removing the menubar.
+ gtkFixedSetVisible (false);
+ menuBar = null;
+ removeMenuBarPeer ();
+ insets.top -= menuBarHeight;
+ menuBarHeight = 0;
+ awtComponent.validate ();
+ gtkFixedSetVisible (true);
+ }
+ else if (bar != null && menuBar == null)
+ {
+ // We're adding a menubar where there was no menubar before.
+ gtkFixedSetVisible (false);
+ menuBar = (MenuBarPeer) ((MenuBar) bar).getPeer();
+ setMenuBarPeer (menuBar);
+ int menuBarWidth =
+ awtComponent.getWidth () - insets.left - insets.right;
+ if (menuBarWidth > 0)
+ setMenuBarWidth (menuBar, menuBarWidth);
+ menuBarHeight = getMenuBarHeight ();
+ insets.top += menuBarHeight;
+ awtComponent.validate ();
+ gtkFixedSetVisible (true);
+ }
+ else if (bar != null && menuBar != null)
+ {
+ // We're swapping the menubar.
+ gtkFixedSetVisible (false);
+ removeMenuBarPeer();
+ int oldHeight = menuBarHeight;
+ int menuBarWidth =
+ awtComponent.getWidth () - insets.left - insets.right;
+ menuBar = (MenuBarPeer) ((MenuBar) bar).getPeer ();
+ setMenuBarPeer (menuBar);
+ if (menuBarWidth > 0)
+ setMenuBarWidth (menuBar, menuBarWidth);
+ menuBarHeight = getMenuBarHeight ();
+ if (oldHeight != menuBarHeight)
+ {
+ insets.top += (menuBarHeight - oldHeight);
+ awtComponent.validate ();
+ }
+ gtkFixedSetVisible (true);
+ }
+ }
+
+ public void setBounds (int x, int y, int width, int height)
+ {
+ int menuBarWidth = width - insets.left - insets.right;
+ if (menuBar != null && menuBarWidth > 0)
+ setMenuBarWidth (menuBar, menuBarWidth);
+
+ nativeSetBounds (x, y,
+ width - insets.left - insets.right,
+ height - insets.top - insets.bottom
+ + menuBarHeight);
+ }
+
+ public void setResizable (boolean resizable)
+ {
+ // Call setSize; otherwise when resizable is changed from true to
+ // false the frame will shrink to the dimensions it had before it
+ // was resizable.
+ setSize (awtComponent.getWidth() - insets.left - insets.right,
+ awtComponent.getHeight() - insets.top - insets.bottom
+ + menuBarHeight);
+ gtkWindowSetResizable (resizable);
+ }
+
+ protected void postInsetsChangedEvent (int top, int left,
+ int bottom, int right)
+ {
+ insets.top = top + menuBarHeight;
+ insets.left = left;
+ insets.bottom = bottom;
+ insets.right = right;
+ }
+
+ public GtkFramePeer (Frame frame)
+ {
+ super (frame);
+ }
+
+ void create ()
+ {
+ // Create a normal decorated window.
+ create (GDK_WINDOW_TYPE_HINT_NORMAL, true);
+
+ Frame frame = (Frame) awtComponent;
+
+ setMenuBar (frame.getMenuBar ());
+
+ setTitle (frame.getTitle ());
+ gtkWindowSetResizable (frame.isResizable ());
+ setIconImage(frame.getIconImage());
+ }
+
+ native void nativeSetIconImage (GtkImage image);
+
+ public void setIconImage (Image image)
+ {
+ if (image != null)
+ {
+ if (image instanceof GtkImage)
+ nativeSetIconImage((GtkImage) image);
+ else
+ nativeSetIconImage(new GtkImage(image.getSource()));
+ }
+ }
+
+ public Graphics getGraphics ()
+ {
+ Graphics g;
+ if (GtkToolkit.useGraphics2D ())
+ g = new GdkGraphics2D (this);
+ else
+ g = new GdkGraphics (this);
+ g.translate (-insets.left, -insets.top);
+ return g;
+ }
+
+ protected void postConfigureEvent (int x, int y, int width, int height)
+ {
+ int frame_x = x - insets.left;
+ // Since insets.top includes the MenuBar height, we need to add back
+ // the MenuBar height to the frame's y position.
+ // If no MenuBar exists in this frame, the MenuBar height will be 0.
+ int frame_y = y - insets.top + menuBarHeight;
+ int frame_width = width + insets.left + insets.right;
+ // Ditto as above. Since insets.top already includes the MenuBar's height,
+ // we need to subtract the MenuBar's height from the top inset.
+ int frame_height = height + insets.top + insets.bottom - menuBarHeight;
+ if (frame_x != awtComponent.getX()
+ || frame_y != awtComponent.getY()
+ || frame_width != awtComponent.getWidth()
+ || frame_height != awtComponent.getHeight())
+ {
+ if (frame_width != awtComponent.getWidth() && menuBar != null
+ && width > 0)
+ setMenuBarWidth (menuBar, width);
+
+ setBoundsCallback ((Window) awtComponent,
+ frame_x,
+ frame_y,
+ frame_width,
+ frame_height);
+
+ awtComponent.validate();
+ }
+ }
+
+ protected void postMouseEvent(int id, long when, int mods, int x, int y,
+ int clickCount, boolean popupTrigger)
+ {
+ super.postMouseEvent (id, when, mods,
+ x + insets.left, y + insets.top,
+ clickCount, popupTrigger);
+ }
+
+ protected void postExposeEvent (int x, int y, int width, int height)
+ {
+ if (!isInRepaint)
+ q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT,
+ new Rectangle (x + insets.left,
+ y + insets.top,
+ width, height)));
+ }
+
+ public int getState ()
+ {
+ return 0;
+ }
+
+ public void setState (int state)
+ {
+
+ }
+
+ public void setMaximizedBounds (Rectangle r)
+ {
+
+ }
+}
+
+
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkGenericPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkGenericPeer.java
new file mode 100644
index 0000000..705eed2
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkGenericPeer.java
@@ -0,0 +1,98 @@
+/* GtkGenericPeer.java - Has a hashcode. Yuck.
+ Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.EventQueue;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+
+public class GtkGenericPeer
+{
+ final int native_state = getUniqueInteger ();
+
+ // Next native state value we will assign.
+ private static int next_native_state = 0;
+
+ // The widget or other java-side object we wrap.
+ protected Object awtWidget;
+
+ // Global event queue.
+ protected static EventQueue q = null;
+
+ // Dispose of our native state.
+ public native void dispose ();
+
+ static EventQueue q ()
+ {
+ return Toolkit.getDefaultToolkit ().getSystemEventQueue ();
+ }
+
+ protected GtkGenericPeer (Object awtWidget)
+ {
+ this.awtWidget = awtWidget;
+ }
+
+ public static void enableQueue (EventQueue sq)
+ {
+ if (q == null)
+ q = sq;
+ }
+
+ protected void postActionEvent (String command, int mods)
+ {
+ q().postEvent (new ActionEvent (awtWidget, ActionEvent.ACTION_PERFORMED,
+ command, mods));
+ }
+
+ // Return a unique integer for use in the native state mapping
+ // code. We can't use a hash code since that is not guaranteed to
+ // be unique.
+ static synchronized int getUniqueInteger ()
+ {
+ // Let's assume this will never wrap.
+ return next_native_state++;
+ }
+
+ native void gtkWidgetModifyFont (String name, int style, int size);
+
+ static void printCurrentThread ()
+ {
+ System.out.println ("gtkgenericpeer, thread: " + Thread.currentThread ());
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java
new file mode 100644
index 0000000..abb4137
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java
@@ -0,0 +1,494 @@
+/* GtkImage.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Graphics;
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.MemoryImageSource;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Vector;
+import gnu.classpath.RawData;
+
+/**
+ * GtkImage - wraps a GdkPixbuf or GdkPixmap.
+ *
+ * The constructor GtkImage(int, int) creates an 'off-screen' GdkPixmap,
+ * this can be drawn to (it's a GdkDrawable), and correspondingly, you can
+ * create a GdkGraphics object for it.
+ *
+ * This corresponds to the Image implementation returned by
+ * Component.createImage(int, int).
+ *
+ * A GdkPixbuf is 'on-screen' and the gdk cannot draw to it,
+ * this is used for the other constructors (and other createImage methods), and
+ * corresponds to the Image implementations returned by the Toolkit.createImage
+ * methods, and is basically immutable.
+ *
+ * @author Sven de Marothy
+ */
+public class GtkImage extends Image
+{
+ int width = -1, height = -1;
+
+ /**
+ * Properties.
+ */
+ Hashtable props;
+
+ /**
+ * Loaded or not flag, for asynchronous compatibility.
+ */
+ boolean isLoaded;
+
+ /**
+ * Pointer to the GdkPixbuf
+ */
+ RawData pixmap;
+
+ /**
+ * Observer queue.
+ */
+ Vector observers;
+
+ /**
+ * If offScreen is set, a GdkBitmap is wrapped and not a Pixbuf.
+ */
+ boolean offScreen;
+
+ /**
+ * Error flag for loading.
+ */
+ boolean errorLoading;
+
+ /**
+ * Original source, if created from an ImageProducer.
+ */
+ ImageProducer source;
+
+ /*
+ * The 32-bit AABBGGRR format the GDK uses.
+ */
+ static ColorModel nativeModel = new DirectColorModel(32,
+ 0x000000FF,
+ 0x0000FF00,
+ 0x00FF0000,
+ 0xFF000000);
+
+ /**
+ * Returns a copy of the pixel data as a java array.
+ */
+ private native int[] getPixels();
+
+ /**
+ * Sets the pixel data from a java array.
+ */
+ private native void setPixels(int[] pixels);
+
+ /**
+ * Loads an image using gdk-pixbuf.
+ */
+ private native boolean loadPixbuf(String name);
+
+ /**
+ * Allocates a Gtk Pixbuf or pixmap
+ */
+ private native void createPixmap();
+
+ /**
+ * Frees the above.
+ */
+ private native void freePixmap();
+
+ /**
+ * Sets the pixmap to scaled copy of src image. hints are rendering hints.
+ */
+ private native void createScaledPixmap(GtkImage src, int hints);
+
+ /**
+ * Draws the image, optionally scaled and composited.
+ */
+ private native void drawPixelsScaled (GdkGraphics gc,
+ int bg_red, int bg_green, int bg_blue,
+ int x, int y, int width, int height,
+ boolean composite);
+
+ /**
+ * Draws the image, optionally scaled flipped and composited.
+ */
+ private native void drawPixelsScaledFlipped (GdkGraphics gc,
+ int bg_red, int bg_green,
+ int bg_blue,
+ boolean flipX, boolean flipY,
+ int srcX, int srcY,
+ int srcWidth, int srcHeight,
+ int dstX, int dstY,
+ int dstWidth, int dstHeight,
+ boolean composite);
+
+ /**
+ * Constructs a GtkImage from an ImageProducer. Asynchronity is handled in
+ * the following manner:
+ * A GtkImageConsumer gets the image data, and calls setImage() when
+ * completely finished. The GtkImage is not considered loaded until the
+ * GtkImageConsumer is completely finished. We go for all "all or nothing".
+ */
+ public GtkImage (ImageProducer producer)
+ {
+ isLoaded = false;
+ observers = new Vector();
+ source = producer;
+ errorLoading = false;
+ source.startProduction(new GtkImageConsumer(this, source));
+ offScreen = false;
+ }
+
+ /**
+ * Constructs a GtkImage by loading a given file.
+ *
+ * @throws IllegalArgumentException if the image could not be loaded.
+ */
+ public GtkImage (String filename)
+ {
+ File f = new File(filename);
+ try
+ {
+ if (loadPixbuf(f.getCanonicalPath()) != true)
+ throw new IllegalArgumentException("Couldn't load image: "+filename);
+ }
+ catch(IOException e)
+ {
+ throw new IllegalArgumentException("Couldn't load image: "+filename);
+ }
+
+ isLoaded = true;
+ observers = null;
+ offScreen = false;
+ props = new Hashtable();
+ }
+
+ /**
+ * Constructs an empty GtkImage.
+ */
+ public GtkImage (int width, int height)
+ {
+ this.width = width;
+ this.height = height;
+ props = new Hashtable();
+ isLoaded = true;
+ observers = null;
+ offScreen = true;
+ createPixmap();
+ }
+
+ /**
+ * Constructs a scaled version of the src bitmap, using the GDK.
+ */
+ private GtkImage (GtkImage src, int width, int height, int hints)
+ {
+ this.width = width;
+ this.height = height;
+ props = new Hashtable();
+ isLoaded = true;
+ observers = null;
+ offScreen = false;
+
+ // Use the GDK scaling method.
+ createScaledPixmap(src, hints);
+ }
+
+ /**
+ * Callback from the image consumer.
+ */
+ public void setImage(int width, int height,
+ int[] pixels, Hashtable properties)
+ {
+ this.width = width;
+ this.height = height;
+ props = (properties != null) ? properties : new Hashtable();
+
+ if (width <= 0 || height <= 0 || pixels == null)
+ {
+ errorLoading = true;
+ return;
+ }
+
+ isLoaded = true;
+ deliver();
+ createPixmap();
+ setPixels(pixels);
+ }
+
+ // java.awt.Image methods ////////////////////////////////////////////////
+
+ public synchronized int getWidth (ImageObserver observer)
+ {
+ if (addObserver(observer))
+ return -1;
+
+ return width;
+ }
+
+ public synchronized int getHeight (ImageObserver observer)
+ {
+ if (addObserver(observer))
+ return -1;
+
+ return height;
+ }
+
+ public synchronized Object getProperty (String name, ImageObserver observer)
+ {
+ if (addObserver(observer))
+ return UndefinedProperty;
+
+ Object value = props.get (name);
+ return (value == null) ? UndefinedProperty : value;
+ }
+
+ /**
+ * Returns the source of this image.
+ */
+ public ImageProducer getSource ()
+ {
+ if (!isLoaded)
+ return null;
+ return new MemoryImageSource(width, height, nativeModel, getPixels(),
+ 0, width);
+ }
+
+ /**
+ * Creates a GdkGraphics context for this pixmap.
+ */
+ public Graphics getGraphics ()
+ {
+ if (!isLoaded)
+ return null;
+ if (offScreen)
+ return new GdkGraphics(this);
+ else
+ throw new IllegalAccessError("This method only works for off-screen"
+ +" Images.");
+ }
+
+ /**
+ * Returns a scaled instance of this pixmap.
+ */
+ public Image getScaledInstance(int width,
+ int height,
+ int hints)
+ {
+ if (width <= 0 || height <= 0)
+ throw new IllegalArgumentException("Width and height of scaled bitmap"+
+ "must be >= 0");
+
+ return new GtkImage(this, width, height, hints);
+ }
+
+ /**
+ * If the image is loaded and comes from an ImageProducer,
+ * regenerate the image from there.
+ *
+ * I have no idea if this is ever actually used. Since GtkImage can't be
+ * instantiated directly, how is the user to know if it was created from
+ * an ImageProducer or not?
+ */
+ public synchronized void flush ()
+ {
+ if (isLoaded && source != null)
+ {
+ observers = new Vector();
+ isLoaded = false;
+ freePixmap();
+ source.startProduction(new GtkImageConsumer(this, source));
+ }
+ }
+
+ public void finalize()
+ {
+ if (isLoaded)
+ freePixmap();
+ }
+
+ /**
+ * Returns the image status, used by GtkToolkit
+ */
+ public int checkImage (ImageObserver observer)
+ {
+ if (addObserver(observer))
+ {
+ if (errorLoading == true)
+ return ImageObserver.ERROR;
+ else
+ return 0;
+ }
+
+ return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT;
+ }
+
+ // Drawing methods ////////////////////////////////////////////////
+
+ /**
+ * Draws an image with eventual scaling/transforming.
+ */
+ public boolean drawImage (GdkGraphics g, int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2,
+ Color bgcolor, ImageObserver observer)
+ {
+ if (addObserver(observer))
+ return false;
+
+ boolean flipX = (dx1 > dx2)^(sx1 > sx2);
+ boolean flipY = (dy1 > dy2)^(sy1 > sy2);
+ int dstWidth = Math.abs (dx2 - dx1);
+ int dstHeight = Math.abs (dy2 - dy1);
+ int srcWidth = Math.abs (sx2 - sx1);
+ int srcHeight = Math.abs (sy2 - sy1);
+ int srcX = (sx1 < sx2) ? sx1 : sx2;
+ int srcY = (sy1 < sy2) ? sy1 : sy2;
+ int dstX = (dx1 < dx2) ? dx1 : dx2;
+ int dstY = (dy1 < dy2) ? dy1 : dy2;
+
+ // Clipping. This requires the dst to be scaled as well,
+ if (srcWidth > width)
+ {
+ dstWidth = (int)((double)dstWidth*((double)width/(double)srcWidth));
+ srcWidth = width - srcX;
+ }
+
+ if (srcHeight > height)
+ {
+ dstHeight = (int)((double)dstHeight*((double)height/(double)srcHeight));
+ srcHeight = height - srcY;
+ }
+
+ if (srcWidth + srcX > width)
+ {
+ dstWidth = (int)((double)dstWidth * (double)(width - srcX)/(double)srcWidth);
+ srcWidth = width - srcX;
+ }
+
+ if (srcHeight + srcY > height)
+ {
+ dstHeight = (int)((double)dstHeight * (double)(width - srcY)/(double)srcHeight);
+ srcHeight = height - srcY;
+ }
+
+ if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0)
+ return true;
+
+ if(bgcolor != null)
+ drawPixelsScaledFlipped (g, bgcolor.getRed (), bgcolor.getGreen (),
+ bgcolor.getBlue (),
+ flipX, flipY,
+ srcX, srcY,
+ srcWidth, srcHeight,
+ dstX, dstY,
+ dstWidth, dstHeight,
+ true);
+ else
+ drawPixelsScaledFlipped (g, 0, 0, 0, flipX, flipY,
+ srcX, srcY, srcWidth, srcHeight,
+ dstX, dstY, dstWidth, dstHeight,
+ false);
+ return true;
+ }
+
+ /**
+ * Draws an image to the GdkGraphics context, at (x,y) scaled to
+ * width and height, with optional compositing with a background color.
+ */
+ public boolean drawImage (GdkGraphics g, int x, int y, int width, int height,
+ Color bgcolor, ImageObserver observer)
+ {
+ if (addObserver(observer))
+ return false;
+
+ if(bgcolor != null)
+ drawPixelsScaled(g, bgcolor.getRed (), bgcolor.getGreen (),
+ bgcolor.getBlue (), x, y, width, height, true);
+ else
+ drawPixelsScaled(g, 0, 0, 0, x, y, width, height, false);
+
+ return true;
+ }
+
+ // Private methods ////////////////////////////////////////////////
+
+ /**
+ * Delivers notifications to all queued observers.
+ */
+ private void deliver()
+ {
+ int flags = ImageObserver.HEIGHT |
+ ImageObserver.WIDTH |
+ ImageObserver.PROPERTIES |
+ ImageObserver.ALLBITS;
+
+ if (observers != null)
+ for(int i=0; i < observers.size(); i++)
+ ((ImageObserver)observers.elementAt(i)).
+ imageUpdate(this, flags, 0, 0, width, height);
+
+ observers = null;
+ }
+
+ /**
+ * Adds an observer, if we need to.
+ * @return true if an observer was added.
+ */
+ private boolean addObserver(ImageObserver observer)
+ {
+ if (!isLoaded)
+ {
+ if(observer != null)
+ if (!observers.contains (observer))
+ observers.addElement (observer);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java
new file mode 100644
index 0000000..564cc8d
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java
@@ -0,0 +1,155 @@
+/* GtkImageConsumer.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * Helper class to GtkImage. Sits and gathers pixels for a GtkImage and then
+ * calls GtkImage.setImage().
+ *
+ * @author Sven de Marothy
+ */
+public class GtkImageConsumer implements ImageConsumer
+{
+ private GtkImage target;
+ private int width, height;
+ private Hashtable properties;
+ private int[] pixelCache = null;
+ private ImageProducer source;
+
+ public GtkImageConsumer(GtkImage target, ImageProducer source)
+ {
+ this.target = target;
+ this.source = source;
+ }
+
+ public synchronized void imageComplete (int status)
+ {
+ source.removeConsumer(this);
+ target.setImage(width, height, pixelCache, properties);
+ }
+
+ public synchronized void setColorModel (ColorModel model)
+ {
+ // This method is to inform on what the most used color model
+ // in the image is, for optimization reasons. We ignore this
+ // information.
+ }
+
+ public synchronized void setDimensions (int width, int height)
+ {
+ pixelCache = new int[width*height];
+
+ this.width = width;
+ this.height = height;
+ }
+
+ public synchronized void setHints (int flags)
+ {
+ // This method informs us in which order the pixels are
+ // delivered, for progressive-loading support, etc.
+ // Since we wait until it's all loaded, we can ignore the hints.
+ }
+
+ public synchronized void setPixels (int x, int y, int width, int height,
+ ColorModel cm, byte[] pixels,
+ int offset, int scansize)
+ {
+ setPixels (x, y, width, height, cm, convertPixels (pixels), offset,
+ scansize);
+ }
+
+ public synchronized void setPixels (int x, int y, int width, int height,
+ ColorModel cm, int[] pixels,
+ int offset, int scansize)
+ {
+ if (pixelCache == null)
+ return; // Not sure this should ever happen.
+
+ if (cm.equals(GtkImage.nativeModel))
+ for (int i = 0; i < height; i++)
+ System.arraycopy (pixels, offset + (i * scansize),
+ pixelCache, (y + i) * this.width + x,
+ width);
+ else
+ {
+ for (int i = 0; i < height; i++)
+ for (int j = 0; j < width; j++)
+ {
+ // get in AARRGGBB and convert to AABBGGRR
+ int pix = cm.getRGB(pixels[offset + (i * scansize) + x + j]);
+ byte b = (byte)(pix & 0xFF);
+ byte r = (byte)(((pix & 0x00FF0000) >> 16) & 0xFF);
+ pix &= 0xFF00FF00;
+ pix |= ((b & 0xFF) << 16);
+ pix |= (r & 0xFF);
+ pixelCache[(y + i) * this.width + x + j] = pix;
+ }
+ }
+ }
+
+ /**
+ * This is an old method, no idea if it's correct.
+ */
+ private int[] convertPixels (byte[] pixels)
+ {
+ int ret[] = new int[pixels.length];
+
+ for (int i = 0; i < pixels.length; i++)
+ ret[i] = pixels[i] & 0xFF;
+
+ return ret;
+ }
+
+ public synchronized void setProperties (Hashtable props)
+ {
+ this.properties = props;
+ }
+}
+
+
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java
new file mode 100644
index 0000000..fdd5fd1
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java
@@ -0,0 +1,84 @@
+/* GtkLabelPeer.java -- Implements LabelPeer with GTK
+ Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Label;
+import java.awt.peer.LabelPeer;
+
+public class GtkLabelPeer extends GtkComponentPeer
+ implements LabelPeer
+{
+ native void create (String text, float alignment);
+ native void gtkWidgetModifyFont (String name, int style, int size);
+ native void nativeSetAlignment (float alignment);
+
+ public native void setText(String text);
+ native void setNativeBounds (int x, int y, int width, int height);
+
+ void create ()
+ {
+ Label label = (Label) awtComponent;
+ create (label.getText (), getGtkAlignment (label.getAlignment ()));
+ }
+
+ public GtkLabelPeer (Label l)
+ {
+ super (l);
+ }
+
+ public void setAlignment (int alignment)
+ {
+ nativeSetAlignment (getGtkAlignment (alignment));
+ }
+
+ float getGtkAlignment (int alignment)
+ {
+ switch (alignment)
+ {
+ case Label.LEFT:
+ return 0.0f;
+ case Label.CENTER:
+ return 0.5f;
+ case Label.RIGHT:
+ return 1.0f;
+ }
+
+ return 0.0f;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java
new file mode 100644
index 0000000..ff12fe3
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java
@@ -0,0 +1,180 @@
+/* GtkListPeer.java -- Implements ListPeer with GTK
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.AWTEvent;
+import java.awt.Dimension;
+import java.awt.List;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.peer.ListPeer;
+
+public class GtkListPeer extends GtkComponentPeer
+ implements ListPeer
+{
+ void create ()
+ {
+ List list = (List) awtComponent;
+
+ create (list.getRows ());
+
+ setMultipleMode (list.isMultipleMode ());
+ }
+
+ native void create (int rows);
+ native void connectSignals ();
+ native void gtkWidgetModifyFont (String name, int style, int size);
+ native void gtkWidgetRequestFocus ();
+
+ native void getSize (int rows, int visibleRows, int dims[]);
+
+ public GtkListPeer (List list)
+ {
+ super (list);
+
+ setMultipleMode (list.isMultipleMode ());
+
+ if (list.getItemCount () > 0)
+ append (list.getItems ());
+ }
+
+ native void append (String items[]);
+
+ public native void add (String item, int index);
+
+ public void addItem (String item, int index)
+ {
+ add (item, index);
+ }
+
+ public void clear ()
+ {
+ removeAll ();
+ }
+
+ public native void delItems (int start, int end);
+ public native void deselect (int index);
+
+ public Dimension getMinimumSize (int rows)
+ {
+ return minimumSize (rows);
+ }
+
+ public Dimension getPreferredSize (int rows)
+ {
+ return preferredSize (rows);
+ }
+
+ public native int[] getSelectedIndexes ();
+ public native void makeVisible (int index);
+
+ public Dimension minimumSize (int rows)
+ {
+ int dims[] = new int[2];
+
+ int visibleRows = ((List) awtComponent).getRows();
+ getSize (rows, visibleRows, dims);
+ return new Dimension (dims[0], dims[1]);
+ }
+
+ public Dimension preferredSize (int rows)
+ {
+ int dims[] = new int[2];
+
+ int visibleRows = ((List) awtComponent).getRows();
+ getSize (rows, visibleRows, dims);
+ return new Dimension (dims[0], dims[1]);
+ }
+
+ public void removeAll ()
+ {
+ delItems (0, -1);
+ }
+
+ public native void select (int index);
+ public native void setMultipleMode (boolean b);
+
+ public void setMultipleSelections (boolean b)
+ {
+ setMultipleMode (b);
+ }
+
+ public void handleEvent (AWTEvent e)
+ {
+ if (e.getID () == MouseEvent.MOUSE_CLICKED && isEnabled ())
+ {
+ // Only generate the ActionEvent on the second click of a
+ // multiple click.
+ MouseEvent me = (MouseEvent) e;
+ if (!me.isConsumed ()
+ && (me.getModifiersEx () & MouseEvent.BUTTON1_DOWN_MASK) != 0
+ && me.getClickCount() == 2)
+ {
+ String selectedItem = ((List) awtComponent).getSelectedItem ();
+
+ // Double-click only generates an Action event if
+ // something is selected.
+ if (selectedItem != null)
+ postActionEvent (((List) awtComponent).getSelectedItem (),
+ me.getModifiersEx ());
+ }
+ }
+
+ if (e.getID () == KeyEvent.KEY_PRESSED)
+ {
+ KeyEvent ke = (KeyEvent) e;
+ if (!ke.isConsumed () && ke.getKeyCode () == KeyEvent.VK_ENTER)
+ {
+ String selectedItem = ((List) awtComponent).getSelectedItem ();
+
+ // Enter only generates an Action event if something is
+ // selected.
+ if (selectedItem != null)
+ postActionEvent (selectedItem, ke.getModifiersEx ());
+ }
+ }
+
+ super.handleEvent (e);
+ }
+
+ protected void postItemEvent (int item, int stateChange)
+ {
+ postItemEvent (new Integer (item), stateChange);
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java
new file mode 100644
index 0000000..79eeaf9
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java
@@ -0,0 +1,80 @@
+/* GtkMenuBarPeer.java -- Implements MenuBarPeer with GTK+
+ Copyright (C) 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Font;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuComponent;
+import java.awt.peer.MenuBarPeer;
+import java.awt.peer.MenuPeer;
+
+public class GtkMenuBarPeer extends GtkMenuComponentPeer
+ implements MenuBarPeer
+{
+
+ native void create ();
+ native void addMenu (MenuPeer menu);
+
+ public GtkMenuBarPeer (MenuBar target)
+ {
+ super (target);
+ }
+
+ void setFont ()
+ {
+ MenuComponent mc = (MenuComponent) awtWidget;
+ Font f = mc.getFont ();
+
+ if (f == null)
+ mc.setFont (new Font ("Dialog", Font.PLAIN, 12));
+ }
+
+ // FIXME: remove this method or replace it with one that does
+ // something useful.
+ /* In Gnome, help menus are no longer right flushed. */
+ native void nativeSetHelpMenu(MenuPeer menuPeer);
+
+ public void addHelpMenu (Menu menu)
+ {
+ // nativeSetHelpMenu((MenuPeer) menu.getPeer());
+ }
+
+ public native void delMenu(int index);
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java
new file mode 100644
index 0000000..8d9d1ca
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java
@@ -0,0 +1,63 @@
+/* GtkMenuComponentPeer.java -- Implements MenuComponentPeer with GTK+
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.peer.MenuComponentPeer;
+
+public class GtkMenuComponentPeer extends GtkGenericPeer
+ implements MenuComponentPeer
+{
+ void create ()
+ {
+ throw new RuntimeException ();
+ }
+
+ void setFont ()
+ {
+ }
+
+ public GtkMenuComponentPeer (Object awtWidget)
+ {
+ super (awtWidget);
+ create ();
+ setFont ();
+ }
+
+ public native void dispose();
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java
new file mode 100644
index 0000000..5728f26
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java
@@ -0,0 +1,120 @@
+/* GtkMenuItemPeer.java -- Implements MenuItemPeer with GTK+
+ Copyright (C) 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Font;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuComponent;
+import java.awt.MenuItem;
+import java.awt.peer.MenuItemPeer;
+import java.awt.peer.MenuPeer;
+
+public class GtkMenuItemPeer extends GtkMenuComponentPeer
+ implements MenuItemPeer
+{
+ native void create (String label);
+ native void connectSignals ();
+ native void gtkWidgetModifyFont (String name, int style, int size);
+
+ void create ()
+ {
+ create (((MenuItem) awtWidget).getLabel());
+ }
+
+ public GtkMenuItemPeer (MenuItem item)
+ {
+ super (item);
+ setEnabled (item.isEnabled ());
+ setParent (item);
+
+ if (item.getParent() instanceof Menu && ! (item instanceof Menu))
+ connectSignals();
+ }
+
+ void setFont ()
+ {
+ MenuComponent mc = ((MenuComponent) awtWidget);
+ Font f = mc.getFont ();
+
+ if (f == null)
+ {
+ MenuComponent parent = (MenuComponent) mc.getParent ();
+ Font pf = parent.getFont ();
+ gtkWidgetModifyFont (pf.getName (), pf.getStyle (), pf.getSize ());
+ }
+ else
+ gtkWidgetModifyFont(f.getName(), f.getStyle(), f.getSize());
+ }
+
+ void setParent (MenuItem item)
+ {
+ // add ourself differently, based on what type of parent we have
+ // yes, the typecasting here is nasty.
+ Object parent = item.getParent ();
+ if (parent instanceof MenuBar)
+ {
+ ((GtkMenuBarPeer)((MenuBar)parent).getPeer ()).addMenu ((MenuPeer) this);
+ }
+ else // parent instanceof Menu
+ {
+ ((GtkMenuPeer)((Menu)parent).getPeer ()).addItem (this,
+ item.getShortcut ());
+ }
+ }
+
+ public void disable ()
+ {
+ setEnabled (false);
+ }
+
+ public void enable ()
+ {
+ setEnabled (true);
+ }
+
+ public native void setEnabled(boolean b);
+
+ public native void setLabel(String label);
+
+ protected void postMenuActionEvent ()
+ {
+ postActionEvent (((MenuItem)awtWidget).getActionCommand (), 0);
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java
new file mode 100644
index 0000000..80332dd
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuPeer.java
@@ -0,0 +1,103 @@
+/* GtkMenuPeer.java -- Implements MenuPeer with GTK+
+ Copyright (C) 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Component;
+import java.awt.Menu;
+import java.awt.MenuContainer;
+import java.awt.MenuItem;
+import java.awt.MenuShortcut;
+import java.awt.peer.MenuItemPeer;
+import java.awt.peer.MenuPeer;
+
+public class GtkMenuPeer extends GtkMenuItemPeer
+ implements MenuPeer
+{
+ native void create (String label);
+ native void addItem (MenuItemPeer item, int key, boolean shiftModifier);
+ native void setupAccelGroup (GtkGenericPeer container);
+ native void addTearOff ();
+
+ public GtkMenuPeer (Menu menu)
+ {
+ super (menu);
+
+ if (menu.isTearOff())
+ addTearOff();
+
+ MenuContainer parent = menu.getParent ();
+ if (parent instanceof Menu)
+ setupAccelGroup ((GtkGenericPeer)((Menu)parent).getPeer ());
+ else if (parent instanceof Component)
+ setupAccelGroup ((GtkGenericPeer)((Component)parent).getPeer ());
+ else
+ setupAccelGroup (null);
+ }
+
+ public void addItem (MenuItem item)
+ {
+ int key = 0;
+ boolean shiftModifier = false;
+
+ MenuShortcut ms = item.getShortcut ();
+ if (ms != null)
+ {
+ key = ms.getKey ();
+ shiftModifier = ms.usesShiftModifier ();
+ }
+
+ addItem ((MenuItemPeer) item.getPeer (), key, shiftModifier);
+ }
+
+ public void addItem (MenuItemPeer item, MenuShortcut ms)
+ {
+ int key = 0;
+ boolean shiftModifier = false;
+
+ if (ms != null)
+ {
+ key = ms.getKey ();
+ shiftModifier = ms.usesShiftModifier ();
+ }
+
+ addItem (item, key, shiftModifier);
+ }
+
+ public native void delItem(int index);
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java
new file mode 100644
index 0000000..fb5adde
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java
@@ -0,0 +1,70 @@
+/* GtkPanelPeer.java -- Implements PanelPeer with GTK
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.AWTEvent;
+import java.awt.Panel;
+import java.awt.event.MouseEvent;
+import java.awt.peer.PanelPeer;
+
+public class GtkPanelPeer extends GtkContainerPeer
+ implements PanelPeer
+{
+ native void create ();
+
+ public GtkPanelPeer (Panel p)
+ {
+ super (p);
+ }
+
+ public void handleEvent (AWTEvent event)
+ {
+ int id = event.getID();
+
+ switch (id)
+ {
+ case MouseEvent.MOUSE_PRESSED:
+ awtComponent.requestFocusInWindow ();
+ break;
+ }
+ super.handleEvent (event);
+ }
+
+ native void connectSignals ();
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java
new file mode 100644
index 0000000..d14c16d
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java
@@ -0,0 +1,74 @@
+/* GtkPopupMenuPeer.java -- Implements PopupMenuPeer with GTK+
+ Copyright (C) 1999 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Component;
+import java.awt.Event;
+import java.awt.MenuItem;
+import java.awt.Point;
+import java.awt.PopupMenu;
+import java.awt.peer.PopupMenuPeer;
+
+public class GtkPopupMenuPeer extends GtkMenuPeer
+ implements PopupMenuPeer
+{
+ public GtkPopupMenuPeer (PopupMenu menu)
+ {
+ super (menu);
+ }
+
+ native void setupAccelGroup (GtkGenericPeer container);
+
+ void setParent (MenuItem item)
+ {
+ // we don't need to "add" ourselves to our parent
+ }
+
+ native void show (int x, int y, long time);
+ public void show (Component origin, int x, int y)
+ {
+ Point abs = origin.getLocationOnScreen ();
+ show (abs.x + x, abs.y + y, 0);
+ }
+
+ public void show (Event e)
+ {
+
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java
new file mode 100644
index 0000000..69f8b49
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java
@@ -0,0 +1,113 @@
+/* GtkScrollPanePeer.java -- Implements ScrollPanePeer with GTK
+ Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Adjustable;
+import java.awt.Dimension;
+import java.awt.ScrollPane;
+import java.awt.peer.ScrollPanePeer;
+
+public class GtkScrollPanePeer extends GtkContainerPeer
+ implements ScrollPanePeer
+{
+ native void create (int width, int height);
+
+ void create ()
+ {
+ create (awtComponent.getWidth (), awtComponent.getHeight ());
+ }
+
+ // native void gtkScrolledWindowSetScrollPosition(int x, int y);
+ native void gtkScrolledWindowSetHScrollIncrement (int u);
+ native void gtkScrolledWindowSetVScrollIncrement (int u);
+
+ public GtkScrollPanePeer (ScrollPane sp)
+ {
+ super (sp);
+
+ setPolicy (sp.getScrollbarDisplayPolicy ());
+ }
+
+ native void setPolicy (int policy);
+ public void childResized (int width, int height)
+ {
+ int dim[] = new int[2];
+
+ gtkWidgetGetDimensions (dim);
+
+ // If the child is in this range, GTK adds both scrollbars, but
+ // the AWT doesn't. So set the peer's scroll policy to
+ // GTK_POLICY_NEVER.
+ if ((width > dim[0] - getVScrollbarWidth ()
+ && width <= dim[0])
+ && (height > dim[1] - getHScrollbarHeight ()
+ && height <= dim[1]))
+ setPolicy (ScrollPane.SCROLLBARS_NEVER);
+ else
+ setPolicy (((ScrollPane) awtComponent).getScrollbarDisplayPolicy ());
+ }
+
+ public native int getHScrollbarHeight();
+ public native int getVScrollbarWidth();
+ public native void setScrollPosition(int x, int y);
+
+ public Dimension getPreferredSize ()
+ {
+ return awtComponent.getSize();
+ }
+
+ public void setUnitIncrement (Adjustable adj, int u)
+ {
+ if (adj.getOrientation()==Adjustable.HORIZONTAL)
+ gtkScrolledWindowSetHScrollIncrement (u);
+ else
+ gtkScrolledWindowSetVScrollIncrement (u);
+ }
+
+ public void setValue (Adjustable adj, int v)
+ {
+// System.out.println("SPP: setVal: "+adj+":"+v);
+// Point p=myScrollPane.getScrollPosition ();
+// if (adj.getOrientation()==Adjustable.HORIZONTAL)
+// gtkScrolledWindowSetScrollPosition (v,p.y);
+// else
+// gtkScrolledWindowSetScrollPosition (p.x,v);
+// adj.setValue(v);
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java
new file mode 100644
index 0000000..aa3a26e
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java
@@ -0,0 +1,80 @@
+/* GtkScrollbarPeer.java -- Implements ScrollbarPeer with GTK+
+ Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Adjustable;
+import java.awt.Scrollbar;
+import java.awt.event.AdjustmentEvent;
+import java.awt.peer.ScrollbarPeer;
+
+public class GtkScrollbarPeer extends GtkComponentPeer
+ implements ScrollbarPeer
+{
+ void create ()
+ {
+ Scrollbar sb = (Scrollbar) awtComponent;
+
+ create (sb.getOrientation (), sb.getValue (),
+ sb.getMinimum (), sb.getMaximum (),
+ sb.getUnitIncrement (), sb.getBlockIncrement (),
+ sb.getVisibleAmount ());
+ }
+
+ native void create (int orientation, int value,
+ int min, int max, int stepIncr, int pageIncr,
+ int visibleAmount);
+
+ native void connectSignals ();
+
+ public GtkScrollbarPeer (Scrollbar s)
+ {
+ super (s);
+ }
+
+ public native void setLineIncrement(int amount);
+ public native void setPageIncrement(int amount);
+ public native void setValues(int value, int visible, int min, int max);
+
+ protected void postAdjustmentEvent (int type, int value)
+ {
+ q().postEvent (new AdjustmentEvent ((Adjustable)awtComponent,
+ AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED,
+ type, value));
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
new file mode 100644
index 0000000..a842b83
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextAreaPeer.java
@@ -0,0 +1,212 @@
+/* GtkTextAreaPeer.java -- Implements TextAreaPeer with GTK
+ Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Rectangle;
+import java.awt.TextArea;
+import java.awt.peer.TextAreaPeer;
+import java.awt.peer.TextComponentPeer;
+
+public class GtkTextAreaPeer extends GtkComponentPeer
+ implements TextComponentPeer, TextAreaPeer
+{
+ private static transient int DEFAULT_ROWS = 10;
+ private static transient int DEFAULT_COLS = 80;
+
+ native void create (int width, int height, int scrollbarVisibility);
+
+ native void gtkWidgetModifyFont (String name, int style, int size);
+ native void gtkWidgetRequestFocus ();
+
+ public native void connectSignals ();
+
+ public native int getCaretPosition ();
+ public native void setCaretPosition (int pos);
+ public native int getSelectionStart ();
+ public native int getSelectionEnd ();
+ public native String getText ();
+ public native void select (int start, int end);
+ public native void setEditable (boolean state);
+ public native void setText (String text);
+
+ public int getIndexAtPoint(int x, int y)
+ {
+ // FIXME
+ return 0;
+ }
+
+ public Rectangle getCharacterBounds (int pos)
+ {
+ // FIXME
+ return null;
+ }
+
+ public long filterEvents (long filter)
+ {
+ // FIXME
+ return filter;
+ }
+
+ void create ()
+ {
+ Font f = awtComponent.getFont ();
+
+ // By default, Sun sets a TextArea's font when its peer is
+ // created. If f != null then the peer's font is set by
+ // GtkComponent.create.
+ if (f == null)
+ {
+ f = new Font ("Dialog", Font.PLAIN, 12);
+ awtComponent.setFont (f);
+ }
+
+ FontMetrics fm = getFontMetrics (f);
+
+ TextArea ta = ((TextArea) awtComponent);
+ int sizeRows = ta.getRows ();
+ int sizeCols = ta.getColumns ();
+
+ sizeRows = sizeRows == 0 ? DEFAULT_ROWS : sizeRows;
+ sizeCols = sizeCols == 0 ? DEFAULT_COLS : sizeCols;
+
+ int width = sizeCols * fm.getMaxAdvance ();
+ int height = sizeRows * (fm.getMaxDescent () + fm.getMaxAscent ());
+
+ create (width, height, ta.getScrollbarVisibility ());
+ setEditable (ta.isEditable ());
+ }
+
+ public GtkTextAreaPeer (TextArea ta)
+ {
+ super (ta);
+
+ setText (ta.getText ());
+ setCaretPosition (0);
+ }
+
+ public native void insert (String str, int pos);
+ public native void replaceRange (String str, int start, int end);
+
+ public Dimension getMinimumSize (int rows, int cols)
+ {
+ return minimumSize (rows == 0 ? DEFAULT_ROWS : rows,
+ cols == 0 ? DEFAULT_COLS : cols);
+ }
+
+ public Dimension getPreferredSize (int rows, int cols)
+ {
+ return preferredSize (rows == 0 ? DEFAULT_ROWS : rows,
+ cols == 0 ? DEFAULT_COLS : cols);
+ }
+
+ native int getHScrollbarHeight ();
+ native int getVScrollbarWidth ();
+
+ // Deprecated
+ public Dimension minimumSize (int rows, int cols)
+ {
+ TextArea ta = ((TextArea) awtComponent);
+ int height = 0;
+ int width = 0;
+
+ if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH
+ || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_HORIZONTAL_ONLY)
+ height = getHScrollbarHeight ();
+
+ if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH
+ || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_VERTICAL_ONLY)
+ width = getVScrollbarWidth ();
+
+ Font f = awtComponent.getFont ();
+ if (f == null)
+ return new Dimension (width, height);
+
+ FontMetrics fm = getFontMetrics (f);
+
+ int sizeRows = rows == 0 ? DEFAULT_ROWS : rows;
+ int sizeCols = cols == 0 ? DEFAULT_COLS : cols;
+
+ width += sizeCols * fm.getMaxAdvance ();
+ height += sizeRows * (fm.getMaxDescent () + fm.getMaxAscent ());
+
+ return new Dimension (width, height);
+ }
+
+ public Dimension preferredSize (int rows, int cols)
+ {
+ TextArea ta = ((TextArea) awtComponent);
+ int height = 0;
+ int width = 0;
+
+ if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH
+ || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_HORIZONTAL_ONLY)
+ height = getHScrollbarHeight ();
+
+ if (ta.getScrollbarVisibility () == TextArea.SCROLLBARS_BOTH
+ || ta.getScrollbarVisibility () == TextArea.SCROLLBARS_VERTICAL_ONLY)
+ width = getVScrollbarWidth ();
+
+ Font f = awtComponent.getFont ();
+ if (f == null)
+ return new Dimension (width, height);
+
+ FontMetrics fm = getFontMetrics (f);
+
+ int sizeRows = rows == 0 ? DEFAULT_ROWS : rows;
+ int sizeCols = cols == 0 ? DEFAULT_COLS : cols;
+
+ width += sizeCols * fm.getMaxAdvance ();
+ height += sizeRows * (fm.getMaxDescent () + fm.getMaxAscent ());
+
+ return new Dimension (width, height);
+ }
+
+ public void replaceText (String str, int start, int end)
+ {
+ replaceRange (str, start, end);
+ }
+
+ public void insertText (String str, int pos)
+ {
+ insert (str, pos);
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java
new file mode 100644
index 0000000..73a976b
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java
@@ -0,0 +1,196 @@
+/* GtkTextFieldPeer.java -- Implements TextFieldPeer with GTK
+ Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.AWTEvent;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Rectangle;
+import java.awt.TextField;
+import java.awt.event.KeyEvent;
+import java.awt.peer.TextFieldPeer;
+import java.awt.peer.TextComponentPeer;
+
+public class GtkTextFieldPeer extends GtkComponentPeer
+ implements TextComponentPeer, TextFieldPeer
+{
+ native void create (int width);
+ native void gtkWidgetSetBackground (int red, int green, int blue);
+ native void gtkWidgetSetForeground (int red, int green, int blue);
+
+ public native void connectSignals ();
+
+ public native int getCaretPosition ();
+ public native void setCaretPosition (int pos);
+ public native int getSelectionStart ();
+ public native int getSelectionEnd ();
+ public native String getText ();
+ public native void select (int start, int end);
+ public native void setEditable (boolean state);
+ public native void setText (String text);
+
+ public int getIndexAtPoint(int x, int y)
+ {
+ // FIXME
+ return 0;
+ }
+
+ public Rectangle getCharacterBounds (int pos)
+ {
+ // FIXME
+ return null;
+ }
+
+ public long filterEvents (long filter)
+ {
+ // FIXME
+ return filter;
+ }
+
+ void create ()
+ {
+ Font f = awtComponent.getFont ();
+
+ // By default, Sun sets a TextField's font when its peer is
+ // created. If f != null then the peer's font is set by
+ // GtkComponent.create.
+ if (f == null)
+ {
+ f = new Font ("Dialog", Font.PLAIN, 12);
+ awtComponent.setFont (f);
+ }
+
+ FontMetrics fm = getFontMetrics (f);
+
+ TextField tf = ((TextField) awtComponent);
+ int cols = tf.getColumns ();
+
+ int text_width = cols * fm.getMaxAdvance ();
+
+ create (text_width);
+
+ setEditable (tf.isEditable ());
+ }
+
+ native int gtkEntryGetBorderWidth ();
+
+ native void gtkWidgetModifyFont (String name, int style, int size);
+
+ public GtkTextFieldPeer (TextField tf)
+ {
+ super (tf);
+
+ setText (tf.getText ());
+ setCaretPosition (0);
+
+ if (tf.echoCharIsSet ())
+ setEchoChar (tf.getEchoChar ());
+ }
+
+ public Dimension getMinimumSize (int cols)
+ {
+ return minimumSize (cols);
+ }
+
+ public Dimension getPreferredSize (int cols)
+ {
+ return preferredSize (cols);
+ }
+
+ public native void setEchoChar (char c);
+
+ // Deprecated
+ public Dimension minimumSize (int cols)
+ {
+ int dim[] = new int[2];
+
+ gtkWidgetGetPreferredDimensions (dim);
+
+ Font f = awtComponent.getFont ();
+ if (f == null)
+ return new Dimension (2 * gtkEntryGetBorderWidth (), dim[1]);
+
+ FontMetrics fm = getFontMetrics (f);
+
+ int text_width = cols * fm.getMaxAdvance ();
+
+ int width = text_width + 2 * gtkEntryGetBorderWidth ();
+
+ return new Dimension (width, dim[1]);
+ }
+
+ public Dimension preferredSize (int cols)
+ {
+ int dim[] = new int[2];
+
+ gtkWidgetGetPreferredDimensions (dim);
+
+ Font f = awtComponent.getFont ();
+ if (f == null)
+ return new Dimension (2 * gtkEntryGetBorderWidth (), dim[1]);
+
+ FontMetrics fm = getFontMetrics (f);
+
+ int text_width = cols * fm.getMaxAdvance ();
+
+ int width = text_width + 2 * gtkEntryGetBorderWidth ();
+
+ return new Dimension (width, dim[1]);
+ }
+
+ public void setEchoCharacter (char c)
+ {
+ setEchoChar (c);
+ }
+
+ public void handleEvent (AWTEvent e)
+ {
+ if (e.getID () == KeyEvent.KEY_PRESSED)
+ {
+ KeyEvent ke = (KeyEvent) e;
+
+ if (!ke.isConsumed ()
+ && ke.getKeyCode () == KeyEvent.VK_ENTER)
+ postActionEvent (getText (), ke.getModifiersEx ());
+ }
+
+ super.handleEvent (e);
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java
new file mode 100644
index 0000000..6990110
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java
@@ -0,0 +1,653 @@
+/* GtkToolkit.java -- Implements an AWT Toolkit using GTK for peers
+ Copyright (C) 1998, 1999, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import gnu.classpath.Configuration;
+import gnu.java.awt.EmbeddedWindow;
+import gnu.java.awt.peer.ClasspathFontPeer;
+import gnu.java.awt.peer.ClasspathTextLayoutPeer;
+import gnu.java.awt.peer.EmbeddedWindowPeer;
+
+import java.awt.*;
+import java.awt.datatransfer.Clipboard;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.peer.DragSourceContextPeer;
+import java.awt.font.FontRenderContext;
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DirectColorModel;
+import java.awt.image.ImageConsumer;
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+import java.awt.peer.*;
+import java.io.InputStream;
+import java.net.URL;
+import java.text.AttributedString;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.imageio.spi.IIORegistry;
+
+/* This class uses a deprecated method java.awt.peer.ComponentPeer.getPeer().
+ This merits comment. We are basically calling Sun's bluff on this one.
+ We think Sun has deprecated it simply to discourage its use as it is
+ bad programming style. However, we need to get at a component's peer in
+ this class. If getPeer() ever goes away, we can implement a hash table
+ that will keep up with every window's peer, but for now this is faster. */
+
+/**
+ * This class accesses a system property called
+ * <tt>gnu.java.awt.peer.gtk.Graphics</tt>. If the property is defined and
+ * equal to "Graphics2D", the cairo-based GdkGraphics2D will be used in
+ * drawing contexts. Any other value will cause the older GdkGraphics
+ * object to be used.
+ */
+public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
+{
+ Hashtable containers = new Hashtable();
+ static EventQueue q;
+ static Clipboard systemClipboard;
+ static boolean useGraphics2dSet;
+ static boolean useGraphics2d;
+
+ public static boolean useGraphics2D()
+ {
+ if (useGraphics2dSet)
+ return useGraphics2d;
+ useGraphics2d = System.getProperty("gnu.java.awt.peer.gtk.Graphics",
+ "Graphics").equals("Graphics2D");
+ useGraphics2dSet = true;
+ return useGraphics2d;
+ }
+
+ static native void gtkInit(int portableNativeSync);
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ System.loadLibrary("gtkpeer");
+
+ int portableNativeSync;
+ String portNatSyncProp =
+ System.getProperty("gnu.classpath.awt.gtk.portable.native.sync");
+
+ if (portNatSyncProp == null)
+ portableNativeSync = -1; // unset
+ else if (Boolean.valueOf(portNatSyncProp).booleanValue())
+ portableNativeSync = 1; // true
+ else
+ portableNativeSync = 0; // false
+
+ gtkInit(portableNativeSync);
+ }
+
+ public GtkToolkit ()
+ {
+ systemClipboard = new GtkClipboard ();
+ }
+
+ public native void beep();
+ private native void getScreenSizeDimensions(int[] xy);
+
+ public int checkImage (Image image, int width, int height,
+ ImageObserver observer)
+ {
+ int status = ImageObserver.ALLBITS
+ | ImageObserver.WIDTH
+ | ImageObserver.HEIGHT;
+
+ if (image instanceof GtkImage)
+ return ((GtkImage) image).checkImage (observer);
+
+ if (observer != null)
+ observer.imageUpdate (image, status,
+ -1, -1,
+ image.getWidth (observer),
+ image.getHeight (observer));
+
+ return status;
+ }
+
+ /**
+ * A helper class to return to clients in cases where a BufferedImage is
+ * desired but its construction fails.
+ */
+ private class GtkErrorImage extends Image
+ {
+ public GtkErrorImage()
+ {
+ }
+
+ public int getWidth(ImageObserver observer)
+ {
+ return -1;
+ }
+
+ public int getHeight(ImageObserver observer)
+ {
+ return -1;
+ }
+
+ public ImageProducer getSource()
+ {
+
+ return new ImageProducer()
+ {
+ HashSet consumers = new HashSet();
+ public void addConsumer(ImageConsumer ic)
+ {
+ consumers.add(ic);
+ }
+
+ public boolean isConsumer(ImageConsumer ic)
+ {
+ return consumers.contains(ic);
+ }
+
+ public void removeConsumer(ImageConsumer ic)
+ {
+ consumers.remove(ic);
+ }
+
+ public void startProduction(ImageConsumer ic)
+ {
+ consumers.add(ic);
+ Iterator i = consumers.iterator();
+ while(i.hasNext())
+ {
+ ImageConsumer c = (ImageConsumer) i.next();
+ c.imageComplete(ImageConsumer.IMAGEERROR);
+ }
+ }
+ public void requestTopDownLeftRightResend(ImageConsumer ic)
+ {
+ startProduction(ic);
+ }
+ };
+ }
+
+ public Graphics getGraphics()
+ {
+ return null;
+ }
+
+ public Object getProperty(String name, ImageObserver observer)
+ {
+ return null;
+ }
+ public Image getScaledInstance(int width, int height, int flags)
+ {
+ return new GtkErrorImage();
+ }
+
+ public void flush()
+ {
+ }
+ }
+
+
+ /**
+ * Helper to return either a BufferedImage -- the argument -- or a
+ * GtkErrorImage if the argument is null.
+ */
+
+ private Image bufferedImageOrError(BufferedImage b)
+ {
+ if (b == null)
+ return new GtkErrorImage();
+ else
+ return b;
+ }
+
+
+ public Image createImage (String filename)
+ {
+ if (useGraphics2D())
+ return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (filename));
+ else
+ return new GtkImage (filename);
+ }
+
+ public Image createImage (URL url)
+ {
+ if (useGraphics2D())
+ return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (url));
+ else
+ {
+ GdkPixbufDecoder d = new GdkPixbufDecoder (url);
+ GtkImage image = new GtkImage (d);
+ return image;
+ }
+ }
+
+ public Image createImage (ImageProducer producer)
+ {
+ if (useGraphics2D())
+ return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (producer));
+ else
+ return new GtkImage (producer);
+ }
+
+ public Image createImage (byte[] imagedata, int imageoffset,
+ int imagelength)
+ {
+ if (useGraphics2D())
+ return bufferedImageOrError(GdkPixbufDecoder.createBufferedImage (imagedata,
+ imageoffset,
+ imagelength));
+ else
+ {
+ GdkPixbufDecoder d = new GdkPixbufDecoder (imagedata,
+ imageoffset,
+ imagelength);
+ GtkImage image = new GtkImage (d);
+ return image;
+ }
+ }
+
+ /**
+ * Creates an ImageProducer from the specified URL. The image is assumed
+ * to be in a recognised format.
+ *
+ * @param url URL to read image data from.
+ */
+ public ImageProducer createImageProducer(URL url)
+ {
+ return new GdkPixbufDecoder(url);
+ }
+
+ /**
+ * Returns the native color model (which isn't the same as the default
+ * ARGB color model, but doesn't have to be).
+ */
+ public ColorModel getColorModel ()
+ {
+ /* Return the GDK-native ABGR format */
+ return new DirectColorModel(32,
+ 0x000000FF,
+ 0x0000FF00,
+ 0x00FF0000,
+ 0xFF000000);
+ }
+
+ public String[] getFontList ()
+ {
+ return (new String[] { "Dialog",
+ "DialogInput",
+ "Monospaced",
+ "Serif",
+ "SansSerif" });
+ }
+
+ private class LRUCache extends LinkedHashMap
+ {
+ int max_entries;
+ public LRUCache(int max)
+ {
+ super(max, 0.75f, true);
+ max_entries = max;
+ }
+ protected boolean removeEldestEntry(Map.Entry eldest)
+ {
+ return size() > max_entries;
+ }
+ }
+
+ private LRUCache fontCache = new LRUCache(50);
+ private LRUCache metricsCache = new LRUCache(50);
+ private LRUCache imageCache = new LRUCache(50);
+
+ public FontMetrics getFontMetrics (Font font)
+ {
+ synchronized (metricsCache)
+ {
+ if (metricsCache.containsKey(font))
+ return (FontMetrics) metricsCache.get(font);
+ }
+
+ FontMetrics m = new GdkFontMetrics (font);
+ synchronized (metricsCache)
+ {
+ metricsCache.put(font, m);
+ }
+ return m;
+ }
+
+ public Image getImage (String filename)
+ {
+ if (imageCache.containsKey(filename))
+ return (Image) imageCache.get(filename);
+ else
+ {
+ Image im = createImage(filename);
+ imageCache.put(filename, im);
+ return im;
+ }
+ }
+
+ public Image getImage (URL url)
+ {
+ if (imageCache.containsKey(url))
+ return (Image) imageCache.get(url);
+ else
+ {
+ Image im = createImage(url);
+ imageCache.put(url, im);
+ return im;
+ }
+ }
+
+ public PrintJob getPrintJob (Frame frame, String jobtitle, Properties props)
+ {
+ return null;
+ }
+
+ public native int getScreenResolution();
+
+ public Dimension getScreenSize ()
+ {
+ int dim[] = new int[2];
+ getScreenSizeDimensions(dim);
+ return new Dimension(dim[0], dim[1]);
+ }
+
+ public Clipboard getSystemClipboard()
+ {
+ return systemClipboard;
+ }
+
+ /**
+ * Prepares a GtkImage. For every other kind of Image it just
+ * assumes the image is already prepared for rendering.
+ */
+ public boolean prepareImage (Image image, int width, int height,
+ ImageObserver observer)
+ {
+ /* GtkImages are always prepared, as long as they're loaded. */
+ if (image instanceof GtkImage)
+ return ((((GtkImage)image).checkImage (observer) &
+ ImageObserver.ALLBITS) != 0);
+
+ /* Assume anything else is too */
+ return true;
+ }
+
+ public native void sync();
+
+ protected void setComponentState (Component c, GtkComponentPeer cp)
+ {
+ /* Make the Component reflect Peer defaults */
+ if (c.getForeground () == null)
+ c.setForeground (cp.getForeground ());
+ if (c.getBackground () == null)
+ c.setBackground (cp.getBackground ());
+ // if (c.getFont () == null)
+ // c.setFont (cp.getFont ());
+
+ /* Make the Peer reflect the state of the Component */
+ if (! (c instanceof Window))
+ {
+ cp.setCursor (c.getCursor ());
+
+ Rectangle bounds = c.getBounds ();
+ cp.setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
+ cp.setVisible (c.isVisible ());
+ }
+ }
+
+ protected ButtonPeer createButton (Button b)
+ {
+ return new GtkButtonPeer (b);
+ }
+
+ protected CanvasPeer createCanvas (Canvas c)
+ {
+ return new GtkCanvasPeer (c);
+ }
+
+ protected CheckboxPeer createCheckbox (Checkbox cb)
+ {
+ return new GtkCheckboxPeer (cb);
+ }
+
+ protected CheckboxMenuItemPeer createCheckboxMenuItem (CheckboxMenuItem cmi)
+ {
+ return new GtkCheckboxMenuItemPeer (cmi);
+ }
+
+ protected ChoicePeer createChoice (Choice c)
+ {
+ return new GtkChoicePeer (c);
+ }
+
+ protected DialogPeer createDialog (Dialog d)
+ {
+ return new GtkDialogPeer (d);
+ }
+
+ protected FileDialogPeer createFileDialog (FileDialog fd)
+ {
+ return new GtkFileDialogPeer (fd);
+ }
+
+ protected FramePeer createFrame (Frame f)
+ {
+ return new GtkFramePeer (f);
+ }
+
+ protected LabelPeer createLabel (Label label)
+ {
+ return new GtkLabelPeer (label);
+ }
+
+ protected ListPeer createList (List list)
+ {
+ return new GtkListPeer (list);
+ }
+
+ protected MenuPeer createMenu (Menu m)
+ {
+ return new GtkMenuPeer (m);
+ }
+
+ protected MenuBarPeer createMenuBar (MenuBar mb)
+ {
+ return new GtkMenuBarPeer (mb);
+ }
+
+ protected MenuItemPeer createMenuItem (MenuItem mi)
+ {
+ return new GtkMenuItemPeer (mi);
+ }
+
+ protected PanelPeer createPanel (Panel p)
+ {
+ return new GtkPanelPeer (p);
+ }
+
+ protected PopupMenuPeer createPopupMenu (PopupMenu target)
+ {
+ return new GtkPopupMenuPeer (target);
+ }
+
+ protected ScrollPanePeer createScrollPane (ScrollPane sp)
+ {
+ return new GtkScrollPanePeer (sp);
+ }
+
+ protected ScrollbarPeer createScrollbar (Scrollbar sb)
+ {
+ return new GtkScrollbarPeer (sb);
+ }
+
+ protected TextAreaPeer createTextArea (TextArea ta)
+ {
+ return new GtkTextAreaPeer (ta);
+ }
+
+ protected TextFieldPeer createTextField (TextField tf)
+ {
+ return new GtkTextFieldPeer (tf);
+ }
+
+ protected WindowPeer createWindow (Window w)
+ {
+ return new GtkWindowPeer (w);
+ }
+
+ public EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w)
+ {
+ return new GtkEmbeddedWindowPeer (w);
+ }
+
+ /**
+ * @deprecated part of the older "logical font" system in earlier AWT
+ * implementations. Our newer Font class uses getClasspathFontPeer.
+ */
+ protected FontPeer getFontPeer (String name, int style) {
+ // All fonts get a default size of 12 if size is not specified.
+ return getFontPeer(name, style, 12);
+ }
+
+ /**
+ * Private method that allows size to be set at initialization time.
+ */
+ private FontPeer getFontPeer (String name, int style, int size)
+ {
+ Map attrs = new HashMap ();
+ ClasspathFontPeer.copyStyleToAttrs (style, attrs);
+ ClasspathFontPeer.copySizeToAttrs (size, attrs);
+ return getClasspathFontPeer (name, attrs);
+ }
+
+ /**
+ * Newer method to produce a peer for a Font object, even though Sun's
+ * design claims Font should now be peerless, we do not agree with this
+ * model, hence "ClasspathFontPeer".
+ */
+
+ public ClasspathFontPeer getClasspathFontPeer (String name, Map attrs)
+ {
+ Map keyMap = new HashMap (attrs);
+ // We don't know what kind of "name" the user requested (logical, face,
+ // family), and we don't actually *need* to know here. The worst case
+ // involves failure to consolidate fonts with the same backend in our
+ // cache. This is harmless.
+ keyMap.put ("GtkToolkit.RequestedFontName", name);
+ if (fontCache.containsKey (keyMap))
+ return (ClasspathFontPeer) fontCache.get (keyMap);
+ else
+ {
+ ClasspathFontPeer newPeer = new GdkFontPeer (name, attrs);
+ fontCache.put (keyMap, newPeer);
+ return newPeer;
+ }
+ }
+
+ public ClasspathTextLayoutPeer getClasspathTextLayoutPeer (AttributedString str,
+ FontRenderContext frc)
+ {
+ return new GdkTextLayout(str, frc);
+ }
+
+ protected EventQueue getSystemEventQueueImpl()
+ {
+ synchronized (GtkToolkit.class)
+ {
+ if (q == null)
+ {
+ q = new EventQueue();
+ GtkGenericPeer.enableQueue (q);
+ }
+ }
+ return q;
+ }
+
+ protected native void loadSystemColors (int[] systemColors);
+
+ public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e)
+ {
+ throw new Error("not implemented");
+ }
+
+ public Map mapInputMethodHighlight(InputMethodHighlight highlight)
+ {
+ throw new Error("not implemented");
+ }
+
+ public Rectangle getBounds()
+ {
+ int[] dims = new int[2];
+ getScreenSizeDimensions(dims);
+ return new Rectangle(0, 0, dims[0], dims[1]);
+ }
+
+ // ClasspathToolkit methods
+
+ public GraphicsEnvironment getLocalGraphicsEnvironment()
+ {
+ return new GdkGraphicsEnvironment(this);
+ }
+
+ public Font createFont(int format, InputStream stream)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public RobotPeer createRobot (GraphicsDevice screen) throws AWTException
+ {
+ return new GdkRobotPeer (screen);
+ }
+
+ public void registerImageIOSpis(IIORegistry reg)
+ {
+ GdkPixbufDecoder.registerSpis(reg);
+ }
+
+ public native boolean nativeQueueEmpty();
+ public native void wakeNativeQueue();
+ public native void iterateNativeQueue(EventQueue locked, boolean block);
+
+} // class GtkToolkit
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java
new file mode 100644
index 0000000..496090a
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java
@@ -0,0 +1,118 @@
+/* GtkVolatileImage.java -- a hardware-accelerated image buffer
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.ImageCapabilities;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
+import java.awt.image.VolatileImage;
+
+public class GtkVolatileImage extends VolatileImage
+{
+ private int width;
+ private int height;
+ private ImageCapabilities caps;
+
+ public GtkVolatileImage(int width, int height)
+ {
+ this(width, height, null);
+ }
+
+ public GtkVolatileImage(int width, int height, ImageCapabilities caps)
+ {
+ this.width = width;
+ this.height = height;
+ this.caps = caps;
+ }
+
+ // FIXME: should return a buffered image snapshot of the accelerated
+ // visual
+ public BufferedImage getSnapshot()
+ {
+ return null;
+ }
+
+ public int getWidth()
+ {
+ return width;
+ }
+
+ public int getHeight()
+ {
+ return height;
+ }
+
+ // FIXME: should return a graphics wrapper around this image's
+ // visual
+ public Graphics2D createGraphics()
+ {
+ return null;
+ }
+
+ public int validate(GraphicsConfiguration gc)
+ {
+ return VolatileImage.IMAGE_OK;
+ }
+
+ public boolean contentsLost()
+ {
+ return false;
+ }
+
+ public ImageCapabilities getCapabilities()
+ {
+ return caps;
+ }
+
+ public synchronized Object getProperty (String name, ImageObserver observer)
+ {
+ return null;
+ }
+
+ public synchronized int getWidth (ImageObserver observer)
+ {
+ return width;
+ }
+
+ public synchronized int getHeight (ImageObserver observer)
+ {
+ return height;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java
new file mode 100644
index 0000000..71e05a8
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java
@@ -0,0 +1,212 @@
+/* GtkWindowPeer.java -- Implements WindowPeer with GTK
+ Copyright (C) 1998, 1999, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.awt.peer.gtk;
+
+import java.awt.Component;
+import java.awt.Frame;
+import java.awt.Window;
+import java.awt.event.WindowEvent;
+import java.awt.peer.WindowPeer;
+
+public class GtkWindowPeer extends GtkContainerPeer
+ implements WindowPeer
+{
+ protected static final int GDK_WINDOW_TYPE_HINT_NORMAL = 0;
+ protected static final int GDK_WINDOW_TYPE_HINT_DIALOG = 1;
+ protected static final int GDK_WINDOW_TYPE_HINT_MENU = 2;
+ protected static final int GDK_WINDOW_TYPE_HINT_TOOLBAR = 3;
+ protected static final int GDK_WINDOW_TYPE_HINT_SPLASHSCREEN = 4;
+ protected static final int GDK_WINDOW_TYPE_HINT_UTILITY = 5;
+ protected static final int GDK_WINDOW_TYPE_HINT_DOCK = 6;
+ protected static final int GDK_WINDOW_TYPE_HINT_DESKTOP = 7;
+
+ private boolean hasBeenShown = false;
+ private int oldState = Frame.NORMAL;
+
+ native void gtkWindowSetTitle (String title);
+ native void gtkWindowSetResizable (boolean resizable);
+ native void gtkWindowSetModal (boolean modal);
+
+ native void realize ();
+
+ int getWidth ()
+ {
+ return awtComponent.getWidth();
+ }
+
+ int getHeight ()
+ {
+ return awtComponent.getHeight();
+ }
+
+ native void create (int type, boolean decorated, GtkWindowPeer parent);
+
+ void create (int type, boolean decorated)
+ {
+ GtkWindowPeer parent_peer = null;
+ Component parent = awtComponent.getParent();
+
+ if (parent != null)
+ parent_peer = (GtkWindowPeer) awtComponent.getParent().getPeer();
+
+ create (type, decorated, parent_peer);
+ }
+
+ void create ()
+ {
+ // Create a normal undecorated window.
+ create (GDK_WINDOW_TYPE_HINT_NORMAL, false);
+ }
+
+ void setParent ()
+ {
+ setVisible (awtComponent.isVisible ());
+ setEnabled (awtComponent.isEnabled ());
+ }
+
+ void setVisibleAndEnabled ()
+ {
+ }
+
+ native void connectSignals ();
+
+ public GtkWindowPeer (Window window)
+ {
+ super (window);
+ }
+
+ public native void toBack();
+ public native void toFront();
+
+ native void nativeSetBounds (int x, int y, int width, int height);
+
+ public void setBounds (int x, int y, int width, int height)
+ {
+ nativeSetBounds (x, y,
+ width - insets.left - insets.right,
+ height - insets.top - insets.bottom);
+ }
+
+ public void setTitle (String title)
+ {
+ gtkWindowSetTitle (title);
+ }
+
+ native void setSize (int width, int height);
+
+ public void setResizable (boolean resizable)
+ {
+ // Call setSize; otherwise when resizable is changed from true to
+ // false the window will shrink to the dimensions it had before it
+ // was resizable.
+ setSize (awtComponent.getWidth() - insets.left - insets.right,
+ awtComponent.getHeight() - insets.top - insets.bottom);
+ gtkWindowSetResizable (resizable);
+ }
+
+ native void setBoundsCallback (Window window,
+ int x, int y,
+ int width, int height);
+
+ protected void postInsetsChangedEvent (int top, int left,
+ int bottom, int right)
+ {
+ insets.top = top;
+ insets.left = left;
+ insets.bottom = bottom;
+ insets.right = right;
+ }
+
+ protected void postConfigureEvent (int x, int y, int width, int height)
+ {
+ int frame_x = x - insets.left;
+ int frame_y = y - insets.top;
+ int frame_width = width + insets.left + insets.right;
+ int frame_height = height + insets.top + insets.bottom;
+
+ if (frame_x != awtComponent.getX()
+ || frame_y != awtComponent.getY()
+ || frame_width != awtComponent.getWidth()
+ || frame_height != awtComponent.getHeight())
+ {
+ setBoundsCallback ((Window) awtComponent,
+ frame_x, frame_y, frame_width, frame_height);
+
+ awtComponent.validate();
+ }
+ }
+
+ native void nativeSetVisible (boolean b);
+ public void setVisible (boolean b)
+ {
+ // Prevent the window manager from automatically placing this
+ // window when it is shown.
+ if (b)
+ setBounds (awtComponent.getX(),
+ awtComponent.getY(),
+ awtComponent.getWidth(),
+ awtComponent.getHeight());
+ nativeSetVisible (b);
+ }
+
+ void postWindowEvent (int id, Window opposite, int newState)
+ {
+ if (id == WindowEvent.WINDOW_OPENED)
+ {
+ // Post a WINDOW_OPENED event the first time this window is shown.
+ if (!hasBeenShown)
+ {
+ q().postEvent (new WindowEvent ((Window) awtComponent, id,
+ opposite));
+ hasBeenShown = true;
+ }
+ }
+ else if (id == WindowEvent.WINDOW_STATE_CHANGED)
+ {
+ if (oldState != newState)
+ {
+ q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite,
+ oldState, newState));
+ oldState = newState;
+ }
+ }
+ else
+ q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite));
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/package.html b/libjava/classpath/gnu/java/awt/peer/gtk/package.html
new file mode 100644
index 0000000..8dd4dd8
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/gtk/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in gnu.java.awt.peer.gtk package.
+ Copyright (C) 2005 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. -->
+
+<html>
+<head><title>GNU Classpath - gnu.java.awt.peer.gtk</title></head>
+
+<body>
+<p>This package implements the GTK peer for java.awt.</p>
+
+</body>
+</html>
diff --git a/libjava/classpath/gnu/java/awt/peer/package.html b/libjava/classpath/gnu/java/awt/peer/package.html
new file mode 100644
index 0000000..846759a
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/peer/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in gnu.java.awt.peer package.
+ Copyright (C) 2005 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. -->
+
+<html>
+<head><title>GNU Classpath - gnu.java.awt.peer</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>