Initial revision

From-SVN: r102074
This commit is contained in:
Tom Tromey 2005-07-16 00:30:23 +00:00
parent 6f4434b39b
commit f911ba985a
4557 changed files with 1000262 additions and 0 deletions

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}
}

View file

@ -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;
}
}
}

View file

@ -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);
}

View file

@ -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");
}
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -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
{
}

View file

@ -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
}
}

View file

@ -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);
}
}

View file

@ -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));
}
}

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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>

View file

@ -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>

View file

@ -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);
}

View file

@ -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 ();
}

View file

@ -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);
}

View file

@ -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() { }
}

View file

@ -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:

View file

@ -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:

View file

@ -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];
}
}

View file

@ -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);
}
}

View file

@ -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 ();
}
}

View file

@ -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);
}
}

File diff suppressed because it is too large Load diff

View file

@ -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);
}
}

View file

@ -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 ();
}
}

View file

@ -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 ();
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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");
}
}

View file

@ -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);
}
}

View file

@ -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 ();
}
}

View file

@ -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 ();
}
}

View file

@ -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();
}
}

View file

@ -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 ();
}
}

View file

@ -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);
}
}

View file

@ -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();
}

View file

@ -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();
}
}

View file

@ -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);
}
}
}

View file

@ -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 ());
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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)
{
}
}

View file

@ -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 ());
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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 ();
}

View file

@ -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)
{
}
}

View file

@ -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);
}
}

View file

@ -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));
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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));
}
}

View file

@ -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>

View file

@ -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>

View file

@ -0,0 +1,171 @@
/* gnu.java.beans.BeanInfoEmbryo
Copyright (C) 1998, 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.beans;
import java.beans.BeanDescriptor;
import java.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.IndexedPropertyDescriptor;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.Vector;
/**
** A BeanInfoEmbryo accumulates information about a Bean
** while it is in the process of being created, and then
** when you are done accumulating the information, the
** getBeanInfo() method may be called to create a BeanInfo
** object based on the information.<P>
**
** This class is not well-synchronized. (It can be, it
** just isn't yet.)
**
** @author John Keiser
** @version 1.1.0, 30 Jul 1998
** @see java.beans.BeanInfo
**/
public class BeanInfoEmbryo {
// by using a TreeMap the properties will be sorted alphabetically by name
// which matches the (undocumented) behavior of jdk
TreeMap properties = new TreeMap();
Hashtable events = new Hashtable();
Vector methods = new Vector();
BeanDescriptor beanDescriptor;
BeanInfo[] additionalBeanInfo;
java.awt.Image[] im;
String defaultPropertyName;
String defaultEventName;
public BeanInfoEmbryo() {
}
public BeanInfo getBeanInfo() {
int defaultProperty = -1;
int defaultEvent = -1;
PropertyDescriptor[] Aproperties = new PropertyDescriptor[properties.size()];
int i = 0;
Iterator it = properties.entrySet().iterator();
while (it.hasNext()) {
Aproperties[i] = (PropertyDescriptor) (((Map.Entry)it.next()).getValue());
if(defaultPropertyName != null && Aproperties[i].getName().equals(defaultPropertyName)) {
defaultProperty = i;
}
i++;
}
EventSetDescriptor[] Aevents = new EventSetDescriptor[events.size()];
i = 0;
Enumeration e = events.elements();
while (e.hasMoreElements()) {
Aevents[i] = (EventSetDescriptor) e.nextElement();
if(defaultEventName != null && Aevents[i].getName().equals(defaultEventName)) {
defaultEvent = i;
}
i++;
}
MethodDescriptor[] Amethods = new MethodDescriptor[methods.size()];
methods.copyInto(Amethods);
return new ExplicitBeanInfo(beanDescriptor,additionalBeanInfo,Aproperties,defaultProperty,Aevents,defaultEvent,Amethods,im);
}
public void setBeanDescriptor(BeanDescriptor b) {
beanDescriptor = b;
}
public void setAdditionalBeanInfo(BeanInfo[] b) {
additionalBeanInfo = b;
}
public boolean hasProperty(PropertyDescriptor p) {
return properties.get(p.getName()) != null;
}
public void addProperty(PropertyDescriptor p) {
properties.put(p.getName(),p);
}
public void addIndexedProperty(IndexedPropertyDescriptor p) {
properties.put(p.getName(),p);
}
public boolean hasEvent(EventSetDescriptor e) {
return events.get(e.getName()) != null;
}
public void addEvent(EventSetDescriptor e) {
events.put(e.getName(),e);
}
public boolean hasMethod(MethodDescriptor m) {
for(int i=0;i<methods.size();i++) {
Method thisMethod = ((MethodDescriptor)methods.elementAt(i)).getMethod();
if(m.getMethod().getName().equals(thisMethod.getName())
&& Arrays.equals(m.getMethod().getParameterTypes(),
thisMethod.getParameterTypes())) {
return true;
}
}
return false;
}
public void addMethod(MethodDescriptor m) {
methods.addElement(m);
}
public void setDefaultPropertyName(String defaultPropertyName) {
this.defaultPropertyName = defaultPropertyName;
}
public void setDefaultEventName(String defaultEventName) {
this.defaultEventName = defaultEventName;
}
public void setIcons(java.awt.Image[] im) {
this.im = im;
}
}

View file

@ -0,0 +1,200 @@
/* gnu.java.beans.DummyAppletContext
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.beans;
import java.applet.Applet;
import java.applet.AppletContext;
import java.applet.AudioClip;
import java.awt.Image;
import java.awt.Toolkit;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
/** A placeholder <code>AppletContext</code> implementation that does nothing.
*
* <p>This is the default implementation for GNU Classpath and is used for <code>Applet</code>
* beans being created with {@link java.beans.Beans.instantiate}.</p>
*
* <p>It has no functionality in order to allow it to be used without any dependencies
* (e.g. sound, network access, ...).</p>
*
* @author Robert Schuster
*/
class DummyAppletContext implements AppletContext
{
private static final Enumeration EMPTY_ENUMERATION = Collections.enumeration(Collections.EMPTY_SET);
private static final AudioClip DUMMY_CLIP = new DummyAudioClip();
DummyAppletContext()
{
}
/** Implementation is VM neutral and returns a dummy {@link AudioClip} instance
* for every URL that returns a non-<code>null</code> object on
* <code>URL.openConnection()</code>.
*
* @see java.applet.AppletContext#getAudioClip(java.net.URL)
*
* FIXME: When Java Sound API (javax.sound) is included in Classpath or URL is able to handle
* sampled sound this should be adjusted.
*/
public AudioClip getAudioClip(URL url)
{
try
{
return (url.openConnection() != null ? DUMMY_CLIP : null);
}
catch (IOException ioe)
{
return null;
}
}
/** Loads the <code>Image</code> instance by delegating to
* {@link java.awt.Toolkit.createImage(URL) }.
*
* @see java.applet.AppletContext#getImage(java.net.URL)
* @see java.awt.Toolkit#createImage(java.net.URL)
*/
public Image getImage(URL url)
{
return Toolkit.getDefaultToolkit().createImage(url);
}
/** Returns <code>null</code> for every argument.
*
* @see java.applet.AppletContext#getApplet(java.lang.String)
*/
public Applet getApplet(String name)
{
return null;
}
/** Returns always an empty <code>Enumeration</code>.
*
* @see java.applet.AppletContext#getApplets()
*/
public Enumeration getApplets()
{
return EMPTY_ENUMERATION;
}
/** Does nothing.
*
* @see java.applet.AppletContext#showDocument(java.net.URL)
*/
public void showDocument(URL url)
{
}
/** Does nothing.
*
* @see java.applet.AppletContext#showDocument(java.net.URL, java.lang.String)
*/
public void showDocument(URL url, String target)
{
}
/** Does nothing.
*
* @see java.applet.AppletContext#showStatus(java.lang.String)
*/
public void showStatus(String message)
{
}
/** Does nothing.
*
* @see java.applet.AppletContext#setStream(java.lang.String, java.io.InputStream)
*/
public void setStream(String key, InputStream stream)
throws IOException
{
throw new IOException("Dummy implementation imposes zero InputStream associations.");
}
/** Returns <code>null</code> for every argument.
*
* @see java.applet.AppletContext#getStream(java.lang.String)
*/
public InputStream getStream(String key)
{
return null;
}
/** Returns always an empty iterator.
*
* @see java.applet.AppletContext#getStreamKeys()
*/
public Iterator getStreamKeys()
{
return Collections.EMPTY_SET.iterator();
}
/** Dummy <code>AudioClip</code> implementation that does nothing but
* preventing <code>NullPointerException</code>S being thrown in programs
* that expect a valid <code>AudioClip</code> instance to be returned by
* their Applet.
*
* @author Robert Schuster
*/
static class DummyAudioClip implements AudioClip
{
public void play()
{
}
public void stop()
{
}
public void loop()
{
}
public String toString()
{
return "DummyAudioClip never plays anything - implement javax.sound and make us happy :)";
}
}
}

View file

@ -0,0 +1,115 @@
/* gnu.java.beans.DummyAppletStub
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.beans;
import java.applet.AppletContext;
import java.applet.AppletStub;
import java.net.URL;
/** Placeholder implementation of <code>AppletStub</code> providing no functionality.
* <p>This class is used for <code>Applet</code> being created with
* {@link java.beans.Bean.instantiate}.</p>
*
* @author Robert Schuster
*/
public class DummyAppletStub implements AppletStub
{
private URL documentBase;
private URL codeBase;
private DummyAppletContext context;
public DummyAppletStub(URL newCodeBase, URL newDocumentBase)
{
codeBase = newCodeBase;
documentBase = newDocumentBase;
context = new DummyAppletContext();
}
/** Returns always <code>true</code>.
*
* @see java.applet.AppletStub#isActive()
*/
public boolean isActive()
{
return true;
}
/**
* @see java.applet.AppletStub#getDocumentBase()
*/
public URL getDocumentBase()
{
return documentBase;
}
/**
* @see java.applet.AppletStub#getCodeBase()
*/
public URL getCodeBase()
{
return codeBase;
}
/** Implementation returns <code>null</code> for every parameter name.
*
* @see java.applet.AppletStub#getParameter(java.lang.String)
*/
public String getParameter(String name)
{
return null;
}
/** Returns a non-functional context instance.
*
* @see java.applet.AppletStub#getAppletContext()
*/
public AppletContext getAppletContext()
{
return context;
}
/** Does nothing.
*
* @see java.applet.AppletStub#appletResize(int, int)
*/
public void appletResize(int width, int height)
{
}
}

View file

@ -0,0 +1,149 @@
/* ExplicitBeanInfo.java --
Copyright (C) 1998, 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.beans;
import java.awt.Image;
import java.beans.BeanDescriptor;
import java.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
/**
** ExplicitBeanInfo lets you specify in the constructor
** all the various parts of the BeanInfo.
**
** @author John Keiser
** @version 1.1.0, 30 Jul 1998
** @see java.beans.BeanInfo
**/
public class ExplicitBeanInfo implements BeanInfo {
/** The BeanDescriptor returned by getBeanDescriptor. **/
protected BeanDescriptor beanDescriptor;
/** The EventSetDescriptor array returned by
** getEventSetDescriptors().
**/
protected EventSetDescriptor[] eventSetDescriptors = new EventSetDescriptor[0];
/** The PropertyDescriptor array returned by
** getPropertyDescriptors().
**/
protected PropertyDescriptor[] propertyDescriptors = new PropertyDescriptor[0];
/** The MethodDescriptor array returned by
** getMethodDescriptors().
**/
protected MethodDescriptor[] methodDescriptors;
/** The default property index. **/
protected int defaultPropertyIndex;
/** The default event index. **/
protected int defaultEventIndex;
/** The BeanInfo array returned by
** getAdditionalBeanInfo().
**/
protected BeanInfo[] additionalBeanInfo;
/** The set of icons. **/
protected Image[] icons;
public ExplicitBeanInfo(BeanDescriptor beanDescriptor,
BeanInfo[] additionalBeanInfo,
PropertyDescriptor[] propertyDescriptors,
int defaultPropertyIndex,
EventSetDescriptor[] eventSetDescriptors,
int defaultEventIndex,
MethodDescriptor[] methodDescriptors,
Image[] icons) {
this.beanDescriptor = beanDescriptor;
this.additionalBeanInfo = additionalBeanInfo;
this.propertyDescriptors = propertyDescriptors;
this.defaultPropertyIndex = defaultPropertyIndex;
this.eventSetDescriptors = eventSetDescriptors;
this.defaultEventIndex = defaultEventIndex;
this.methodDescriptors = methodDescriptors;
this.icons = icons;
}
/** Get Bean descriptor. **/
public BeanDescriptor getBeanDescriptor() {
return beanDescriptor;
}
/** Get Bean events. **/
public EventSetDescriptor[] getEventSetDescriptors() {
return eventSetDescriptors;
}
/** Get default event set. **/
public int getDefaultEventIndex() {
return defaultEventIndex;
}
/** Get Bean properties. **/
public PropertyDescriptor[] getPropertyDescriptors() {
return propertyDescriptors;
}
/** Get "default" property. **/
public int getDefaultPropertyIndex() {
return defaultPropertyIndex;
}
/** Get Bean methods. **/
public MethodDescriptor[] getMethodDescriptors() {
return methodDescriptors;
}
/** Get additional Bean info. **/
public BeanInfo[] getAdditionalBeanInfo() {
return additionalBeanInfo;
}
/** Get Bean icons.
** @param iconType the type of icon
**/
public Image getIcon(int iconType) {
return icons != null ? icons[iconType - 1] : null;
}
}

View file

@ -0,0 +1,441 @@
/* gnu.java.beans.IntrospectionIncubator
Copyright (C) 1998, 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.beans;
import gnu.java.lang.ArrayHelper;
import gnu.java.lang.ClassHelper;
import java.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.IndexedPropertyDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
/**
** IntrospectionIncubator takes in a bunch of Methods, and
** Introspects only those Methods you give it.<br/>
**
** See {@link addMethod(Method)} for details which rules apply to
** the methods.
**
** @author John Keiser
** @author Robert Schuster
** @see gnu.java.beans.ExplicitBeanInfo
** @see java.beans.BeanInfo
**/
public class IntrospectionIncubator {
Hashtable propertyMethods = new Hashtable();
Hashtable listenerMethods = new Hashtable();
Vector otherMethods = new Vector();
Class propertyStopClass;
Class eventStopClass;
Class methodStopClass;
public IntrospectionIncubator() {
}
/** Examines the given method and files it in a suitable collection.
* It files the method as a property method if it finds:
* <ul>
* <li>boolean "is" getter</li>
* <li>"get" style getter</li>
* <li>single argument setter</li>
* <li>indiced setter and getter</li>
* </ul>
* It files the method as a listener method if all of these rules apply:
* <ul>
* <li>the method name starts with "add" or "remove"</li>
* <li>there is only a single argument</li>
* <li>the argument type is a subclass of <code>java.util.EventListener</code></li>
* </ul>
* All public methods are filed as such.
*
* @param method The method instance to examine.
*/
public void addMethod(Method method) {
if(Modifier.isPublic(method.getModifiers())) {
String name = ClassHelper.getTruncatedName(method.getName());
Class retType = method.getReturnType();
Class[] params = method.getParameterTypes();
boolean isVoid = retType.equals(java.lang.Void.TYPE);
Class methodClass = method.getDeclaringClass();
/* Accepts the method for examination if no stop class is given or the method is declared in a subclass of the stop class.
* The rules for this are described in {@link java.beans.Introspector.getBeanInfo(Class, Class)}.
* This block finds out whether the method is a suitable getter or setter method (or read/write method).
*/
if(isReachable(propertyStopClass, methodClass)) {
/* At this point a method may regarded as a property's read or write method if its name
* starts with "is", "get" or "set". However, if a method is static it cannot be part
* of a property.
*/
if(Modifier.isStatic(method.getModifiers())) {
// files method as other because it is static
otherMethods.addElement(method);
} else if(name.startsWith("is")
&& retType.equals(java.lang.Boolean.TYPE)
&& params.length == 0) {
// files method as boolean "is" style getter
addToPropertyHash(name,method,IS);
} else if(name.startsWith("get") && !isVoid) {
if(params.length == 0) {
// files as legal non-argument getter
addToPropertyHash(name,method,GET);
} else if(params.length == 1 && params[0].equals(java.lang.Integer.TYPE)) {
// files as legal indiced getter
addToPropertyHash(name,method,GET_I);
} else {
// files as other because the method's signature is not Bean-like
otherMethods.addElement(method);
}
} else if(name.startsWith("set") && isVoid) {
if(params.length == 1) {
// files as legal single-argument setter method
addToPropertyHash(name,method,SET);
} else if(params.length == 2 && params[0].equals(java.lang.Integer.TYPE)) {
// files as legal indiced setter method
addToPropertyHash(name,method,SET_I);
} else {
// files as other because the method's signature is not Bean-like
otherMethods.addElement(method);
}
}
}
if(isReachable(eventStopClass, methodClass)) {
if(name.startsWith("add")
&& isVoid
&& params.length == 1
&& java.util.EventListener.class.isAssignableFrom(params[0])) {
addToListenerHash(name,method,ADD);
} else if(name.startsWith("remove")
&& isVoid
&& params.length == 1
&& java.util.EventListener.class.isAssignableFrom(params[0])) {
addToListenerHash(name,method,REMOVE);
}
}
if(isReachable(methodStopClass, methodClass)) {
// files as reachable public method
otherMethods.addElement(method);
}
}
}
public void addMethods(Method[] m) {
for(int i=0;i<m.length;i++) {
addMethod(m[i]);
}
}
public void setPropertyStopClass(Class c) {
propertyStopClass = c;
}
public void setEventStopClass(Class c) {
eventStopClass = c;
}
public void setMethodStopClass(Class c) {
methodStopClass = c;
}
public BeanInfoEmbryo getBeanInfoEmbryo() throws IntrospectionException {
BeanInfoEmbryo b = new BeanInfoEmbryo();
findXXX(b,IS);
findXXXInt(b,GET_I);
findXXXInt(b,SET_I);
findXXX(b,GET);
findXXX(b,SET);
findAddRemovePairs(b);
for(int i=0;i<otherMethods.size();i++) {
MethodDescriptor newMethod = new MethodDescriptor((Method)otherMethods.elementAt(i));
if(!b.hasMethod(newMethod)) {
b.addMethod(new MethodDescriptor((Method)otherMethods.elementAt(i)));
}
}
return b;
}
public BeanInfo getBeanInfo() throws IntrospectionException {
return getBeanInfoEmbryo().getBeanInfo();
}
void findAddRemovePairs(BeanInfoEmbryo b) throws IntrospectionException {
Enumeration listenerEnum = listenerMethods.keys();
while(listenerEnum.hasMoreElements()) {
DoubleKey k = (DoubleKey)listenerEnum.nextElement();
Method[] m = (Method[])listenerMethods.get(k);
if(m[ADD] != null && m[REMOVE] != null) {
EventSetDescriptor e = new EventSetDescriptor(Introspector.decapitalize(k.getName()),
k.getType(), k.getType().getMethods(),
m[ADD],m[REMOVE]);
e.setUnicast(ArrayHelper.contains(m[ADD].getExceptionTypes(),java.util.TooManyListenersException.class));
if(!b.hasEvent(e)) {
b.addEvent(e);
}
}
}
}
void findXXX(BeanInfoEmbryo b, int funcType) throws IntrospectionException {
Enumeration keys = propertyMethods.keys();
while(keys.hasMoreElements()) {
DoubleKey k = (DoubleKey)keys.nextElement();
Method[] m = (Method[])propertyMethods.get(k);
if(m[funcType] != null) {
PropertyDescriptor p = new PropertyDescriptor(Introspector.decapitalize(k.getName()),
m[IS] != null ? m[IS] : m[GET],
m[SET]);
if(m[SET] != null) {
p.setConstrained(ArrayHelper.contains(m[SET].getExceptionTypes(),java.beans.PropertyVetoException.class));
}
if(!b.hasProperty(p)) {
b.addProperty(p);
}
}
}
}
void findXXXInt(BeanInfoEmbryo b, int funcType) throws IntrospectionException {
Enumeration keys = propertyMethods.keys();
while(keys.hasMoreElements()) {
DoubleKey k = (DoubleKey)keys.nextElement();
Method[] m = (Method[])propertyMethods.get(k);
if(m[funcType] != null) {
boolean constrained;
if(m[SET_I] != null) {
constrained = ArrayHelper.contains(m[SET_I].getExceptionTypes(),java.beans.PropertyVetoException.class);
} else {
constrained = false;
}
/** Find out if there is an array type get or set **/
Class arrayType = Array.newInstance(k.getType(),0).getClass();
DoubleKey findSetArray = new DoubleKey(arrayType,k.getName());
Method[] m2 = (Method[])propertyMethods.get(findSetArray);
IndexedPropertyDescriptor p;
if(m2 == null) {
p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()),
null,null,
m[GET_I],m[SET_I]);
} else {
if(constrained && m2[SET] != null) {
constrained = ArrayHelper.contains(m2[SET].getExceptionTypes(),java.beans.PropertyVetoException.class);
}
p = new IndexedPropertyDescriptor(Introspector.decapitalize(k.getName()),
m2[GET],m2[SET],
m[GET_I],m[SET_I]);
}
p.setConstrained(constrained);
if(!b.hasProperty(p)) {
b.addProperty(p);
}
}
}
}
static final int IS=0;
static final int GET_I=1;
static final int SET_I=2;
static final int GET=3;
static final int SET=4;
static final int ADD=0;
static final int REMOVE=1;
void addToPropertyHash(String name, Method method, int funcType) {
String newName;
Class type;
switch(funcType) {
case IS:
type = java.lang.Boolean.TYPE;
newName = name.substring(2);
break;
case GET_I:
type = method.getReturnType();
newName = name.substring(3);
break;
case SET_I:
type = method.getParameterTypes()[1];
newName = name.substring(3);
break;
case GET:
type = method.getReturnType();
newName = name.substring(3);
break;
case SET:
type = method.getParameterTypes()[0];
newName = name.substring(3);
break;
default:
return;
}
newName = capitalize(newName);
if (newName.length() == 0)
return;
DoubleKey k = new DoubleKey(type,newName);
Method[] methods = (Method[])propertyMethods.get(k);
if(methods == null) {
methods = new Method[5];
propertyMethods.put(k,methods);
}
methods[funcType] = method;
}
void addToListenerHash(String name, Method method, int funcType) {
String newName;
Class type;
switch(funcType) {
case ADD:
type = method.getParameterTypes()[0];
newName = name.substring(3,name.length()-8);
break;
case REMOVE:
type = method.getParameterTypes()[0];
newName = name.substring(6,name.length()-8);
break;
default:
return;
}
newName = capitalize(newName);
if (newName.length() == 0)
return;
DoubleKey k = new DoubleKey(type,newName);
Method[] methods = (Method[])listenerMethods.get(k);
if(methods == null) {
methods = new Method[2];
listenerMethods.put(k,methods);
}
methods[funcType] = method;
}
/* Determines whether <code>stopClass</code> is <code>null</code>
* or <code>declaringClass<code> is a true subclass of <code>stopClass</code>.
* This expression is useful to detect whether a method should be introspected or not.
* The rules for this are described in {@link java.beans.Introspector.getBeanInfo(Class, Class)}.
*/
static boolean isReachable(Class stopClass, Class declaringClass) {
return stopClass == null || (stopClass.isAssignableFrom(declaringClass) && !stopClass.equals(declaringClass));
}
/** Transforms a property name into a part of a method name.
* E.g. "value" becomes "Value" which can then concatenated with
* "set", "get" or "is" to form a valid method name.
*
* Implementation notes:
* If "" is the argument, it is returned without changes.
* If <code>null</code> is the argument, <code>null</code> is returned.
*
* @param name Name of a property.
* @return Part of a method name of a property.
*/
static String capitalize(String name) {
try {
if(Character.isUpperCase(name.charAt(0))) {
return name;
} else {
char[] c = name.toCharArray();
c[0] = Character.toLowerCase(c[0]);
return new String(c);
}
} catch(StringIndexOutOfBoundsException E) {
return name;
} catch(NullPointerException E) {
return null;
}
}
}
/** This class is a hashmap key that consists of a <code>Class</code> and a
* <code>String</code> element.
*
* It is used for XXX: find out what this is used for
*
* @author John Keiser
* @author Robert Schuster
*/
class DoubleKey {
Class type;
String name;
DoubleKey(Class type, String name) {
this.type = type;
this.name = name;
}
Class getType() {
return type;
}
String getName() {
return name;
}
public boolean equals(Object o) {
if(o instanceof DoubleKey) {
DoubleKey d = (DoubleKey)o;
return d.type.equals(type) && d.name.equals(name);
} else {
return false;
}
}
public int hashCode() {
return type.hashCode() ^ name.hashCode();
}
}

View file

@ -0,0 +1 @@
- overhaul efficiency

View file

@ -0,0 +1,70 @@
/* gnu.java.beans.decoder.AbstractContext
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.beans.decoder;
/** AbstractContext implements some basic functionality of the Context
* interface and is therefore the base of all Context implementations.
*
* @author Robert Schuster
*/
abstract class AbstractContext implements Context
{
private boolean isStatement;
private String id;
public String getId()
{
return id;
}
public void setId(String newId)
{
id = newId;
}
public boolean isStatement()
{
return isStatement;
}
public void setStatement(boolean b)
{
isStatement = b;
}
}

View file

@ -0,0 +1,113 @@
/* gnu.java.beans.decoder.AbstractCreatableContext
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.beans.decoder;
/** AbstractCreatableObjectContext is the base class for all Context implementations
* which create a result object in their lifetime. It provides means for preventing
* to create the object twice.
*
* @author Robert Schuster
*
*/
abstract class AbstractCreatableObjectContext extends AbstractObjectContext
{
AbstractCreatableObjectContext()
{
}
/** Adds a parameter object to this Context if the result object has not been
* created yet. Otherwise an AssemblyException is thrown that indicates a wrong
* behavior of the decoder.
*/
public final void addParameterObject(Object o) throws AssemblyException
{
if (object == null)
addParameterObjectImpl(o);
else
throw new AssemblyException(new IllegalStateException("No more parameter objects are allowed when the object as already been created."));
}
/** Adds a parameter object to this Context. Implement this without caring
* for illegal states because this has been done already.
*
* @param obj The parameter object to be added.
*/
protected abstract void addParameterObjectImpl(Object obj);
/** Creates the result object if it does not exist already.
*/
public final void notifyStatement(Context outerContext)
throws AssemblyException
{
if (object != null)
return;
object = createObject(outerContext);
}
/** Creates the result object. This method is called only once. Implement this
* without checking for double invocations as this is already being prevented.
*
* @param outerContext The Context that exists around this one.
* @return The result object.
* @throws AssemblerException if the object creation fails somehow.
*/
protected abstract Object createObject(Context outerContext)
throws AssemblyException;
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context)
*/
public final Object endContext(Context outerContext)
throws AssemblyException
{
notifyStatement(outerContext);
return object;
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#subContextFailed()
*/
public boolean subContextFailed()
{
/* Returns true when the AbstractCreatableObjectContext has not created the result object yet
* (A failed subcontext automatically lets this context fail too.)
*/
return object == null;
}
}

View file

@ -0,0 +1,316 @@
/* gnu.java.beans.decoder.AbstractElementHandler
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.beans.decoder;
import java.beans.ExceptionListener;
import org.xml.sax.Attributes;
/** ElementHandler manages a Context instance and interacts with
* its parent and child handlers.
*
* @author Robert Schuster
*/
abstract class AbstractElementHandler implements ElementHandler
{
/** The Context instance of this handler. The instance is available after the startElement()
* method was called. Otherwise the handler is marked as failed.
*/
private Context context;
/** The parent handler. */
private ElementHandler parent;
/** Stores whether this handler is marked as failed. */
private boolean hasFailed;
/** Stores the character data which is contained in the body of the XML tag. */
private StringBuffer buffer = new StringBuffer();
/** Stores whether this ElementHandler can have subelements. The information for this is taken from
* javabeans.dtd which can be found here:
* <a href="http://java.sun.com/products/jfc/tsc/articles/persistence3/">Java Persistence Article</a>
*/
private boolean allowsSubelements;
/** Creates a new ElementHandler with the given ElementHandler instance
* as parent.
*
* @param parentHandler The parent handler.
*/
protected AbstractElementHandler(ElementHandler parentHandler,
boolean allowsSubs)
{
parent = parentHandler;
allowsSubelements = allowsSubs;
}
/** Evaluates the attributes and creates a Context instance.
* If the creation of the Context instance fails the ElementHandler
* is marked as failed which may affect the parent handler other.
*
* @param attributes Attributes of the XML tag.
*/
public final void start(Attributes attributes,
ExceptionListener exceptionListener)
{
try
{
// lets the subclass create the appropriate Context instance
context = startElement(attributes, exceptionListener);
}
catch (AssemblyException pe)
{
Throwable t = pe.getCause();
if (t instanceof Exception)
exceptionListener.exceptionThrown((Exception) t);
else
throw new InternalError("Unexpected Throwable type in AssemblerException. Please file a bug report.");
notifyContextFailed();
return;
}
}
/** Analyses the content of the Attributes instance and creates a Context
* object accordingly.
* An AssemblerException is thrown when the Context instance could not
* be created.
*
* @param attributes Attributes of the XML tag.
* @return A Context instance.
* @throws AssemblerException when Context instance could not be created.
*/
protected abstract Context startElement(Attributes attributes, ExceptionListener exceptionListener)
throws AssemblyException;
/** Post-processes the Context.
*/
public final void end(ExceptionListener exceptionListener)
{
// skips processing if the handler is marked as failed (because the Context
// is then invalid or may not exist at all)
if (!hasFailed)
{
try
{
// note: the order of operations is very important here
// sends the stored character data to the Context
endElement(buffer.toString());
// reports to the parent handler if this handler's Context is a
// statement (returning no value BACK to the parent's Context)
if (context.isStatement())
{
// This may create a valid result in the parent's Context
// or let it fail
parent.notifyStatement(exceptionListener);
// skips any further processing if the parent handler is now marked
// as failed
if (parent.hasFailed())
return;
}
// processes the Context and stores the result
putObject(context.getId(), context.endContext(parent.getContext()));
// transfers the Context's results to the parent's Context
// if it is an expression (rather than a statement)
if (! context.isStatement())
parent.getContext().addParameterObject(context.getResult());
}
catch (AssemblyException pe)
{
// notifies that an exception was thrown in this handler's Context
Throwable t = pe.getCause();
if (t instanceof Exception)
exceptionListener.exceptionThrown((Exception) t);
else
throw (InternalError) new InternalError("Severe problem while decoding XML data.")
.initCause(t);
// marks the handler as failed
notifyContextFailed();
}
}
}
/** Notifies the handler's Context that its child Context will not return
* a value back. Some Context variants need this information to know when
* a method or a constructor call can be made.
*
* This method is called by a child handler.
*/
public void notifyStatement(ExceptionListener exceptionListener)
{
try
{
// propagates to parent handler first to generate objects
// needed by this Context instance
if(context.isStatement())
{
parent.notifyStatement(exceptionListener);
}
// Some Context instances do stuff which can fail now. If that
// happens this handler is marked as failed.
context.notifyStatement(parent.getContext());
}
catch (AssemblyException ae)
{
// notifies that an exception was thrown in this handler's Context
Throwable t = ae.getCause();
if (t instanceof Exception)
exceptionListener.exceptionThrown((Exception) t);
else
throw (InternalError) new InternalError("Severe problem while decoding XML data.")
.initCause(t);
// marks the handler as failed
notifyContextFailed();
}
}
/** Marks this and any depending parent handlers as failed. Which means that on their end
* no result is calculated.
*
* When a handler has failed no more handlers are accepted within it.
*/
public final void notifyContextFailed()
{
hasFailed = true;
// marks the parent handler as failed if its Context
// is affected by the failure of this handler's Context
if (parent.getContext().subContextFailed())
parent.notifyContextFailed();
}
/** Returns whether this handler has failed.
*
* This is used to skip child elements.
*
* @return Whether this handler has failed.
*/
public final boolean hasFailed()
{
return hasFailed;
}
/** Processes the character data when the element ends.
*
* The default implementation does nothing for convenience.
*
* @param characters
* @throws AssemblerException
*/
protected void endElement(String characters) throws AssemblyException
{
// XXX: throw an exception when unexpected character data is available?
}
/** Adds characters from the body of the XML tag to the buffer.
*
* @param ch
* @param start
* @param length
* @throws SAXException
*/
public final void characters(char[] ch, int start, int length)
{
// simply appends character data
buffer.append(ch, start, length);
}
/** Stores an object globally under a unique id. If the id is
* null the object is not stored.
*
* @param objectId
* @param o
*/
public void putObject(String objectId, Object o)
{
if (objectId != null)
parent.putObject(objectId, o);
}
/** Returns a previously stored object. If the id is null the
* result is null, too.
*
* @param objectId
* @return Returns a previously stored object or null.
*/
public Object getObject(String objectId) throws AssemblyException
{
return objectId == null ? null : parent.getObject(objectId);
}
/** Returns the Class instance as if called Class.forName() but
* uses a ClassLoader given by the user.
*
* @param className
* @return
* @throws ClassNotFoundException
*/
public Class instantiateClass(String className)
throws ClassNotFoundException
{
return parent.instantiateClass(className);
}
public final boolean isSubelementAllowed(String subElementName)
{
return allowsSubelements && ! subElementName.equals("java");
}
public final Context getContext()
{
return context;
}
public final ElementHandler getParent()
{
return parent;
}
}

View file

@ -0,0 +1,127 @@
/* gnu.java.beans.decoder.AbstractObjectContext
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.beans.decoder;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/** AbstractObjectContext is the base for all Context implementations which
* create or provide a result object during their lifetime.
*
* <p>This class provides the implementation for an indexed get and set method.
* But this does not mean that the result object supports these operation.</p>
*
* @author Robert Schuster
*
*/
abstract class AbstractObjectContext extends AbstractContext
{
protected Object object;
AbstractObjectContext()
{}
/** Sets the result object of the Context.
*
* @param obj The result object to be set.
*/
protected final void setObject(Object obj)
{
object = obj;
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#set(int, java.lang.Object)
*/
public final void set(int index, Object o) throws AssemblyException
{
try
{
Method method =
object.getClass().getMethod(
"set",
new Class[] { Integer.TYPE, Object.class });
method.invoke(object, new Object[] { new Integer(index), o });
}
catch (NoSuchMethodException nsme)
{
throw new AssemblyException(nsme);
}
catch (InvocationTargetException ite)
{
throw new AssemblyException(ite.getCause());
}
catch (IllegalAccessException iae)
{
throw new AssemblyException(iae);
}
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#get(int)
*/
public final Object get(int index) throws AssemblyException
{
try
{
Method method =
object.getClass().getMethod(
"get",
new Class[] { Integer.TYPE });
return method.invoke(object, new Object[] { new Integer(index)});
}
catch (NoSuchMethodException nsme)
{
throw new AssemblyException(nsme);
}
catch (InvocationTargetException ite)
{
throw new AssemblyException(ite.getCause());
}
catch (IllegalAccessException iae)
{
throw new AssemblyException(iae);
}
}
public final Object getResult()
{
return object;
}
}

View file

@ -0,0 +1,122 @@
/* gnu.java.beans.decoder.ArrayContext
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.beans.decoder;
import java.lang.reflect.Array;
/** A Context implementation for a fixed size array. The array
* elements have to be set using IndexContext instances.
*
* @author Robert Schuster
*/
class ArrayContext extends AbstractContext
{
private Object array;
ArrayContext(String id, Class klass, int length)
{
setId(id);
array = Array.newInstance(klass, length);
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#addObject(java.lang.Object)
*/
public void addParameterObject(Object o) throws AssemblyException
{
throw new AssemblyException(new IllegalStateException("Adding objects without an index to a fixed array is not possible."));
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#reportStatement()
*/
public void notifyStatement(Context outerContext)
{
// method call intentionally ignored because there is not any useful effect
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context)
*/
public Object endContext(Context outerContext) throws AssemblyException
{
return array;
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#subContextFailed()
*/
public boolean subContextFailed()
{
// returns false to indicate that assembling the array does not fail only because
// a subelement failed.
return false;
}
public void set(int index, Object o) throws AssemblyException
{
try
{
Array.set(array, index, o);
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
throw new AssemblyException(aioobe);
}
}
public Object get(int index) throws AssemblyException
{
try
{
return Array.get(array, index);
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
throw new AssemblyException(aioobe);
}
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#getResult()
*/
public Object getResult()
{
return array;
}
}

View file

@ -0,0 +1,118 @@
/* gnu.java.beans.decoder.ArrayHandler
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.beans.decoder;
import java.beans.ExceptionListener;
import java.util.HashMap;
import org.xml.sax.Attributes;
/** ArrayHandler processes the &lt;array&gt; tag. Depending on the existance of the 'length' attribute a Context for
* a fixed-size or growable array is created.
*
* @author Robert Schuster
*/
class ArrayHandler extends AbstractElementHandler
{
/** Contains a mapping between a textual description of a primitive type (like "byte") and
* its corresponding wrapper class. This allows it to easily construct Array objects for
* primitive data types.
*/
private static HashMap typeMap = new HashMap();
static
{
typeMap.put("byte", Byte.TYPE);
typeMap.put("short", Short.TYPE);
typeMap.put("int", Integer.TYPE);
typeMap.put("long", Long.TYPE);
typeMap.put("float", Float.TYPE);
typeMap.put("double", Double.TYPE);
typeMap.put("boolean", Boolean.TYPE);
typeMap.put("char", Character.TYPE);
}
/**
* @param PersistenceParser
*/
ArrayHandler(ElementHandler parent)
{
super(parent, true);
}
protected Context startElement(Attributes attributes, ExceptionListener exceptionListener)
throws AssemblyException, AssemblyException
{
String id = attributes.getValue("id");
String className = attributes.getValue("class");
if (className != null)
{
try
{
Class klass;
if (typeMap.containsKey(className))
klass = (Class) typeMap.get(className);
else
klass = instantiateClass(className);
String length = attributes.getValue("length");
if (length != null)
// creates Array with predefined length
return new ArrayContext(id, klass, Integer.parseInt(length));
else
// creates Array without length restriction
return new GrowableArrayContext(id, klass);
}
catch (ClassNotFoundException cnfe)
{
throw new AssemblyException(cnfe);
}
catch (NumberFormatException nfe)
{
throw new AssemblyException(nfe);
}
}
throw new AssemblyException(new IllegalArgumentException("Missing 'class' attribute in <array> tag."));
}
}

View file

@ -0,0 +1,57 @@
/* gnu.java.beans.decoder.AssemblyException
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.beans.decoder;
/** The AssemblyException is used to wrap the cause of problems when assembling objects.
* In all cases only the wrapped exception is given to the PersistenceParser's
* ExceptionListener instance (never the AssemblyException itself).
*
* <p>Note: Often multiple steps are needed to construct a fully usuable object instance.
* Such a construction can be called assembly and thats why this exception was
* named AssemblyException.</p>
*
* @author Robert Schuster
*/
class AssemblyException extends Exception
{
AssemblyException(Throwable cause)
{
super(cause);
}
}

View file

@ -0,0 +1,67 @@
/* gnu.java.beans.decoder.BooleanHandler
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.beans.decoder;
/** Creates a Boolean instance from the character data in a &lt;boolean&gt; tag.
*
* @author Robert Schuster
*/
class BooleanHandler extends SimpleHandler
{
/**
* @param PersistenceParser
*/
BooleanHandler(ElementHandler parent)
{
super(parent);
// TODO Auto-generated constructor stub
}
protected Object parse(String number) throws AssemblyException
{
if (number.equals("true"))
return new Boolean(true);
if (number.equals("false"))
return new Boolean(false);
throw new AssemblyException(new IllegalArgumentException("Element contained no valid boolean value."));
}
}

View file

@ -0,0 +1,59 @@
/* gnu.java.beans.decoder.ByteHandler
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.beans.decoder;
/** Creates a Byte instance from the character data in a &lt;byte&gt; tag.
*
* @author Robert Schuster
*/
class ByteHandler extends SimpleHandler
{
/**
* @param PersistenceParser
*/
ByteHandler(ElementHandler parent)
{
super(parent);
}
protected Object parse(String number) throws NumberFormatException
{
return Byte.valueOf(number);
}
}

View file

@ -0,0 +1,62 @@
/* gnu.java.beans.decoder.CharHandler
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.beans.decoder;
/** Creates a Character instance from the character data in a &lt;char&gt; tag.
*
* @author Robert Schuster
*/
class CharHandler extends SimpleHandler
{
/**
* @param PersistenceParser
*/
CharHandler(ElementHandler parent)
{
super(parent);
}
protected Object parse(String number) throws AssemblyException
{
if (number.length() > 1)
throw new AssemblyException(new IllegalArgumentException("Element contained no valid character."));
return new Character(number.charAt(0));
}
}

View file

@ -0,0 +1,66 @@
/* gnu.java.beans.decoder.ClassHandler
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.beans.decoder;
/** Creates a Class instance from the character data in a &lt;class&gt; tag.
*
* @author Robert Schuster
*/
class ClassHandler extends SimpleHandler
{
/**
* @param PersistenceParser
*/
ClassHandler(ElementHandler parent)
{
super(parent);
}
protected Object parse(String characters) throws AssemblyException
{
try
{
return instantiateClass(characters);
}
catch (ClassNotFoundException cnfe)
{
throw new AssemblyException(cnfe);
}
}
}

View file

@ -0,0 +1,102 @@
/* gnu.java.beans.decoder.ConstructorContext
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.beans.decoder;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
/** A ConstructorContext is a {@link Context} implementation which collects the parameters for a constructor
* call and instantiates the result object using that constructor. After that sub-contexts can invoke
* methods on the result object.
*
* <p>The constructor is invoked when a sub-context is a statement or the Context ends.</p>
*
* @author Robert Schuster
*/
class ConstructorContext extends AbstractCreatableObjectContext
{
private ArrayList arguments = new ArrayList();
private Class klass;
ConstructorContext(String id, Class newClass)
{
setId(id);
// sets superclass field
klass = newClass;
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#addObject(java.lang.Object)
*/
protected void addParameterObjectImpl(Object o)
{
arguments.add(o);
}
protected Object createObject(Context outerContext)
throws AssemblyException
{
Object[] args = arguments.toArray();
try
{
Constructor constructor = MethodFinder.getConstructor(klass, args);
// instantiates object (klass field gets re-set by superclass)
return constructor.newInstance(args);
}
catch (NoSuchMethodException nsme)
{
throw new AssemblyException(nsme);
}
catch (InvocationTargetException ite)
{
throw new AssemblyException(ite.getCause());
}
catch (IllegalAccessException iae)
{
throw new AssemblyException(iae);
}
catch (InstantiationException ie)
{
throw new AssemblyException(ie);
}
}
}

View file

@ -0,0 +1,137 @@
/* gnu.java.beans.decoder.Context
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.beans.decoder;
/** A Context is the environment for an object which is being assembler. If there
* are no errors each handler creates one Context.
* <p>Depending on the result of isStatement() a Context can be statement or an
* expression. An expression returns a value to the Context of its parent handler,
* a statement does not. Whenever a Context is a statement the parent handler's
* Context is informed about that through the {@link notifyStatement}-method.</p>
*
* @author Robert Schuster
*/
interface Context
{
/** Adds a parameter object to the context. This method is used when
* sub-Contexts return their result.
*
* Some Contexts do not accept more than a certain amount of objects
* and throw an AssemblerException if the amount is exceeded.
*
* @param o The object added to this context.
*/
void addParameterObject(Object o) throws AssemblyException;
/** Notifies that the next element is a statement. This can mean
* that an argument list is complete to be called.
*
*/
void notifyStatement(Context outerContext) throws AssemblyException;
/** Notifies that the context ends and the returns the appropriate result
* object.
*
* @param outerContext
* @return
*/
Object endContext(Context outerContext) throws AssemblyException;
/** Notifies that the assembly of a subcontext failed and returns
* whether this Context is affected in a way that it fails too.
*
* @return Whether the failure of a subcontext lets this context fail, too.
*/
boolean subContextFailed();
/** Calls an appropriate indexed set method if it is available or
* throws an AssemblerException if that is not allowed on this Context.
*
* The behaviour of this method is equal to List.set(int, Object).
*
* @param index Index position to be set.
* @param o Object to be set at the given index position.
* @throws AssemblerException Indexed set is not allowed or otherwise failed.
*/
void set(int index, Object o) throws AssemblyException;
/** Calls an appropriate indexed get method if it is available or
* throws an AssemblerException if that is not allowed on this Context.
*
* The behaviour of this method is equal to List.get(int).
*
* @param index Index position of the object return.
* @throws AssemblerException Indexed get is not allowed or otherwise failed.
*/
Object get(int index) throws AssemblyException;
/** Returns the result which was calculated by calling endContext() or reportStatement().
* Its the handler's responsibility to care that any of these two methods was called.
*
* This is used by sub-Contexts to access this Context's result.
*
* @return
*/
Object getResult();
/** Gives this Context a unique id. For convenience the id may be null which means
* that no id exists at all.
*
* @param id
*/
void setId(String id);
/** Returns this Context's unique id or null if does not have such an id.
*
* @return This Context's id or null.
*/
String getId();
/** Returns whether this Context is a statement (not returning result back
* to parent handler's Context) or not (= expression).
*
* @return
*/
boolean isStatement();
/** Sets whether this Context is a statement or not.
*
* @param b
*/
void setStatement(boolean b);
}

View file

@ -0,0 +1,124 @@
/* gnu.java.beans.decoder.DecoderContext
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.beans.decoder;
import java.beans.XMLDecoder;
import java.util.ArrayList;
import java.util.Iterator;
/** DecoderContext is a Context implementation which allows access to
* the XMLDecoder instance itself. This is used for the &lt;java&gt; tag.
*
* @author Robert Schuster
*/
public class DecoderContext extends AbstractContext
{
private XMLDecoder decoder;
public DecoderContext(XMLDecoder xmlDecoder)
{
decoder = xmlDecoder;
}
private ArrayList objects = new ArrayList();
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#addObject(java.lang.Object)
*/
public void addParameterObject(Object o) throws AssemblyException
{
objects.add(o);
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#reportStatement()
*/
public void notifyStatement(Context outerContext) throws AssemblyException
{
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#endContext(gnu.java.beans.decoder.Context)
*/
public Object endContext(Context outerContext) throws AssemblyException
{
return decoder;
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#subContextFailed()
*/
public boolean subContextFailed()
{
return false;
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#set(int, java.lang.Object)
*/
public void set(int index, Object o) throws AssemblyException
{
throw new AssemblyException(new IllegalArgumentException("Set method is not allowed in decoder context."));
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#get(int)
*/
public Object get(int index) throws AssemblyException
{
throw new AssemblyException(new IllegalArgumentException("Get method is not allowed in decoder context."));
}
/* (non-Javadoc)
* @see gnu.java.beans.decoder.Context#getResult()
*/
public Object getResult()
{
return decoder;
}
/** Returns an Iterator that retrieves the assembled objects.
*
* @return An Iterator retrieving assembled objects.
*/
public Iterator iterator()
{
return objects.iterator();
}
}

Some files were not shown because too many files have changed in this diff Show more