Merging in more AWT stuff

Rolf W. Rasmussen rolfwr@ii.uib.no
Fri Aug 11 10:44:00 GMT 2000


This patch merges in most of the AWT code I've been working on.  With
this patch, and the Xlib-based toolkit implementation I've also been
working on I've been able to get my AWT test programs up and running,
The patch implements missing parts of some AWT classes, and also fixes 
some bugs that became apparent when the windows and components
actually started appearing on the screen.

Ok to check in?


2000-08-11  Rolf W. Rasmussen  <rolfwr@ii.uib.no>

	* gnu/gcj/awt/ComponentDataBlitOp.java: New file.
	* gnu/gcj/awt/GLightweightPeer.java: New file.
	* java/awt/BorderLayout.java: Implemented all methods.
	* java/awt/Button.java (actionListener, actionCommand): Renamed
	and modifier change.
	(addNotify): Call super.
	(dispatchEventImpl): New method.
	(getListeners): New method.
	(label): Made package-private, not private.
	* java/awt/Canvas.java: Implemented class body.
	* java/awt/Color.java (brighter): New method.
	(darker): New method.
	(hashCode): New method.
	* java/awt/Component.java (visible, enabled, eventMask): Set defaults.
	(getGraphicsConfiguration): Delegate to
	getGraphicsConfigurationImpl().
	(getGraphicsConfigurationImpl): New method.
	(getToolkit): Only return value from peer if not null.
	(isDisplayable): Check with parent.
	(isShowing): No parent implies not showing.
	(getForeground): Check parent property if local is null.
	(getBackground): Likewise.
	(getFont): Likewise.
	(setForeground): Inform peer.
	(setBackground): Likewise
	(setFont): Likewise.
	(setLocale): Invalidate component.
	(getColorModel): Implemented.
	(setLocation): Invalidate, or ignore if no change.
	(setSize): Invalidate, or ignore if no change.
	(setBounds): Invalidate, or ignore if no change.
	(isOpaque): By default, heavyweight implies opaque.
	(isLightweight): Implemented.
	(getMaximumSize): Implemented.
	(doLayout): Implemented, NOP.
	(validate): Implemented, NOP.
	(invalidate): Only propagate to parent if parent was valid.
	(getGraphics): Implemented.
	(getFontMetrics): Implemented.
	(update): Implemented.
	(paintAll): Implemented.
	(repaint): Implemented all repaint methods.
	(print): Implemented.
	(printAll): Implemented.
	(createImage): Implemented.
	(dispatchEvent): Give the peer a chance to handle the event.
	(dispatchEventImpl): Dispatch paint events.
	(enableEvents): Lightweights enable events on parent component.
	(coalesceEvents): Coalesce paint events, and select event type
	using a switch.
	(coalescePaintEvents): New method.
	(processEvent): Fix unfortunate ordering of statements, and call
	correct method for MOUSE_CLICKED.
	(processPaintEvent): New method.
	(addNotify): Allow container to notify children before event
	mask is set in peer.
	(addNotifyContainerChildren): New method.
	(removeNotify): Visibility should not change on removeNotify.
	(paramString): Implemented.
	(list): Implemented two of the list methods.
	* Container (myInsets): Removed, insets are managed by peer.
	(getInsets): Query peer.
	(addImpl): Fix reparenting, enable events for lightweights,
	initialize component array.
	(validate): Call doLayout in validateTree() instead.
	(validateTree): Do nothing if already valid. Call beginValidate(),
	endValidate() on peer. Call validateTree() instead of validate()
	for children that are containers. Mark valid after validation of
	children.
	(setFont): Partial implementation.
	(paint): Implemented.
	(visitChildren): New method.
	(visitChild): New method.
	(update): Implemented.
	(print): Implemented.
	(paintComponents): Implemented.
	(printComponents): Consider translation and clipping.
	(getComponentAt): Ignore invisible children. Return this if no
	child match.
	(addNotify): Call super.
	(addNotifyContainerChildren): New method.
	(paramString): Implemented.
	(list): Implemented.
	* java/awt/EventQueue (invokeAndWait): Get system event queue the
	right way.
	(invokeLater): Likewise.
	(isDispatchThread): Likewise.
	* java/awt/FontMetrics (getLeading): Formula change.
	(getDescent): Consider leading also.
	(getMaxAscent): Default to getAscent().
	(getMaxDescent): Default to getDescent.
	(getMaxAdvance): Return value signifying unknown.
	(charWidth): Both methods implemented.
	(charsWidth): Implemented.
	(bytesWidth): Implemented.
	(getWidths): Implemented.
	* java/awt/Frame.java (NORMAL, ICONIFIED, iconImage, isResizable,
	state): New fields.
	(Frame): Rearragend constuctor chaining to disallow null being
	passed as a graphics configuration.
	(getTitle): Return empty string if null.
	(dispose): Removed.
	(getIconImage): New method.
	(setIconImage): New method.
	(finalize): New method.
	(setMenuBar): Notify peer.
	(isResizable): New method.
	(setResizable): New method.
	(getState): New method.
	(getFont): Removed.
	(remove): Implemented.
	(removeNotify): New method.
	(getFrames): New method.
	* java/awt/Graphics.java: Implemented body of class.
	* java/awt/Graphics2D.java: New file.
	* java/awt/GraphicsConfiguration.java: Enabled part of the API.
	* java/awt/Image.java: Implemented body of class.
	* java/awt/Panel.java (Panel): Call correct super constructor.
	(addNotify): Implemented.
	* java/awt/Rectangle.java (isEmpty): Fixed reversed logic.
	* java/awt/RenderingHints.java: New file.
	* java/awt/Toolkit.java (createComponent): Implemented.
	(getSystemEventQueue): Delegate to getSystemEventQueueImpl().
	* java/awt/Window.java (Window): Two new constructors. Reordered
	constructor chaining.
	(getGraphicsConfigurationImpl): New method.
	(finalize): Call super.
	(addNotify): Call super.
	(pack): Do layout stuff.
	(show): Ensure that peer exists and that component is valid.
	(dispose): Dispose owned children.
	(getOwner): Simplify code, casting null pointers is valid.
	(getGraphicsConfiguration): Ask peer if local value is null.
	* java/awt/event/ActionEvent.java (getActionCommand): Renamed from
	getcmd().
	* java/awt/image/BufferedImage.java: New file.
	* java/awt/image/RasterOp.java: New file.
	* java/awt/peer/ComponentPeer.java (getGraphicsConfiguration):
	More powerfult replacement for getColorModel().
	(getColorModel) Removed.
	(setEventMask) New method.
	* Makefile.am: Added new files.
	* Makefile.in: Rebuilt.


Rolf


Index: libjava/gnu/gcj/awt/ComponentDataBlitOp.java
===================================================================
RCS file: ComponentDataBlitOp.java
diff -N ComponentDataBlitOp.java
--- /dev/null	Tue May  5 13:32:27 1998
+++ ComponentDataBlitOp.java	Fri Aug 11 10:06:44 2000
@@ -0,0 +1,125 @@
+/* Copyright © 2000  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package gnu.gcj.awt;
+
+import java.awt.geom.*;
+import java.awt.image.*;
+import java.awt.RenderingHints;
+
+/**
+ * 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 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.
+	// System.out.println("scan lines blits collapsed"); // DEBUG
+	
+	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");
+  }
+}
Index: libjava/gnu/gcj/awt/GLightweightPeer.java
===================================================================
RCS file: GLightweightPeer.java
diff -N GLightweightPeer.java
--- /dev/null	Tue May  5 13:32:27 1998
+++ GLightweightPeer.java	Fri Aug 11 10:06:44 2000
@@ -0,0 +1,131 @@
+/* Copyright © 2000  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package gnu.gcj.awt;
+
+import java.awt.*;
+import java.awt.peer.*;
+import java.awt.image.*;
+
+/**
+ * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
+ */
+public class GLightweightPeer implements LightweightPeer
+{
+  public static final GLightweightPeer INSTANCE = new GLightweightPeer();
+
+  public GLightweightPeer() {}
+
+  // -------- java.awt.peer.ComponentPeer implementation:
+  
+  public int checkImage(Image img, int width, int height, ImageObserver o)
+  {
+    return 0;
+  }
+
+  public Image createImage(ImageProducer prod) {
+    return null;
+  }
+
+  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 null;
+  }
+
+  public Graphics getGraphics()
+  {
+    return null;
+  }
+
+  public Point getLocationOnScreen()
+  {
+    return null;
+  }
+
+  public Dimension getMinimumSize()
+  {
+    return null;
+  }
+
+  public Dimension getPreferredSize()
+  {
+    return null;
+  }
+
+  public Toolkit getToolkit()
+  {
+    return null;
+  }
+
+  public void handleEvent(AWTEvent e) {}
+
+  public void hide() {}
+
+  public boolean isFocusTraversable()
+  {
+    return false;
+  }
+
+  public Dimension minimumSize()
+  {
+    return null;
+  }
+
+  public Dimension preferredSize()
+  {
+    return null;
+  }
+
+  public void paint(Graphics graphics) {}
+
+  public boolean prepareImage(Image img, int width, int height,
+			      ImageObserver o)
+  {
+    return false;
+  }
+
+  public void print(Graphics graphics) {}
+
+  public void repaint(long tm, int x, int y, int width, int height) {}
+
+  public void requestFocus() {}
+
+  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() {}
+}
Index: libjava/java/awt/BorderLayout.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/BorderLayout.java,v
retrieving revision 1.4
diff -u -r1.4 BorderLayout.java
--- BorderLayout.java	2000/07/31 02:03:51	1.4
+++ BorderLayout.java	2000/08/11 17:06:44
@@ -8,12 +8,25 @@
 
 package java.awt;
 
-/* A very incomplete placeholder. */
-
-public class BorderLayout implements LayoutManager2
+public class BorderLayout implements LayoutManager2, java.io.Serializable
 {
+  public static final String NORTH  = "North";
+  public static final String SOUTH  = "South";
+  public static final String EAST   = "East";
+  public static final String WEST   = "West";
+  public static final String CENTER = "Center";
+  
+  // FIXME: use these too
+  public static final String BEFORE_FIRST_LINE = "First";
+  public static final String AFTER_LAST_LINE = "Last";
+  public static final String BEFORE_LINE_BEGINS = "Before";
+  public static final String AFTER_LINE_ENDS = "After";
+
+
+  // FIXME: check serialization of fields
   int hgap;
   int vgap;
+  Component north, south, east, west, center;
 
   public BorderLayout ()
   {
@@ -25,27 +38,215 @@
     this.hgap = hgap;
     this.vgap = vgap;
   }
+
+  public int getHgap()
+  {
+    return hgap;
+  }    
+
+  public void setHgap(int hgap)
+  {
+    this.hgap = hgap;
+  }
+
+  public int getVgap()
+  {
+    return vgap;
+  }    
+
+  public void setVgap(int vgap)
+  {
+    this.vgap = vgap;
+  }
+  
+  public void addLayoutComponent(Component comp, Object constraints)
+  {
+    if ((constraints == null) || CENTER.equals(constraints))
+      {
+	center = comp; 
+      }
+    else if (NORTH.equals(constraints))
+      {
+	north = comp;
+      }
+    else if (SOUTH.equals(constraints))
+      {
+	south = comp;
+      }
+    else if (EAST.equals(constraints))
+      {
+	east = comp;
+      }
+    else if (WEST.equals(constraints))
+      {
+	west = comp;
+      }
+  }
+    
+  public void addLayoutComponent(String name, Component comp)
+  {
+    addLayoutComponent(comp, name);
+  }
+
+  public void removeLayoutComponent(Component comp)
+  {
+    if (center == comp)
+      {
+	center = null;
+      }
+    else if (north == comp)
+      {
+	north = null;
+      }
+    else if (south == comp)
+      {
+	south = null;
+      }
+    else if (east == comp)
+      {
+	east = null;
+      }
+    else if (west == comp)
+      {
+	west = null;
+      }
+  }
+
+  public Dimension minimumLayoutSize(Container target)
+  {
+    return calcSize(getMinimumSize(center),
+		    getMinimumSize(north),
+		    getMinimumSize(south),
+		    getMinimumSize(east),
+		    getMinimumSize(west),
+		    target);
+  }
 
-  public void addLayoutComponent (String name, Component comp)
-  { /* FIXME */ }
-  public void layoutContainer (Container parent)
-  { /* FIXME */ }
-  public Dimension minimumLayoutSize (Container parent)
-  { /* FIXME */ return null; }
-  public Dimension preferredLayoutSize (Container parent)
-  { /* FIXME */ return null; }
-  public void removeLayoutComponent (Component comp)
-  { /* FIXME */ }
-
-  public void addLayoutComponent (Component comp, Object constraints)
-  { /* FIXME */ }
-  public float getLayoutAlignmentX (Container target)
-  { /* FIXME */ return (float) 0.0; }
-  public float getLayoutAlignmentY (Container target)
-  { /* FIXME */ return (float) 0.0; }
-  public void invalidateLayout (Container target)
-  { /* FIXME */ }
-  public Dimension maximumLayoutSize (Container target)
-  { /* FIXME */ return null; }
+  public Dimension preferredLayoutSize(Container target)
+  {
+    return calcSize(getPreferredSize(center),
+		    getPreferredSize(north),
+		    getPreferredSize(south),
+		    getPreferredSize(east),
+		    getPreferredSize(west),
+		    target);	
+  }
+    
+  /**
+   * Completely disregards the requested maximum sizes of the
+   * components, and states that the container has no upper size
+   * limit.
+   *
+   * @return a dimension of width and height Integer.MAX_VALUE.
+   */
+  public Dimension maximumLayoutSize(Container target)
+  {
+    return (Dimension) DIM_MAX.clone();
+  }	
 
+  public float getLayoutAlignmentX(Container parent)
+  {
+    return Component.CENTER_ALIGNMENT;
+  }
+
+  public float getLayoutAlignmentY(Container parent)
+  {
+    return Component.CENTER_ALIGNMENT;
+  }
+    
+  public void invalidateLayout(Container target)
+  {
+    // TODO... implement caching?
+  }
+
+  public void layoutContainer(Container target)
+  {
+    Insets i = target.getInsets();
+    Dimension c = getPreferredSize(center);
+    Dimension n = getPreferredSize(north);
+    Dimension s = getPreferredSize(south);
+    Dimension e = getPreferredSize(east);
+    Dimension w = getPreferredSize(west);
+    Dimension t = target.getSize();
+    
+    /*
+      <-> hgap     <-> hgap
+      +----------------------------+          }
+      |t                           |          } i.top
+      |  +----------------------+  |  --- y1  }
+      |  |n                     |  |
+      |  +----------------------+  |          } vgap
+      |  +---+ +----------+ +---+  |  --- y2  }        }
+      |  |w  | |c         | |e  |  |                   } hh
+      |  +---+ +----------+ +---+  |          } vgap   }
+      |  +----------------------+  |  --- y3  }
+      |  |s                     |  |
+      |  +----------------------+  |          }
+      |                            |          } i.bottom
+      +----------------------------+          }
+         |x1   |x2          |x3
+         <---------------------->
+      <-->         ww           <-->
+     i.left                    i.right
+    */
+
+    int x1 = i.left;
+    int x2 = x1 + w.width + hgap;
+    int x3 = t.width - i.right - e.width;
+    int ww = t.width - i.right - i.left;
+
+    int y1 = i.top;
+    int y2 = y1 + n.height + vgap;
+    int y3 = t.height - i.bottom - s.height;
+    int hh = y3-y2-vgap;
+
+    setBounds(center, x2, y2, x3-x2-hgap, hh);
+    setBounds(north, x1, y1, ww, n.height);
+    setBounds(south, x1, y3, ww, s.height);
+    setBounds(west, x1, y2, w.width, hh);
+    setBounds(east, x3, y2, e.width, hh);
+  }
+  
+  
+  void setBounds(Component comp, int x, int y, int w, int h)
+  {
+    if (comp == null) return;
+    comp.setBounds(x, y, w, h);
+  }
+
+  public String toString()
+  {
+    return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
+  }
+
+
+  // Support:
+
+  static final Dimension DIM_0   = new Dimension(0, 0);
+  static final Dimension DIM_MAX = new Dimension(Integer.MAX_VALUE,
+						 Integer.MAX_VALUE);
+
+  Dimension getMinimumSize(Component comp)
+  {
+    if (comp == null) return DIM_0;
+    return comp.getMinimumSize();
+  }
+
+  Dimension getPreferredSize(Component comp)
+  {
+    if (comp == null) return DIM_0;
+    return comp.getPreferredSize();
+  }
+
+  Dimension calcSize(Dimension c, Dimension n, Dimension s,
+		     Dimension e, Dimension w, Container target)
+  {
+    Insets i = target.getInsets();
+    
+    return new Dimension(c.width + e.width + w.width + hgap*2 +
+			 i.left + i.right,
+			 c.height + n.height + s.height + vgap*2 +
+			 i.top + i.bottom
+			 );
+  }
 }
Index: libjava/java/awt/Button.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Button.java,v
retrieving revision 1.2
diff -u -r1.2 Button.java
--- Button.java	2000/07/31 02:03:51	1.2
+++ Button.java	2000/08/11 17:06:44
@@ -11,6 +11,7 @@
 import java.awt.peer.ComponentPeer;
 import java.awt.event.ActionListener;
 import java.awt.event.ActionEvent;
+import java.util.EventListener;
 
 /**
  * @author Tom Tromey <tromey@cygnus.com>
@@ -31,18 +32,19 @@
 
   public void addActionListener (ActionListener l)
   {
-    listeners = AWTEventMulticaster.add (listeners, l);
+    actionListener = AWTEventMulticaster.add (actionListener, l);
   }
 
   public void addNotify ()
   {
     if (peer == null)
       peer = (ComponentPeer) getToolkit ().createButton (this);
+    super.addNotify();
   }
 
   public String getActionCommand ()
   {
-    return command;
+    return actionCommand;
   }
 
   public String getLabel ()
@@ -55,10 +57,21 @@
     return "Button[" + label + "]";
   }
 
+  void dispatchEventImpl(AWTEvent e)
+  {
+      super.dispatchEventImpl(e);
+      
+      if (e.id <= ActionEvent.ACTION_LAST 
+	  && e.id >= ActionEvent.ACTION_FIRST
+	  && (actionListener != null 
+	      || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
+	  processEvent(e);
+  }
+
   protected void processActionEvent (ActionEvent e)
   {
-    if (listeners != null)
-      listeners.actionPerformed (e);
+    if (actionListener != null)
+      actionListener.actionPerformed (e);
   }
 
   protected void processEvent (AWTEvent e)
@@ -71,12 +84,19 @@
 
   public void removeActionListener (ActionListener l)
   {
-    listeners = AWTEventMulticaster.remove (listeners, l);
+    actionListener = AWTEventMulticaster.remove (actionListener, l);
   }
 
+  public EventListener[] getListeners(Class listenerType)
+  {
+    if (listenerType == ActionListener.class)
+      return getListenersImpl(listenerType, actionListener);
+    return super.getListeners(listenerType);
+  }
+
   public void setActionCommand (String command)
   {
-    this.command = (command == null) ? label : command;
+    this.actionCommand = (command == null) ? label : command;
   }
 
   public void setLabel (String label)
@@ -88,8 +108,9 @@
 	bp.setLabel (label);
       }
   }
+
+  String label;
+  String actionCommand;
 
-  private String label;
-  private String command;
-  private ActionListener listeners;
+  transient ActionListener actionListener;
 }
Index: libjava/java/awt/Canvas.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Canvas.java,v
retrieving revision 1.1
diff -u -r1.1 Canvas.java
--- Canvas.java	2000/08/03 12:09:38	1.1
+++ Canvas.java	2000/08/11 17:06:44
@@ -8,8 +8,44 @@
 
 package java.awt;
 
-/* A very incomplete placeholder. */
+import java.awt.peer.ComponentPeer;
 
 public class Canvas extends Component
 {
+  transient GraphicsConfiguration graphicsConfiguration;
+  
+  public Canvas() { }
+  
+  public Canvas(GraphicsConfiguration graphicsConfiguration)
+  {
+    this.graphicsConfiguration = graphicsConfiguration;
+  }
+
+  GraphicsConfiguration getGraphicsConfigurationImpl()
+  {
+    if (graphicsConfiguration != null) return graphicsConfiguration;
+    return super.getGraphicsConfigurationImpl();
+  }
+
+  public void addNotify()
+  {
+    if (peer == null)
+      {
+	peer = (ComponentPeer) getToolkit().createCanvas(this);
+      }
+    super.addNotify();
+  }
+
+  /** Override this to create components with custom painting.
+      Defaults to filling the component with the background color. */
+  public void paint(Graphics gfx)
+  {
+    /* This implementation doesn't make much sense since the filling
+      of background color is guaranteed for heavyweight components
+      such as this.  But there's no need to worry, since paint() is
+      usually overridden anyway.  */
+    gfx.setColor(getBackground());
+    Dimension size = getSize();
+    gfx.fillRect(0, 0, size.width, size.height);
+  }
 }
Index: libjava/java/awt/Color.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Color.java,v
retrieving revision 1.4
diff -u -r1.4 Color.java
--- Color.java	2000/08/09 13:01:43	1.4
+++ Color.java	2000/08/11 17:06:44
@@ -87,6 +87,29 @@
   {
     return rgba;
   }
+
+  static final int BRIGHT_STEP = 0x30;
+
+  public Color brighter()
+  {
+    return new Color(Math.min(255, getRed()   + BRIGHT_STEP),
+		     Math.min(255, getGreen() + BRIGHT_STEP),
+		     Math.min(255, getBlue()  + BRIGHT_STEP),
+		     getAlpha());
+  }
+    
+  public Color darker()
+  {
+    return new Color(Math.max(0, getRed()   - BRIGHT_STEP),
+		     Math.max(0, getGreen() - BRIGHT_STEP),
+		     Math.max(0, getBlue()  - BRIGHT_STEP),
+		     getAlpha());
+  }
+    
+  public int hashCode()
+  {
+    return rgba;
+  }
   
   public int getTransparency()
   {
@@ -96,3 +119,4 @@
       return Transparency.TRANSLUCENT;
   }
 }
+
Index: libjava/java/awt/Component.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Component.java,v
retrieving revision 1.11
diff -u -r1.11 Component.java
--- Component.java	2000/08/09 13:01:43	1.11
+++ Component.java	2000/08/11 17:06:44
@@ -17,6 +17,7 @@
 import java.util.ResourceBundle;
 import java.util.Vector;
 import java.awt.peer.ComponentPeer;
+import java.awt.peer.LightweightPeer;
 import java.beans.PropertyChangeSupport;
 import java.beans.PropertyChangeListener;
 // import javax.accessibility.AccessibleContext;
@@ -59,8 +60,8 @@
   Font peerFont;
   Cursor cursor;
   Locale locale;
-  boolean visible;
-  boolean enabled;
+  boolean visible = true; // default (except for Window)
+  boolean enabled = true;
   boolean valid;
   boolean hasFocus;
   //DropTarget dropTarget;
@@ -70,7 +71,7 @@
   Dimension minSize;
   Dimension prefSize;
   boolean newEventsOnly;  
-  long eventMask;
+  long eventMask = AWTEvent.PAINT_EVENT_MASK;
   PropertyChangeSupport changeSupport;
   boolean isPacked;
   int componentSerializedDataVersion;
@@ -143,8 +144,23 @@
   /** @since 1.3 */
   public GraphicsConfiguration getGraphicsConfiguration()
   {
+    return getGraphicsConfigurationImpl();
+  }
+
+  /** Implementation method that allows classes such as Canvas and
+      Window to override the graphics configuration without violating
+      the published API. */
+  GraphicsConfiguration getGraphicsConfigurationImpl()
+  {
+    if (peer != null)
+      {
+	GraphicsConfiguration config = peer.getGraphicsConfiguration();
+	if (config != null) return config;
+      }
+
     if (parent != null)
       return parent.getGraphicsConfiguration();
+
     return null;
   }
 
@@ -156,7 +172,10 @@
   public Toolkit getToolkit()
   {
     if (peer != null)
-      return peer.getToolkit ();
+      {
+	Toolkit tk = peer.getToolkit();
+	if (tk != null) return tk;
+      }
     if (parent != null)
       return parent.getToolkit ();
     return Toolkit.getDefaultToolkit ();
@@ -170,7 +189,8 @@
   /** @since 1.2 */
   public boolean isDisplayable()
   {
-    return (peer != null);
+    if (parent != null) return parent.isDisplayable();
+    return false;
   }
   
   public boolean isVisible()
@@ -186,7 +206,7 @@
     if (parent != null)
       return (parent.isShowing());
 
-    return true;
+    return false;
   }
   
   public boolean isEnabled()
@@ -264,7 +284,9 @@
   
   public Color getForeground()
   {
-    return this.foreground;
+    if (foreground != null) return foreground;
+    if (parent != null) return parent.getForeground();
+    return null;
   }
   
   public void setForeground(Color c)
@@ -272,11 +294,18 @@
     if (peer != null)
       peer.setForeground(c);
     this.foreground = c;
+    if (peer != null) peer.setForeground(foreground);
   }
-  
+
+  /** @return the background color of the component. null may be
+      returned instead of the actual background color, if this
+      method is called before the component is added to the
+      component hierarchy. */
   public Color getBackground()
   {
-    return this.background;
+    if (background != null) return background;
+    if (parent != null) return parent.getBackground();
+    return null;
   }
   
   public void setBackground(Color c)
@@ -284,11 +313,14 @@
     if (peer != null)
       peer.setBackground(c);
     this.background = c;
+    if (peer != null) peer.setBackground(background);
   }
   
   public Font getFont()
   {
-    return this.font;
+    if (font != null) return font;
+    if (parent != null) return parent.getFont();
+    return null;
   }
   
   public void setFont(Font f)
@@ -296,6 +328,7 @@
     if (peer != null)
       peer.setFont(f);
     this.font = f;
+    if (peer != null) peer.setFont(font);
   }
 
   public Locale getLocale() throws IllegalComponentStateException
@@ -311,12 +344,19 @@
   public void setLocale(Locale l)  
   {
     this.locale = l;
+    
+    /* new writing/layout direction perhaps, or make more/less
+       room for localized text labels */
+    invalidate();
   }
   
   public ColorModel getColorModel()
   {
-    // FIXME
-    return null;
+    GraphicsConfiguration config = getGraphicsConfiguration();
+
+    if (config != null) return config.getColorModel();
+
+    return getToolkit().getColorModel();    
   }
 
   public Point getLocation()
@@ -338,6 +378,10 @@
 
   public void setLocation (int x, int y)
   {
+    if ((this.x == x) && (this.y == y)) return;
+    
+    invalidate();
+    
     this.x = x;
     this.y = y;
     if (peer != null)
@@ -368,6 +412,10 @@
   
   public void setSize(int width, int height)
   {
+    if ((this.width == width) && (this.height == height)) return;
+
+    invalidate();
+
     this.width = width;
     this.height = height;
     if (peer != null)
@@ -404,10 +452,16 @@
   
   public void setBounds(int x, int y, int w, int h)
   {
+    if ((this.x == x) && (this.y == y) &&
+	(this.width == w) && (this.height == h)) return;
+
+    invalidate();
+
     this.x = x;
     this.y = y;
     this.width = w;
     this.height = h;
+
     if (peer != null)
       peer.setBounds(x, y, w, h);
   }
@@ -473,14 +527,19 @@
   /** @since 1.2 */
   public boolean isOpaque()
   {
-    return false;
+    return !isLightweight();
   }
   
-  /** @since 1.2 */  
+  /** 
+   * Return whether the component is lightweight.
+   *
+   * @return true if component has a peer and and the peer is lightweight.
+   *
+   * @since 1.2
+   */  
   public boolean isLightweight()
   {
-    // FIXME
-    return false;
+    return (peer != null) && (peer instanceof LightweightPeer);
   }
   
   public Dimension getPreferredSize()
@@ -515,8 +574,7 @@
   
   public Dimension getMaximumSize()
   {
-    // FIXME
-    return null;
+    return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
   }
   
   public float getAlignmentX()
@@ -533,7 +591,7 @@
   
   public void doLayout()
   {
-    // FIXME
+    // nothing to do unless we're a container
   }
   
   /** @deprecated */
@@ -544,26 +602,39 @@
   
   public void validate()
   {
-    // FIXME
+    // nothing to do unless we're a container
   }
   
   public void invalidate()
   {
     valid = false;
-    if (parent != null)
-      parent.invalidate ();
+
+    if ((parent != null) && parent.valid)
+	parent.invalidate ();
   }
   
   public Graphics getGraphics()
   {
-    // FIXME
+    if (peer != null) {
+      Graphics gfx = peer.getGraphics();
+      if (gfx != null) return gfx;
+      
+      // create graphics for lightweight:
+      Container parent = getParent();
+      if (parent != null) {
+	gfx = parent.getGraphics();
+	Rectangle bounds = getBounds();
+	gfx.setClip(bounds);
+	gfx.translate(bounds.x, bounds.y);
+	return gfx;
+      }
+    }
     return null;
   }
   
   public FontMetrics getFontMetrics(Font font)
   {
-    // FIXME
-    return null;
+    return getToolkit().getFontMetrics(font);
   }
   
   public void setCursor(Cursor cursor)
@@ -582,41 +653,53 @@
   
   public void update(Graphics g)
   {
-    // FIXME
+    paint(g);
   }
   
   public void paintAll(Graphics g)
   {    
+    if (!visible) return;
+	
+    if (peer != null) peer.paint(g);
+    paint(g);
   }
   
   public void repaint()
   {
-    // FIXME
+    repaint(0, 0, 0, getWidth(), getHeight());
   }
   
   public void repaint(long tm)
   {
-    // FIXME
+    repaint(tm, 0, 0, getWidth(), getHeight());
   }
   
   public void repaint(int x, int y, int width, int height)
   {
-    // FIXME  
+    repaint(0, x, y, width, height);
   }
   
   public void repaint(long tm, int x, int y, int width, int height)
   {    
-    // FIXME  
+    // Handle lightweight repainting by forwarding to native parent
+    if (isLightweight() && (parent != null))
+      {
+	if (parent != null)
+	  parent.repaint(tm, x+getX(), y+getY(), width, height);
+	return;
+      }
+    
+    if (peer != null) peer.repaint(tm, x, y, width, height);
   }
   
   public void print(Graphics g)
   {
-    // FIXME    
+    paint(g);
   }
   
   public void printAll(Graphics g)
   {
-    // FIXME      
+    paintAll(g);
   }
   
   public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h)
@@ -633,8 +716,7 @@
   
   public Image createImage(int width, int height)
   {
-    // FIXME
-    return null;
+    return getGraphicsConfiguration().createCompatibleImage(width, height);
   }
   
   public boolean prepareImage(Image image, ImageObserver observer)
@@ -717,6 +799,9 @@
   public final void dispatchEvent(AWTEvent e)
   {
     dispatchEventImpl(e);
+
+    /* Give the peer a chance to handle the event. */
+    if (peer != null) peer.handleEvent(e);
   }
   
   void dispatchEventImpl(AWTEvent e)
@@ -754,6 +839,10 @@
 		 || hierarchyBoundsListener != null
 		 || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0))
       processEvent(e);
+    else if (e.id <= PaintEvent.PAINT_LAST
+	     && e.id >= PaintEvent.PAINT_FIRST
+	     && (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0)      
+      processEvent(e);
   }
   
   /** @deprecated */
@@ -939,6 +1028,9 @@
     // interface, but thats okay because the peer interfaces have been
     // deprecated for a long time, and no longer feature in the 
     // API specification at all.
+
+    if (isLightweight() && (parent != null))
+      parent.enableEvents(eventsToEnable);
   }
   
   protected final void disableEvents(long eventsToDisable)
@@ -953,37 +1045,83 @@
     */
   protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)
   {
-    if (existingEvent instanceof MouseEvent
-        && (existingEvent.id == MouseEvent.MOUSE_DRAGGED
-	    || existingEvent.id == MouseEvent.MOUSE_MOVED))
+    switch (existingEvent.id)
       {
-        // Just drop the old (intermediate) event and return the new one.
+      case MouseEvent.MOUSE_MOVED:
+      case MouseEvent.MOUSE_DRAGGED:
+	// Just drop the old (intermediate) event and return the new one.
 	return newEvent;
+      case PaintEvent.PAINT:
+      case PaintEvent.UPDATE:
+	return coalescePaintEvents((PaintEvent) existingEvent,
+				   (PaintEvent) newEvent);
       }
-    /*
-    else if (existingEvent instanceof PaintEvent)
-      {
-        // The JDK 1.3 documentation says that in this case a complex 
-	// RepaintArea is generated. We don't do that yet, and creating a 
-	// union area as suggested by older documentation sounds ugly.
-      }
-    */
-      
-    // FIXME
     return null;
   }
   
+  /**
+   * Coalesce paint events. Current heuristic is: Merge if the union of
+   * areas is less than twice that of the sum of the areas. The X server
+   * tend to create a lot of paint events that are adjacent but not
+   * overlapping.
+   *
+   * <pre>
+   * +------+
+   * |      +-----+  ...will be merged
+   * |      |     |
+   * |      |     |
+   * +------+     |
+   *        +-----+
+   * 
+   * +---------------+--+
+   * |               |  |  ...will not be merged
+   * +---------------+  |
+   *                 |  |
+   *                 |  |
+   *                 |  |
+   *                 |  |
+   *                 |  |
+   *                 +--+
+   * </pre>
+   */
+
+  private PaintEvent coalescePaintEvents(PaintEvent queuedEvent,
+					 PaintEvent newEvent)
+  {
+    Rectangle r1 = queuedEvent.getUpdateRect();
+    Rectangle r2 = newEvent.getUpdateRect();
+    Rectangle union = r1.union(r2);
+    
+    int r1a = r1.width * r1.height;
+    int r2a = r2.width * r2.height;
+    int ua  = union.width * union.height;
+    
+    if (ua > (r1a+r2a)*2) return null;
+    /* The 2 factor should maybe be reconsidered. Perhaps 3/2
+       would be better? */
+
+    newEvent.setUpdateRect(union);
+    return newEvent;
+  }
+
+
+
+
   /** Forward event to the appropriate processXXXEvent method based on the
     * event type.
     */
   protected void processEvent(AWTEvent e)
   {
-    if (e instanceof ComponentEvent)
-      processComponentEvent((ComponentEvent) e);
-    else if (e instanceof FocusEvent)
+
+    /* Note: the order of these if statements are
+       important. Subclasses must be checked first. Eg. MouseEvent
+       must be checked before ComponentEvent, since a MouseEvent
+       object is also an instance of a ComponentEvent. */
+
+    if (e instanceof FocusEvent)
       processFocusEvent((FocusEvent) e);
-    else if (e instanceof KeyEvent)
-      processKeyEvent((KeyEvent) e);
+    else if (e instanceof PaintEvent)
+      processPaintEvent((PaintEvent) e);
     else if (e instanceof MouseEvent)
       {
         if (e.id == MouseEvent.MOUSE_MOVED 
@@ -992,6 +1130,10 @@
 	else
 	  processMouseEvent((MouseEvent) e);
       }
+    else if (e instanceof ComponentEvent)
+      processComponentEvent((ComponentEvent) e);
+    else if (e instanceof KeyEvent)
+      processKeyEvent((KeyEvent) e);
     else if (e instanceof InputMethodEvent)
       processInputMethodEvent((InputMethodEvent) e);
     else if (e instanceof HierarchyEvent)
@@ -1067,7 +1209,7 @@
     switch (e.id)
       {
 	case MouseEvent.MOUSE_CLICKED:
-	  mouseListener.mousePressed(e);
+	  mouseListener.mouseClicked(e);
 	break;
         case MouseEvent.MOUSE_ENTERED:
 	  mouseListener.mouseEntered(e);
@@ -1139,6 +1281,31 @@
 	break;
       }
   }
+
+  private void processPaintEvent(PaintEvent event)
+  {
+    ComponentPeer peer = getPeer();
+	
+    // Can't do graphics without peer
+    if (peer == null)
+      return;
+
+    Graphics gfx = getGraphics();
+    Shape clip = event.getUpdateRect();
+    gfx.setClip(clip);
+
+    switch (event.id)
+      {
+      case PaintEvent.PAINT:
+	if (peer != null) paint(gfx);
+	break;
+      case PaintEvent.UPDATE:
+	if (peer != null) update(gfx);
+	break;
+      default:
+	throw new IllegalArgumentException("unknown paint event");
+      }
+  }
   
   /** @deprecated */
   public boolean handleEvent(Event evt)
@@ -1204,14 +1371,33 @@
   {
     if (peer == null)
       peer = getToolkit().createComponent(this);
+
+    /* Add notify children using a template method, so that it is
+       possible to ensure that the new event mask delivered to the
+       peer. */
+    addNotifyContainerChildren();
+
+    /* Now that all the children has gotten their peers, we should
+       have the event mask needed for this component and its
+       lightweight subcomponents. */
+
+    peer.setEventMask(eventMask);
+
+    /* We do not invalidate here, but rather leave that job up to
+       the peer. For efficiency, the peer can choose not to
+       invalidate if it is happy with the current dimensions,
+       etc. */
   }
-  
+
+  void addNotifyContainerChildren() {
+    // nothing to do unless we're a container
+  }
+
   public void removeNotify()
   {    
     if (peer != null)
       peer.dispose();
     peer = null;
-    visible = false;
   }
   
   /** @deprecated */
@@ -1269,8 +1455,28 @@
   
   protected String paramString()
   {
-    // FIXME
-    return "FIXME";
+    StringBuffer param = new StringBuffer();
+    String name = getName();
+    if (name != null)
+      {
+	param.append(name);
+	param.append(",");
+      }
+    param.append(width);
+    param.append("x");
+    param.append(height);
+    param.append("+");
+    param.append(x);
+    param.append("+");
+    param.append(y);
+    
+    if (!isValid()) param.append(",invalid");
+    if (!isVisible()) param.append(",invisible");
+    if (!isEnabled()) param.append(",disabled");
+    if (!isOpaque()) param.append(",translucent");
+    if (isDoubleBuffered()) param.append(",doublebuffered");
+    
+    return param.toString();
   }
   
   public String toString()
@@ -1280,10 +1486,12 @@
   
   public void list()
   {
+    list(System.out);
   }
   
   public void list(PrintStream out)
   {
+    list(out, 0);
   }
   
   public void list(PrintStream out, int indent)
Index: libjava/java/awt/Container.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Container.java,v
retrieving revision 1.8
diff -u -r1.8 Container.java
--- Container.java	2000/08/09 13:01:43	1.8
+++ Container.java	2000/08/11 17:06:44
@@ -14,8 +14,9 @@
 import java.util.EventListener;
 import java.awt.peer.ComponentPeer;
 import java.awt.peer.ContainerPeer;
+import java.awt.peer.LightweightPeer;
 
-/* A very incomplete placeholder. */
+/* A somewhat incomplete class. */
 
 public abstract class Container extends Component
 {
@@ -30,9 +31,6 @@
   /* Anything else is non-serializable, and should be declared "transient". */
   transient ContainerListener containerListener;  
 
-  // Insets.
-  private transient Insets myInsets;
-
   public Container()
   {
   }
@@ -65,7 +63,9 @@
 
   public Insets getInsets()
   {
-    return myInsets;
+    if (peer == null) return new Insets(0, 0, 0, 0);
+	
+    return ((ContainerPeer) peer).getInsets();
   }
 
   /** @deprecated Use getInsets() instead. */
@@ -112,14 +112,22 @@
 
     // Reparent component, and make sure component is instantiated if
     // we are.
-    if (comp.parent != this)
+    if (comp.parent != null)
       comp.parent.remove (comp);
     comp.parent = this;
     if (peer != null)
-      comp.addNotify ();
+      {
+	comp.addNotify ();
+    
+	if (comp.isLightweight())
+	  enableEvents(comp.eventMask);
+      }
 
     invalidate ();
 
+    if (component == null)
+	component = new Component[4]; // FIXME, better initial size?
+
     // This isn't the most efficient implementation.  We could do less
     // copying when growing the array.  It probably doesn't matter.
     if (ncomponents >= component.length)
@@ -228,20 +236,48 @@
   {
     if (! isValid ())
       {
-	doLayout ();
 	validateTree ();
       }
   }
 
   protected void validateTree()
   {
+    if (valid) return; 
+
+    ContainerPeer cPeer = null;
+    if ((peer != null) && !(peer instanceof LightweightPeer))
+      {
+	cPeer = (ContainerPeer) peer;
+	cPeer.beginValidate();
+      }
+
+    doLayout ();
     for (int i = 0; i < ncomponents; ++i)
-      component[i].validate ();
+      {
+	Component comp = component[i];
+	if (comp instanceof Container)
+	  {
+	    ((Container) comp).validateTree();
+	  }
+	else
+	  {
+	    component[i].validate();
+	  }
+      }
+    
+    /* children will call invalidate() when they are layed out. It
+       is therefore imporant that valid is not set to true
+       before after the children has been layed out. */
+    valid = true;
+
+    if (cPeer != null)
+      cPeer.endValidate();
   }
 
   public void setFont(Font f)
   {
-    // FIXME
+    super.setFont(f);
+    // FIXME, should invalidate all children with font == null
   }
 
   public Dimension getPreferredSize()
@@ -307,28 +343,66 @@
 
   public void paint(Graphics g)
   {
-    // FIXME
+    if (!isShowing()) return;
+    super.paint(g);
+    visitChildren(g, GfxPaintVisitor.INSTANCE, true);
+  }
+
+  private void visitChildren(Graphics gfx, GfxVisitor visitor,
+		     boolean lightweightOnly)
+  {
+    // FIXME: do locking
+
+    for (int i = 0; i < ncomponents; ++i)
+      {
+	Component comp = component[i];
+	// ignore invisible children
+	if (!comp.isVisible()) continue;
+	
+	visitChild(gfx, visitor, lightweightOnly, comp);
+      }
   }
 
+  private void visitChild(Graphics gfx, GfxVisitor visitor,
+			  boolean lightweightOnly, Component comp)
+  {
+    boolean isHeavy = !comp.isLightweight();
+    
+    if (lightweightOnly && isHeavy) return;
+
+    Rectangle bounds = comp.getBounds();
+    Rectangle clip = gfx.getClipBounds().intersection(bounds);
+    
+    if (clip.isEmpty()) return;
+
+    Graphics gfx2 = gfx.create();
+    gfx2.setClip(clip.x, clip.y, clip.width, clip.height);
+    gfx2.translate(bounds.x, bounds.y);
+    
+    visitor.visit(comp, gfx2);
+  }
+
   public void update(Graphics g)
   {
-    // FIXME
+    super.update(g);
   }
 
   public void print(Graphics g)
   {
-    // FIXME
+    super.print(g);
+    visitChildren(g, GfxPrintVisitor.INSTANCE, true);
   }
 
   public void paintComponents(Graphics g)
   {
-    // FIXME
+    super.paint(g);
+    visitChildren(g, GfxPaintAllVisitor.INSTANCE, true);
   }
 
   public void printComponents(Graphics g)
   {
-    for (int i = 0; i < ncomponents; ++i)
-      component[i].printAll (g);
+    super.paint(g);
+    visitChildren(g, GfxPrintAllVisitor.INSTANCE, true);
   }
   
   void dispatchEventImpl(AWTEvent e)
@@ -393,12 +467,16 @@
       return null;
     for (int i = 0; i < ncomponents; ++i)
       {
+	// Ignore invisible children...
+	if (!component[i].isVisible())
+	  continue;
+	
 	int x2 = x - component[i].x;
 	int y2 = y - component[i].y;
 	if (component[i].contains (x2, y2))
 	  return component[i];
       }
-    return null;
+    return this;
   }
 
   /** @deprecated Use getComponentAt() instead */
@@ -425,8 +503,17 @@
 
   public void addNotify ()
   {
+    super.addNotify();
+  }
+
+  void addNotifyContainerChildren()
+  {
     for (int i = ncomponents;  --i >= 0; )
-      component[i].addNotify();
+      {
+	component[i].addNotify();
+	if (component[i].isLightweight())
+	  enableEvents(component[i].eventMask);
+      }
   }
 
   public void removeNotify()
@@ -450,7 +537,11 @@
 
   protected String paramString()
   {
-    return "FIXME";
+    String param = super.paramString();
+    if (layoutMgr != null)
+      param = param + "," + layoutMgr.getClass().getName();
+
+    return param;
   }
   
   public void list (PrintStream out, int indent)
@@ -470,4 +561,33 @@
     for (int i = 0; i < ncomponents; ++i)
       component[i].list (out, indent + 2);
   }
+}
+
+abstract class GfxVisitor
+{
+  public abstract void visit(Component c, Graphics gfx);
+}
+
+class GfxPaintVisitor extends GfxVisitor
+{
+  public void visit(Component c, Graphics gfx) { c.paint(gfx); }
+  public static final GfxVisitor INSTANCE = new GfxPaintVisitor();
+}
+
+class GfxPrintVisitor extends GfxVisitor
+{
+  public void visit(Component c, Graphics gfx) { c.print(gfx); }
+  public static final GfxVisitor INSTANCE = new GfxPrintVisitor();
+}
+
+class GfxPaintAllVisitor extends GfxVisitor
+{
+  public void visit(Component c, Graphics gfx) { c.paintAll(gfx); }
+  public static final GfxVisitor INSTANCE = new GfxPaintAllVisitor();
+}
+
+class GfxPrintAllVisitor extends GfxVisitor
+{
+  public void visit(Component c, Graphics gfx) { c.printAll(gfx); }
+  public static final GfxVisitor INSTANCE = new GfxPrintAllVisitor();
 }
Index: libjava/java/awt/EventQueue.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/EventQueue.java,v
retrieving revision 1.2
diff -u -r1.2 EventQueue.java
--- EventQueue.java	2000/07/15 04:42:47	1.2
+++ EventQueue.java	2000/08/11 17:06:44
@@ -145,8 +145,7 @@
   public static void invokeAndWait(Runnable runnable)
     throws InterruptedException, InvocationTargetException
   {
-    // FIXME: Is this an appropriate way to access the event queue?
-    EventQueue eq = Toolkit.systemEventQueue; 
+    EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue(); 
     Thread current = Thread.currentThread();
     if (current == eq.dispatchThread)
       throw new Error("Can't call invokeAndWait from event dispatch thread");
@@ -169,8 +168,7 @@
   /** @since JDK1.2 */
   static void invokeLater(Runnable runnable)
   {
-    // FIXME: Is this an appropriate way to access the event queue?
-    EventQueue eq = Toolkit.systemEventQueue; 
+    EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue(); 
 
     InvocationEvent ie = 
       new InvocationEvent(eq, runnable, null, false);
@@ -180,8 +178,7 @@
   
   static boolean isDispatchThread()
   {
-    // FIXME: Is this an appropriate way to access the event queue?
-    EventQueue eq = Toolkit.systemEventQueue; 
+    EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue(); 
     return (Thread.currentThread() == eq.dispatchThread);
   }
   
Index: libjava/java/awt/FontMetrics.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/FontMetrics.java,v
retrieving revision 1.1
diff -u -r1.1 FontMetrics.java
--- FontMetrics.java	2000/07/12 03:32:06	1.1
+++ FontMetrics.java	2000/08/11 17:06:44
@@ -28,38 +28,32 @@
 
   public int getLeading()
   {
-    // FIXME??
-    return getHeight() - (getDescent() + getAscent());
+    return getMaxAscent() + getMaxDescent() - (getAscent() + getDescent());
   }
 
   public int getAscent()
   {
-    // FIXME??
     return getHeight() - (getDescent() + getLeading());
   }
 
   public int getDescent()
   {
-    // FIXME??
-    return getHeight() - getDescent();
+    return getHeight() - (getLeading() + getDescent());
   }
 
   public int getHeight()
   {
-    // FIXME??
     return getLeading() + getAscent() + getDescent();
   }
 
   public int getMaxAscent()
   {
-    // FIXME
-    return 0;
+    return getAscent();
   }
 
   public int getMaxDescent()
   {
-    // FIXME
-    return 0;
+    return getDescent();
   }
 
   /* @deprecated Use getMaxDescent() instead. */
@@ -68,24 +62,24 @@
     return getMaxDescent();
   }
 
+  /** @return max advance, or -1 if unknown. */
   public int getMaxAdvance()
   {
-    // FIXME
-    return 0;
+    return -1;
   }
 
+
   public int charWidth(int ch)
   {
-    // FIXME
-    return 0;
+    return charWidth((char) ch);
   }
 
   public int charWidth(char ch)
   {
-    // FIXME
-    return 0;
+    Character chObj = new Character(ch);
+    return stringWidth(chObj.toString());
   }
-
+    
   public int stringWidth(String str)
   {
     return charsWidth(str.toCharArray(), 0, str.length());
@@ -93,20 +87,19 @@
 
   public int charsWidth(char[] data, int off, int len)
   {
-    // FIXME
-    return -1;
+    return stringWidth(new String(data, off, len));
   }
 
   public int bytesWidth(byte[] data, int off, int len)
   {
-    // FIXME?
-    return -1;
+    return stringWidth(new String(data, off, len));
   }
-
+    
   public int[] getWidths()
   {
-    // FIXME
-    return new int[0];
+    int[] widths = new int[256];
+    for (char c=0; c<256; c++) widths[c] = charWidth(c);
+    return widths;
   }
 
   public boolean hasUniformLineMetrics()
Index: libjava/java/awt/Frame.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Frame.java,v
retrieving revision 1.6
diff -u -r1.6 Frame.java
--- Frame.java	2000/07/31 02:03:51	1.6
+++ Frame.java	2000/08/11 17:06:44
@@ -13,22 +13,43 @@
 
 public class Frame extends Window implements MenuContainer
 {
+  public static final int NORMAL = 0;
+  public static final int ICONIFIED = 1;
+
   MenuBar menuBar = null;
   String title;
 
+  private transient Image iconImage;
+  private transient boolean isResizable = true;
+  private transient int state = NORMAL;
+
   public Frame ()
+  {
+    super();
+  }
+
+  public Frame(GraphicsConfiguration gc)
   {
-    super (null);
+    super(gc);
   }
 
   public Frame (String title)
   {
-    super (null);
+    super();
     setTitle(title);
   }
 
-  public String getTitle () { return title; }
+  public Frame(String title, GraphicsConfiguration gc)
+  {
+    super(gc);
+    setTitle(title);
+  }
 
+  public String getTitle()
+  {
+    return (title != null) ? title : "";
+  }
+    
   public void setTitle (String title)
   {
     this.title = title;
@@ -36,12 +57,58 @@
       ((FramePeer)peer).setTitle(title);
   }
 
-  public synchronized void dispose ()
-  { /* FIXME */ }
+  public Image getIconImage()
+  {
+    return iconImage;
+  }
+  
+  public void setIconImage(Image image)
+  {
+    iconImage = image;
+    if (peer != null) ((FramePeer) peer).setIconImage(iconImage);
+  }
+
+  protected void finalize() throws Throwable
+  {
+    //frames.remove(this);
+    /* FIXME: This won't work. Finalize will never be called if frames
+       has a reference to the object. We need weak references to
+       implement this correctly. */
+
+    super.finalize();
+  }
 
   public synchronized void setMenuBar (MenuBar menuBar)
-  { this.menuBar = menuBar; }
+  { 
+    if (this.menuBar != menuBar)
+      {
+	//this.menuBar.removeNotify();
+	this.menuBar = menuBar;
+	//this.menuBar.addNotify();
+      }	
 
+    if (peer != null) ((FramePeer) peer).setMenuBar(menuBar);
+  }
+  
+  public boolean isResizable()
+  {
+    return isResizable;
+  }
+
+  public void setResizable(boolean resizable)
+  {
+    isResizable = resizable;
+    if (peer != null) ((FramePeer) peer).setResizable(isResizable);
+  }
+
+  public int getState()
+  {
+    /* FIXME: State might have changed in the peer... Must check. */
+    
+    return state;
+  }
+
+
   public synchronized void addNotify ()
   {
     if (peer == null)
@@ -49,7 +116,32 @@
     super.addNotify();
   }
 
-  public Font getFont() { return null; } // FIXME
   public boolean postEvent(Event evt) { return false; } // FIXME
-  public void remove(MenuComponent comp) { } // FIXME
+ 
+  public void remove(MenuComponent m)
+  {
+    if (m == menuBar)
+      {
+	setMenuBar(null);
+	return;
+      }
+	
+    super.remove(m);
+  }
+  
+  public void removeNotify()
+  {
+    //if ((peer != null) && (menuBar != null)) menuBar.removeNotify();
+    super.removeNotify();
+  }
+    
+  public static Frame[] getFrames()
+  {
+    //Frame[] array = new Frames[frames.size()];
+    //return frames.toArray(array);
+    
+    // see finalize() comment
+    String msg = "FIXME: can't be implemented without weak references";
+    throw new UnsupportedOperationException(msg);
+  }
 }
Index: libjava/java/awt/Graphics.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Graphics.java,v
retrieving revision 1.1
diff -u -r1.1 Graphics.java
--- Graphics.java	2000/03/17 00:45:06	1.1
+++ Graphics.java	2000/08/11 17:06:44
@@ -8,6 +8,8 @@
 
 package java.awt;
 
+import java.awt.image.ImageObserver;
+
 /**
  * @author Warren Levy <warrenl@cygnus.com>
  * @date March 15, 2000.
@@ -16,14 +18,218 @@
 /**
  * Written using on-line Java Platform 1.2 API Specification, as well
  * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
- * Status:  Stubbed; A very incomplete placeholder.
+ * Status:  Almost complete
  */
 
-public abstract class Graphics extends Object
+public abstract class Graphics
 {
-  protected Graphics()
+  protected Graphics() {}
+  
+  public abstract Graphics create();
+
+  public Graphics create(int x, int y, int width, int height)
+  {
+    Graphics gfx = create();
+    gfx.translate(x, y);
+    gfx.setClip(0, y, width, height);
+    return gfx;
+  }
+
+  public abstract void translate(int x, int y);
+
+  public abstract Color getColor();
+
+  public abstract void setColor(Color color);
+
+  public abstract void setPaintMode();
+
+  public abstract void setXORMode(Color altColor);
+
+  public abstract Font getFont();
+
+  public abstract void setFont(Font font);
+
+  public FontMetrics getFontMetrics()
+  {
+    return getFontMetrics(getFont());
+  }
+
+  public abstract FontMetrics getFontMetrics(Font font);
+
+  public abstract Rectangle getClipBounds();
+
+  public abstract void clipRect(int x, int y, int width, int height);
+
+  public abstract void setClip(int x, int y, int width, int height);
+
+  public abstract Shape getClip();
+
+  public abstract void setClip(Shape clip);
+
+  public abstract void copyArea(int x, int y, int width, int height,
+				int dx, int dy);
+
+  public abstract void drawLine(int x1, int y1, int x2, int y2);
+    
+  public abstract void fillRect(int x, int y, int width, int height);
+
+  public void drawRect(int x, int y, int width, int height)
+  {
+    int x1 = x;
+    int y1 = y;
+    int x2 = x + width;
+    int y2 = y + height;
+    drawLine(x1, y1, x2, y1);
+    drawLine(x2, y1, x2, y2);
+    drawLine(x2, y2, x1, y2);
+    drawLine(x1, y2, x1, y1);
+  }
+
+  public abstract void clearRect(int x, int y, int width, int height);
+  
+  public abstract void drawRoundRect(int x, int y, int width, int height,
+				     int arcWidth, int arcHeight);
+  
+  public abstract void fillRoundRect(int x, int y, int width, int height,
+				     int arcWidth, int arcHeight);
+  
+  public void draw3DRect(int x, int y, int width, int height,
+			 boolean raised)
+  {
+    Color color = getColor();
+    Color tl = color; // FIXME, make lighter
+    Color br = color; // FIXME, make darker
+    
+    if (!raised)
+      {
+	Color tmp = tl;
+	tl = br;
+	br = tmp;
+      }
+    
+    int x1 = x;
+    int y1 = y;
+    int x2 = x + width;
+    int y2 = y + height;
+    
+    setColor(tl);
+    drawLine(x1, y1, x2, y1);
+    drawLine(x1, y2, x1, y1);
+    setColor(br);
+    drawLine(x2, y1, x2, y2);
+    drawLine(x2, y1, x1, y2);
+    setColor(color);
+  }
+
+  public void fill3DRect(int x, int y, int width, int height,
+			 boolean raised)
   {
-    super();  // ???
-    throw new Error ("java.awt.Graphics: not implemented");
+    fillRect(x, y, width, height);
+    draw3DRect(x, y, width-1, height-1, raised);
+  }
+
+  public abstract void drawOval(int x, int y, int width, int height);
+  
+  public abstract void fillOval(int x, int y, int width, int height);
+  
+  public abstract void drawArc(int x, int y, int width, int height,
+			       int startAngle, int arcAngle);
+  
+  public abstract void fillArc(int x, int y, int width, int height,
+			       int startAngle, int arcAngle);
+  
+  public abstract void drawPolyline(int[] xPoints, int[] yPoints,
+				    int nPoints);
+  
+  public abstract void drawPolygon(int[] xPoints, int[] yPoints,
+				   int nPoints);
+  
+  //public void drawPolygon(Polygon p);
+    
+  public abstract void fillPolygon(int[] xPoints, int[] yPoints,
+				   int nPoints);
+
+  //public void fillPolygon(Polygon p);
+
+  public abstract void drawString(String str, int x, int y);
+
+  /*
+  public abstract void drawString(AttributedCharacterIterator iterator,
+	        		  int x, int y)
+  */
+
+  public void drawChars(char[] data, int offset, int length,
+			int x, int y)
+  {
+    String str = new String(data, offset, length);
+    drawString(str, x, y);
+  }
+
+  public void drawBytes(byte[] data, int offset, int length,
+			int x, int y)
+  {
+    String str = new String(data, offset, length);
+    drawString(str, x, y);
+  }
+
+  public abstract boolean drawImage(Image img, int x, int y,
+				    ImageObserver observer);
+
+  public abstract boolean drawImage(Image img, int x, int y,
+				    int width, int height,
+				    ImageObserver observer);
+
+  public abstract boolean drawImage(Image img, int x, int y, Color bgcolor,
+				    ImageObserver observer);
+  
+  public abstract boolean drawImage(Image img, int x, int y,
+				    int width, int height, Color bgcolor,
+				    ImageObserver observer);
+
+  public abstract boolean drawImage(Image img,
+				    int dx1, int dy1, int dx2, int dy2,
+				    int sx1, int sy1, int sx2, int sy2,
+				    ImageObserver observer);
+
+  public abstract boolean drawImage(Image img,
+				    int dx1, int dy1, int dx2, int dy2,
+				    int sx1, int sy1, int sx2, int sy2,
+				    Color bgcolor, ImageObserver observer);
+
+  public abstract void dispose();
+  
+  public void finalize()
+  {
+    dispose();
+  }
+
+  public String toString()
+  {
+    return super.toString(); // FIXME
+  }
+    
+  /** @deprecated */
+  public Rectangle getClipRect()
+  {
+    return getClipBounds(null);
+  }
+
+  public boolean hitClip(int x, int y, int width, int height)
+  {
+    throw new UnsupportedOperationException("not implemented yet");
+  }
+
+  public Rectangle getClipBounds(Rectangle r)
+  {
+    Rectangle clipBounds = getClipBounds();
+
+    if (r == null)
+      return clipBounds;
+
+    r.x      = clipBounds.x;
+    r.y      = clipBounds.y;
+    r.width  = clipBounds.width;
+    r.height = clipBounds.height;
+    return r;
   }
 }
Index: libjava/java/awt/Graphics2D.java
===================================================================
RCS file: Graphics2D.java
diff -N Graphics2D.java
--- /dev/null	Tue May  5 13:32:27 1998
+++ Graphics2D.java	Fri Aug 11 10:06:44 2000
@@ -0,0 +1,133 @@
+/* Copyright © 2000  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package java.awt;
+
+import java.awt.geom.AffineTransform;
+import java.awt.image.ImageObserver;
+
+//import java.util.Map;
+
+/**
+ * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
+ */
+public abstract class Graphics2D extends Graphics
+{
+
+  protected Graphics2D()
+  {
+  }
+  
+  public void draw3DRect(int x, int y, int width, int height,
+			 boolean raised)
+  {
+    super.draw3DRect(x, y, width, height, raised);
+  }
+  
+  public void fill3DRect(int x, int y, int width, int height,
+			 boolean raised)
+  {
+    super.fill3DRect(x, y, width, height, raised);
+  }
+
+  public abstract void draw(Shape shape);
+
+  public abstract boolean drawImage(Image image, AffineTransform xform,
+				    ImageObserver obs);
+
+  /*
+  public abstract void drawImage(BufferedImage image,
+				 BufferedImageOp op,
+				 int x,
+				 int y);
+  */
+
+  /*
+  public abstract void drawRenderedImage(RenderedImage image,
+					 AffineTransform xform);
+  */
+
+  /*
+  public abstract void drawRenderableImage(RenderableImage image,
+                                           AffineTransform xform);
+  */
+
+  public abstract void drawString(String text, int x, int y);
+
+  public abstract void drawString(String text, float x, float y);
+    
+  /*
+  public abstract void drawString(AttributedCharacterIterator iterator,
+                                  int x, int y);
+  */
+
+  /*
+  public abstract void drawString(AttributedCharacterIterator iterator,
+				  float x, float y);
+  */
+
+  /*
+  public abstract void drawGlyphVector(GlyphVector g, float x, float y);
+  */
+
+  public abstract void fill(Shape shape);
+    
+  public abstract boolean hit(Rectangle rect, Shape text,
+			      boolean onStroke);
+
+  public abstract GraphicsConfiguration getDeviceConfiguration();
+
+  //public abstract void setComposite(Composite comp);
+    
+  public abstract void setPaint(Paint paint);
+
+  //public abstract void setStroke(Stroke stroke)
+
+  public abstract void setRenderingHint(RenderingHints.Key hintKey,
+                                        Object hintValue);
+
+  public abstract Object getRenderingHint(RenderingHints.Key hintKey);
+  
+  //public abstract void setRenderingHints(Map hints);
+
+  //public abstract void addRenderingHints(Map hints);
+
+  public abstract RenderingHints getRenderingHints();
+
+  public abstract void translate(int x, int y);
+
+  public abstract void translate(double tx, double ty);
+    
+  public abstract void rotate(double theta);
+
+  public abstract void rotate(double theta, double x, double y);
+
+  public abstract void scale(double scaleX, double scaleY);
+
+  public abstract void shear(double shearX, double shearY);
+
+  public abstract void transform(AffineTransform Tx);
+  
+  public abstract void setTransform(AffineTransform Tx);
+
+  public abstract AffineTransform getTransform();
+
+  public abstract Paint getPaint();
+
+  //public abstract Composite getComposite();
+
+  public abstract void setBackground(Color color);
+
+  public abstract Color getBackground();
+
+  //public abstract Stroke getStroke();    
+
+  public abstract void clip(Shape s);
+
+  //public abstract FontRenderContext getFontRenderContext()
+}
Index: libjava/java/awt/GraphicsConfiguration.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/GraphicsConfiguration.java,v
retrieving revision 1.1
diff -u -r1.1 GraphicsConfiguration.java
--- GraphicsConfiguration.java	2000/07/12 03:32:06	1.1
+++ GraphicsConfiguration.java	2000/08/11 17:06:44
@@ -6,15 +6,21 @@
 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 details.  */
 
-/* Status: Complete, but commented out until we have the required Java2D
-   classes. */
+/* Status: Complete, but commented out until we have the required
+   GraphicsDevice. */
 
 package java.awt;
 
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.geom.AffineTransform;
+
 public abstract class GraphicsConfiguration
 {
   /*
   public abstract GraphicsDevice getDevice();
+  */
+
   public abstract BufferedImage createCompatibleImage(int width, int height);
   public abstract BufferedImage createCompatibleImage(int width, int height,
                                                       int transparency);
@@ -22,7 +28,7 @@
   public abstract ColorModel getColorModel(int transparency);
   public abstract AffineTransform getDefaultTransform();
   public abstract AffineTransform getNormalizingTransform();
-  */
+
   /* @since 1.3 */
   public abstract Rectangle getBounds();
 }
Index: libjava/java/awt/Image.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Image.java,v
retrieving revision 1.1
diff -u -r1.1 Image.java
--- Image.java	2000/03/17 00:45:06	1.1
+++ Image.java	2000/08/11 17:06:44
@@ -8,6 +8,9 @@
 
 package java.awt;
 
+import java.awt.image.ImageObserver;
+import java.awt.image.ImageProducer;
+
 /**
  * @author Warren Levy <warrenl@cygnus.com>
  * @date March 15, 2000.
@@ -16,14 +19,33 @@
 /**
  * Written using on-line Java Platform 1.2 API Specification, as well
  * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
- * Status:  Stubbed; A very incomplete placeholder.
+ * Status:  Mostly complete, but look for FIXMEs.
  */
 
 public abstract class Image extends Object
 {
-  public Image()
+  public static final Object UndefinedProperty;
+
+  public static final int SCALE_DEFAULT        =  1;
+  public static final int SCALE_FAST           =  2;
+  public static final int SCALE_SMOOTH         =  4;
+  public static final int SCALE_REPLICATE      =  8;
+  public static final int SCALE_AREA_AVERAGING = 16;
+
+  public abstract int getWidth(ImageObserver observer);
+
+  public abstract int getHeight(ImageObserver observer);
+
+  public abstract ImageProducer getSource();
+  
+  public abstract Graphics getGraphics();
+
+  public abstract Object getProperty(String name, ImageObserver observer);
+
+  public Image getScaledInstance(int width, int height, int hints)
   {
-    super();  // ???
-    throw new Error("java.awt.Image: not implemented");
+    throw new UnsupportedOperationException("FIXME: not implemented yet");
   }
+
+  public abstract void flush();
 }
Index: libjava/java/awt/Panel.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Panel.java,v
retrieving revision 1.1
diff -u -r1.1 Panel.java
--- Panel.java	2000/07/12 03:32:06	1.1
+++ Panel.java	2000/08/11 17:06:44
@@ -8,15 +8,20 @@
 
 package java.awt;
 
+import java.awt.peer.ComponentPeer;
+
 /* An incomplete placeholder. */
 
 public class Panel extends Container
 {
   public Panel()
-  {
-    super();
+  { 
+    this(
+	 // should be: new FlowLayout()
+	 null // FIXME
+	 );
   }
-  
+
   public Panel(LayoutManager layout)
   {
     super();
@@ -27,6 +32,8 @@
 
   public void addNotify()
   {
-    // FIXME
+    if (getPeer() == null)
+      peer = (ComponentPeer) getToolkit().createPanel(this);
+    super.addNotify();
   }
 }
Index: libjava/java/awt/Rectangle.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Rectangle.java,v
retrieving revision 1.5
diff -u -r1.5 Rectangle.java
--- Rectangle.java	2000/07/23 00:24:14	1.5
+++ Rectangle.java	2000/08/11 17:06:44
@@ -220,7 +220,7 @@
 
   public boolean isEmpty()
   {
-    return (width > 0 && height > 0);
+    return !(width > 0 && height > 0);
   }
 
   /** @deprecated Use setLocation() instead. */
Index: libjava/java/awt/RenderingHints.java
===================================================================
RCS file: RenderingHints.java
diff -N RenderingHints.java
--- /dev/null	Tue May  5 13:32:27 1998
+++ RenderingHints.java	Fri Aug 11 10:06:44 2000
@@ -0,0 +1,299 @@
+/* Copyright © 2000  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package java.awt;
+
+/**
+ * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
+ */
+public class RenderingHints implements
+    //java.util.Map,
+    Cloneable
+{
+
+  static abstract class Key
+  {
+    private int intKey;
+
+    protected Key(int privateKey)
+    {
+      intKey = privateKey;
+    }
+
+    public abstract boolean isCompatibleValue(Object value);
+    
+    protected final int intKey() 
+    {
+      return intKey;
+    }    
+
+    public final int hashCode() 
+    {
+      return System.identityHashCode(this);
+    }
+    
+    public final boolean equals(Object other) 
+    {
+      return (this == other);
+    }
+  }
+
+  private static class KeyImpl extends Key
+  {
+    String description;
+    Object v1, v2, v3;
+
+    KeyImpl(int privateKey, String description,
+	    Object v1, Object v2, Object v3)
+    {
+      super(privateKey);
+      this.description = description;
+      this.v1 = v1;
+      this.v2 = v2;
+      this.v3 = v3;
+    }
+    
+    public boolean isCompatibleValue(Object value) 
+    {
+      return (value == v1) || (value == v2) || (value == v3);
+    }
+
+    public String toString() 
+    {
+      return description;
+    }
+  }
+
+
+  //java.util.HashMap hintMap;
+
+  public static final Key KEY_ANTIALIASING;
+  public static final Object
+    VALUE_ANTIALIAS_ON = "Antialiased rendering mode",
+    VALUE_ANTIALIAS_DEFAULT = "Default antialiasing rendering mode";
+
+  static 
+  {
+    KEY_ANTIALIASING = new KeyImpl(1, "Global antialiasing enable key",
+				   VALUE_ANTIALIAS_ON,
+				   VALUE_ANTIALIAS_DEFAULT,
+				   VALUE_ANTIALIAS_DEFAULT);
+  }
+
+  public static final Key KEY_RENDERING;
+  public static final Object 
+    VALUE_RENDER_SPEED = "Fastest rendering methods",
+    VALUE_RENDER_QUALITY = "Highest quality rendering methods",
+    VALUE_RENDER_DEFAULT = "Default rendering methods";
+
+  static
+  {
+    KEY_RENDERING = new KeyImpl(2, "Global rendering quality key",
+				VALUE_RENDER_SPEED,
+				VALUE_RENDER_QUALITY,
+				VALUE_RENDER_DEFAULT);
+  }
+  
+  public static final Key KEY_DITHERING;
+  public static final Object
+    VALUE_DITHER_DISABLE = "Nondithered rendering mode",
+    VALUE_DITHER_ENABLE = "Dithered rendering mode",
+    VALUE_DITHER_DEFAULT = "Default dithering mode";
+
+  static
+  {
+    KEY_DITHERING = new KeyImpl(3, "Dithering quality key",
+				VALUE_DITHER_DISABLE,
+				VALUE_DITHER_ENABLE,
+				VALUE_DITHER_DEFAULT);
+  }
+  
+  public static final Key KEY_TEXT_ANTIALIASING;
+  public static final Object
+    VALUE_TEXT_ANTIALIAS_ON = "Antialiased text mode",
+    VALUE_TEXT_ANTIALIAS_OFF = "Nonantialiased text mode",
+    VALUE_TEXT_ANTIALIAS_DEFAULT = "Default antialiasing text mode";
+
+  static 
+  {
+    KEY_TEXT_ANTIALIASING = new KeyImpl(4, "Text-specific antialiasing enable key",
+					VALUE_TEXT_ANTIALIAS_ON,
+					VALUE_TEXT_ANTIALIAS_OFF,
+					VALUE_TEXT_ANTIALIAS_DEFAULT);
+  }
+  
+  public static final Key KEY_FRACTIONALMETRICS;
+  public static final Object
+    VALUE_FRACTIONALMETRICS_OFF = "Integer text metrics mode",
+    VALUE_FRACTIONALMETRICS_ON = "Fractional text metrics mode",
+    VALUE_FRACTIONALMETRICS_DEFAULT = "Default fractional text metrics mode";
+
+  static 
+  {
+    KEY_FRACTIONALMETRICS = new KeyImpl(5, "Fractional metrics enable key",
+					VALUE_FRACTIONALMETRICS_OFF,
+					VALUE_FRACTIONALMETRICS_ON,
+					VALUE_FRACTIONALMETRICS_DEFAULT);
+  }
+  
+  public static final Key KEY_INTERPOLATION;
+  public static final Object
+    VALUE_INTERPOLATION_NEAREST_NEIGHBOR = "Nearest Neighbor image interpolation mode",
+    VALUE_INTERPOLATION_BILINEAR = "Bilinear image interpolation mode",
+    VALUE_INTERPOLATION_BICUBIC = "Bicubic image interpolation mode";
+
+  static 
+  {
+    KEY_INTERPOLATION = new KeyImpl(6, "Image interpolation method key",
+				    VALUE_INTERPOLATION_NEAREST_NEIGHBOR,
+				    VALUE_INTERPOLATION_BILINEAR,
+				    VALUE_INTERPOLATION_BICUBIC);
+  }
+  
+  public static final Key KEY_ALPHA_INTERPOLATION;
+  public static final Object
+    VALUE_ALPHA_INTERPOLATION_SPEED = "Fastest alpha blending methods",
+    VALUE_ALPHA_INTERPOLATION_QUALITY = "Highest quality alpha blending methods",
+    VALUE_ALPHA_INTERPOLATION_DEFAULT = "Default alpha blending methods";
+
+  static
+  {
+    KEY_ALPHA_INTERPOLATION = new KeyImpl(7, "Alpha blending interpolation method key",
+					  VALUE_ALPHA_INTERPOLATION_SPEED,
+					  VALUE_ALPHA_INTERPOLATION_QUALITY,
+					  VALUE_ALPHA_INTERPOLATION_DEFAULT);
+  }
+  
+  public static final Key KEY_COLOR_RENDERING;
+  public static final Object
+    VALUE_COLOR_RENDER_SPEED = "Fastest color rendering mode",
+    VALUE_COLOR_RENDER_QUALITY = "Highest quality color rendering mode",
+    VALUE_COLOR_RENDER_DEFAULT = "Default color rendering mode";
+
+  static 
+  {
+    KEY_COLOR_RENDERING = new KeyImpl(8, "Color rendering quality key",
+				      VALUE_COLOR_RENDER_SPEED,
+				      VALUE_COLOR_RENDER_QUALITY,
+				      VALUE_COLOR_RENDER_DEFAULT);
+  }
+
+  public static final Key KEY_STROKE_CONTROL;
+  public static final Object
+    VALUE_STROKE_DEFAULT = "Default stroke control mode",
+    VALUE_STROKE_NORMALIZE = "Normalize stroke control mode",
+    VALUE_STROKE_PURE = "Pure stroke control mode";
+
+  static 
+  {
+    KEY_STROKE_CONTROL = new KeyImpl(9, "Stroke normalization control key",
+				     VALUE_STROKE_DEFAULT,
+				     VALUE_STROKE_NORMALIZE,
+				     VALUE_STROKE_PURE);
+  }
+  
+  //public RenderingHints(Map init);
+
+  public RenderingHints(Key key, Object value)
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+
+  public int size() 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  
+  public boolean isEmpty() 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+
+  public boolean containsKey(Object key) 
+  {      
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  
+  public boolean containsValue(Object value) 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  
+  public Object get(Object key)
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  
+  public Object put(Object key, Object value) 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  
+  public void add(RenderingHints hints) 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+
+  public void clear() 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  
+  public Object remove(Object key) 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  
+  /*
+  public void putAll(Map m) 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  */
+  
+  /*
+  public Set keySet() 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  */
+  
+  /*
+  public Collection values() 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  */
+  
+  /*
+  public Set entrySet() 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  */
+  
+  public boolean equals(Object o) 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  
+  public int hashCode() 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  
+  public Object clone() 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+  
+  public String toString() 
+  {
+    throw new UnsupportedOperationException("FIXME, not implemented yet");
+  }
+}
Index: libjava/java/awt/Toolkit.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Toolkit.java,v
retrieving revision 1.11
diff -u -r1.11 Toolkit.java
--- Toolkit.java	2000/08/09 13:01:43	1.11
+++ Toolkit.java	2000/08/11 17:06:44
@@ -14,6 +14,7 @@
 import java.awt.image.*;
 import java.awt.datatransfer.Clipboard;
 import java.util.Hashtable;
+import gnu.gcj.awt.GLightweightPeer;
 
 /* A very incomplete placeholder. */
 
@@ -28,7 +29,7 @@
   {
     if (defaultToolkit != null)
       return defaultToolkit;
-      
+    
     Class toolkit_class;
     String tk_class_name = System.getProperty("awt.toolkit");
     if (tk_class_name == null)
@@ -72,8 +73,7 @@
 
   protected LightweightPeer createComponent(Component target)
   {
-    // FIXME
-    return null;
+    return GLightweightPeer.INSTANCE;
   }
   
   /* @deprecated Use GraphicsEnvironment.getAllFonts() */
@@ -191,7 +191,7 @@
 
   public final EventQueue getSystemEventQueue()
   {
-      return systemEventQueue;
+      return getSystemEventQueueImpl();
   }
 
   protected abstract EventQueue getSystemEventQueueImpl();
Index: libjava/java/awt/Window.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/Window.java,v
retrieving revision 1.5
diff -u -r1.5 Window.java
--- Window.java	2000/08/09 13:01:43	1.5
+++ Window.java	2000/08/11 17:06:44
@@ -28,20 +28,47 @@
   private transient WindowListener windowListener;
   private transient GraphicsConfiguration graphicsConfiguration;
 
+  /** 
+   * This (package access) constructor is used by subclasses that want
+   * to build windows that do not have parents.  Eg. toplevel
+   * application frames.  Subclasses cannot call super(null), since
+   * null is an illegal argument.
+   */
+  Window()
+  {
+    setVisible(false);
+    setLayout((LayoutManager) new BorderLayout());
+  }
+
+  Window(GraphicsConfiguration gc)
+  {
+    this();
+    graphicsConfiguration = gc;
+  }
+    
   public Window(Frame owner)
   {
-    this (owner, null);
+    this((Window) owner);
   }
 
   /** @since 1.2 */
   public Window(Window owner)
   {
-    this (owner, null);
+    this();
+    if (owner == null)
+      throw new IllegalArgumentException("owner must not be null");
+    
+    this.parent = owner;
+
+    // FIXME: add to owner's "owned window" list
+    //owner.owned.add(this); // this should be a weak reference
   }
   
   /** @since 1.3 */
   public Window(Window owner, GraphicsConfiguration gc)
   {
+    this(owner);
+
     /*  FIXME: Security check
     SecurityManager.checkTopLevelWindow(...)
 
@@ -55,22 +82,20 @@
 			     .getDefaultConfiguration();
     else
     */    
-      graphicsConfiguration = gc;
+    graphicsConfiguration = gc;
+  }
 
-    // FIXME: compiler bug
-    // this.layoutMgr = new BorderLayout ();
-    
-    if (owner == null)
-      throw new IllegalArgumentException ("Owner can not be null");
-          
-    this.parent = owner;
-    
-    // FIXME: add to owner's "owned window" list
+  GraphicsConfiguration getGraphicsConfigurationImpl()
+  {
+    if (graphicsConfiguration != null) return graphicsConfiguration;
+
+    return super.getGraphicsConfigurationImpl();
   }
 
   protected void finalize() throws Throwable
   {
     // FIXME: remove from owner's "owned window" list (Weak References)
+    super.finalize();
   }
 
   public void addNotify()
@@ -78,6 +103,7 @@
     if (peer == null)
       // FIXME: This cast should NOT be required. ??? Compiler bug ???
       peer = (ComponentPeer) getToolkit ().createWindow (this);
+    super.addNotify ();
   }
 
   /** @specnote pack() doesn't appear to be called internally by show(), so
@@ -87,16 +113,19 @@
     if (parent != null
         && !parent.isDisplayable())
       parent.addNotify();
-        if (peer == null)
+    if (peer == null)
       addNotify();
-    
-    // FIXME: do layout stuff here
+
+    setSize(getPreferredSize());
     
     validate();
   }
 
   public void show ()
   {
+    if (peer == null) addNotify();
+    validate ();
+
     if (isVisible())
       {
 	this.toFront();
@@ -126,7 +155,13 @@
 
   public void dispose()
   {
-    // FIXME: first call removeNotify() on owned children
+    hide();
+
+    Window[] list = getOwnedWindows();
+    for (int i=0; i<list.length; i++) {
+      list[i].dispose();
+    }
+
     for (int i = 0; i < ncomponents; ++i)
       component[i].removeNotify();
     this.removeNotify();
@@ -195,10 +230,7 @@
 
   public Window getOwner()
   {
-    if (parent != null)
-      return (Window) parent;
-    else 
-      return null;
+    return (Window) parent;
   }
 
   /** @since 1.2 */
@@ -317,8 +349,16 @@
   }
   */
 
+  /** 
+   * Get graphics configuration.  The implementation for Window will
+   * not ask any parent containers, since Window is a toplevel
+   * window and not actually embedded in the parent component.
+   */
   public GraphicsConfiguration getGraphicsConfiguration()
   {
-    return graphicsConfiguration;
+    if (graphicsConfiguration != null) return graphicsConfiguration;
+    if (peer != null) return peer.getGraphicsConfiguration();
+    return null;
   }
+
 }
Index: libjava/java/awt/event/ActionEvent.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/event/ActionEvent.java,v
retrieving revision 1.5
diff -u -r1.5 ActionEvent.java
--- ActionEvent.java	2000/07/12 03:32:06	1.5
+++ ActionEvent.java	2000/08/11 17:06:44
@@ -37,7 +37,7 @@
     this.modifiers = modifiers;
   }
 
-  public String getcmd ()
+  public String getActionCommand ()
   {
     return cmd;
   }
Index: libjava/java/awt/image/BufferedImage.java
===================================================================
RCS file: BufferedImage.java
diff -N BufferedImage.java
--- /dev/null	Tue May  5 13:32:27 1998
+++ BufferedImage.java	Fri Aug 11 10:06:47 2000
@@ -0,0 +1,541 @@
+/* Copyright © 2000  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package java.awt.image;
+
+import java.awt.*;
+import java.awt.color.*;
+import java.util.*;
+
+import gnu.gcj.awt.ComponentDataBlitOp;
+
+/**
+ * A buffered image always starts at coordinates (0, 0).
+ *
+ * The buffered image is not subdivided into multiple tiles. Instead,
+ * the image consists of one large tile (0,0) with the width and
+ * height of the image. This tile is always considered to be checked
+ * out.
+ * 
+ * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
+ */
+public class BufferedImage extends java.awt.Image
+    //implements java.awt.image.WritableRenderedImage
+{
+  public static final int TYPE_CUSTOM         =  0;
+  public static final int TYPE_INT_RGB        =  1;
+  public static final int TYPE_INT_ARGB       =  2;
+  public static final int TYPE_INT_ARGB_PRE   =  3;
+  public static final int TYPE_INT_BGR        =  4;
+  public static final int TYPE_3BYTE_BGR      =  5;
+  public static final int TYPE_4BYTE_ABGR     =  6;
+  public static final int TYPE_4BYTE_ABGR_PRE =  7;
+  public static final int TYPE_USHORT_565_RGB =  8;
+  public static final int TYPE_USHORT_555_RGB =  9;
+  public static final int TYPE_BYTE_GRAY      = 10;
+  public static final int TYPE_USHORT_GRAY    = 11;
+  public static final int TYPE_BYTE_BINARY    = 12;
+  public static final int TYPE_BYTE_INDEXED   = 13;
+  
+  final static int[] bits3 = { 8, 8, 8 };
+  final static int[] bits4 = { 8, 8, 8 };
+  final static int[] bits1byte = { 8 };
+  final static int[] bits1ushort = { 16 };
+  
+  final static int[] masks_int = { 0x00ff0000,
+				   0x0000ff00,
+				   0x000000ff,
+				   DataBuffer.TYPE_INT };
+  final static int[] masks_565 = { 0xf800,
+				   0x07e0,
+				   0x001f,
+				   DataBuffer.TYPE_USHORT};
+  final static int[] masks_555 = { 0x7c00,
+				   0x03e0,
+				   0x001f,
+				   DataBuffer.TYPE_USHORT};
+  
+  public BufferedImage(int w, int h, int type)
+  {
+    ColorModel cm;
+    
+    boolean alpha = false;
+    boolean premultiplied = false;
+    switch (type)
+      {
+      case TYPE_4BYTE_ABGR_PRE:
+      case TYPE_INT_ARGB_PRE:
+	premultiplied = true;
+	// fall through
+      case TYPE_INT_ARGB:
+      case TYPE_4BYTE_ABGR:
+	alpha = true;
+      }
+	
+    ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+    switch (type)
+      {
+      case TYPE_INT_RGB:
+      case TYPE_INT_ARGB:
+      case TYPE_INT_ARGB_PRE:
+      case TYPE_USHORT_565_RGB:
+      case TYPE_USHORT_555_RGB:
+	int[] masks;
+	switch (type)
+	  {
+	  case TYPE_INT_RGB:
+	  case TYPE_INT_ARGB:
+	  case TYPE_INT_ARGB_PRE:
+	    masks = masks_int;
+	    break;
+	  case TYPE_USHORT_565_RGB:
+	    masks = masks_565;
+	    break;
+	  case TYPE_USHORT_555_RGB:
+	    masks = masks_555;
+	    break;
+	  }
+	
+	cm = new DirectColorModel(cs,
+				  32, // 32 bits in an int
+				  masks[0], // r
+				  masks[1], // g
+				  masks[2], // b
+				  alpha ? 0xff000000 : 0,
+				  premultiplied,
+				  masks[3] // data type
+				  );
+	break;
+	
+      case TYPE_INT_BGR:
+	String msg =
+	  "FIXME: Programmer is confused. Why (and how) does a " +
+	  "TYPE_INT_BGR image use ComponentColorModel to store " +
+	  "8-bit values? Is data type TYPE_INT or TYPE_BYTE. What " +
+	  "is the difference between TYPE_INT_BGR and TYPE_3BYTE_BGR?";
+	throw new UnsupportedOperationException(msg);
+	
+      case TYPE_3BYTE_BGR:
+      case TYPE_4BYTE_ABGR:
+      case TYPE_4BYTE_ABGR_PRE:
+      case TYPE_BYTE_GRAY:
+      case TYPE_USHORT_GRAY:
+	int[] bits = null;
+	int dataType = DataBuffer.TYPE_BYTE;
+	switch (type) {
+	case TYPE_3BYTE_BGR:
+	  bits = bits3;
+	  break;
+	case TYPE_4BYTE_ABGR:
+	case TYPE_4BYTE_ABGR_PRE:
+	  bits = bits4;
+	  break;
+	case TYPE_BYTE_GRAY:
+	  bits = bits1byte;
+	  break;
+	case TYPE_USHORT_GRAY:
+	  bits = bits1ushort;
+	  dataType = DataBuffer.TYPE_USHORT;
+	  break;
+	}
+	cm = new ComponentColorModel(cs, bits, alpha, premultiplied,
+				     alpha ?
+				     Transparency.TRANSLUCENT:
+				     Transparency.OPAQUE,
+				     dataType);
+	break;
+      case TYPE_BYTE_BINARY:
+	byte[] vals = { 0, (byte) 0xff };
+	cm = new IndexColorModel(8, 2, vals, vals, vals);
+	break;
+      case TYPE_BYTE_INDEXED:
+	String msg2 = "type not implemented yet";
+	throw new UnsupportedOperationException(msg2);
+	// FIXME: build color-cube and create color model
+      }
+    
+    init(cm,
+	 cm.createCompatibleWritableRaster(w, h),
+	 premultiplied,
+	 null, // no properties
+	 type
+	 );
+  }
+
+  public BufferedImage(int w, int h, int type,
+		       IndexColorModel indexcolormodel)
+  {
+    if ((type != TYPE_BYTE_BINARY) && (type != TYPE_BYTE_INDEXED))
+      throw new
+	IllegalArgumentException("type must be binary or indexed");
+    init(indexcolormodel,
+	 indexcolormodel.createCompatibleWritableRaster(w, h),
+	 false, // not premultiplied (guess)
+	 null, // no properties
+	 type);
+  }
+
+  public BufferedImage(ColorModel colormodel, 
+		       WritableRaster writableraster,
+		       boolean premultiplied,
+		       Hashtable properties)
+  {
+    init(colormodel, writableraster, premultiplied, properties,
+	 TYPE_CUSTOM);
+    // TODO: perhaps try to identify type?
+  }
+ 
+  WritableRaster raster;
+  ColorModel colorModel;
+  Hashtable properties;
+  boolean isPremultiplied;
+  int type;
+  
+  private void init(ColorModel cm,
+		    WritableRaster writableraster,
+		    boolean premultiplied,
+		    Hashtable properties,
+		    int type)
+  {
+    raster = writableraster;
+    colorModel = cm;
+    this.properties = properties;
+    isPremultiplied = premultiplied;
+    this.type = type;
+  }
+    
+  //public void addTileObserver(TileObserver tileobserver) {}
+  
+  public void coerceData(boolean premultiplied)
+  {
+    colorModel = colorModel.coerceData(raster, premultiplied);
+  }
+
+  public WritableRaster copyData(WritableRaster dest)
+  {
+    if (dest == null) dest = raster.createCompatibleWritableRaster();
+
+    int x = dest.getMinX();
+    int y = dest.getMinY();
+    int w = dest.getWidth();
+    int h = dest.getHeight();
+    
+    // create a src child that has the right bounds...
+    WritableRaster src =
+      raster.createWritableChild(x, y, w, h, x, y,
+				 null  // same bands
+				 );
+    
+    // Refer to ComponentDataBlitOp for optimized data blitting:
+    ComponentDataBlitOp.INSTANCE.filter(src, dest);
+    return dest;
+  }
+
+  public Graphics2D createGraphics()
+  {
+    throw new UnsupportedOperationException("not implemented");
+    // will require a lot of effort to implement
+  }
+
+  public void flush() {
+  }
+  
+  public WritableRaster getAlphaRaster()
+  {
+    return colorModel.getAlphaRaster(raster);
+  }
+  
+  public ColorModel getColorModel()
+  {
+    return colorModel;
+  }
+  
+  public Raster getData()
+  {
+    return copyData(null);
+    /* TODO: this might be optimized by returning the same
+       raster (not writable) as long as image data doesn't change. */
+  }
+
+  public Raster getData(Rectangle rectangle)
+  {
+    WritableRaster dest =
+      raster.createCompatibleWritableRaster(rectangle);
+    return copyData(dest);
+  }
+  
+  public Graphics getGraphics()
+  {
+    return createGraphics();
+  }
+
+  public int getHeight()
+  {
+    return raster.getHeight();
+  }
+  
+  public int getHeight(ImageObserver imageobserver)
+  {
+    return getHeight();
+  }
+    
+  public int getMinTileX()
+  {
+    return 0;
+  }
+  
+  public int getMinTileY()
+  {
+    return 0;
+  }
+
+  public int getMinX()
+  {
+    return 0; 
+  }
+
+  public int getMinY() 
+  {
+    return 0;
+  }
+  
+  public int getNumXTiles()
+  {
+    return 1;
+  }
+
+  public int getNumYTiles()
+  {
+	return 1;
+  }
+
+  public Object getProperty(String string)
+  {
+    if (properties == null) return null;
+    return properties.get(string);
+  }
+
+  public Object getProperty(String string, ImageObserver imageobserver)
+  {
+    return getProperty(string);
+  }
+
+  
+  public String[] getPropertyNames()
+  {
+    // FIXME: implement
+    return null;
+  }
+
+  public int getRGB(int x, int y)
+  {
+    Object rgbElem = raster.getDataElements(x, y,
+					    null // create as needed
+					    );
+    return colorModel.getRGB(rgbElem);
+  }
+    
+  public int[] getRGB(int startX, int startY, int w, int h,
+		      int[] rgbArray,
+		      int offset, int scanlineStride)
+  {
+    if (rgbArray == null)
+    {
+      /*
+	000000000000000000
+	00000[#######-----   [ = start
+	-----########-----   ] = end
+	-----#######]00000
+	000000000000000000  */
+      int size = (h-1)*scanlineStride + w;
+      rgbArray = new int[size];
+    }
+	
+    int endX = startX + w;
+    int endY = startY + h;
+    
+    /* *TODO*:
+       Opportunity for optimization by examining color models...
+       
+       Perhaps wrap the rgbArray up in a WritableRaster with packed
+       sRGB color model and perform optimized rendering into the
+       array. */
+
+    Object rgbElem = null;
+    for (int y=startY; y<endY; y++)
+      {
+	int xoffset = offset;
+	for (int x=startX; x<endX; x++)
+	  {
+	    int rgb;
+	    rgbElem = raster.getDataElements(x, y, rgbElem);
+	    rgb = colorModel.getRGB(rgbElem);
+	    rgbArray[xoffset++] = rgb;
+	  }
+	offset += scanlineStride;
+      }
+    return rgbArray;
+  }
+
+  public WritableRaster getRaster()
+  {
+    return raster;
+  }
+  
+  public SampleModel getSampleModel()
+  {
+    return raster.getSampleModel();
+  }
+    
+  public ImageProducer getSource()
+  {
+    throw new UnsupportedOperationException("not implemented");
+  }
+  
+  public Vector getSources()
+  {
+    return null;
+  }
+  
+  public BufferedImage getSubimage(int x, int y, int w, int h)
+  {
+    WritableRaster subRaster = 
+      getRaster().createWritableChild(x, y, w, h, 0, 0, null);
+    
+    return new BufferedImage(getColorModel(),
+			     subRaster,
+			     isPremultiplied,
+			     properties);
+  }
+
+  public Raster getTile(int tileX, int tileY)
+  {
+    return getWritableTile(tileX, tileY);
+  }
+    
+  public int getTileGridXOffset()
+  {
+    return 0; // according to javadocs
+  }
+
+  public int getTileGridYOffset()
+  {
+    return 0; // according to javadocs
+  }
+
+  public int getTileHeight()
+  {
+    return getHeight(); // image is one big tile
+  }
+
+  public int getTileWidth()
+  {
+    return getWidth(); // image is one big tile
+  }
+
+  public int getType()
+  {
+    return type;
+  }
+
+  public int getWidth()
+  {
+    return raster.getWidth();
+  }
+
+  public int getWidth(ImageObserver imageobserver)
+  {
+    return getWidth();
+  }
+
+  public WritableRaster getWritableTile(int tileX, int tileY)
+  {
+    isTileWritable(tileX, tileY);  // for exception
+    return raster;
+  }
+
+  private static final Point[] tileIndices = { new Point() };
+    
+  public Point[] getWritableTileIndices()
+  {
+    return tileIndices;
+  }
+
+  public boolean hasTileWriters()
+  {
+    return true;
+  }
+  
+  public boolean isAlphaPremultiplied()
+  {
+    return isPremultiplied;
+  }
+
+  public boolean isTileWritable(int tileX, int tileY)
+  {
+    if ((tileX != 0) || (tileY != 0))
+      throw new ArrayIndexOutOfBoundsException("only tile is (0,0)");
+    return true;
+  }
+
+  public void releaseWritableTile(int tileX, int tileY)
+  {
+    isTileWritable(tileX, tileY);  // for exception
+  }
+
+  //public void removeTileObserver(TileObserver tileobserver) {}
+
+  public void setData(Raster src)
+  {
+    int x = src.getMinX();
+    int y = src.getMinY();
+    int w = src.getWidth();
+    int h = src.getHeight();
+    
+    // create a dest child that has the right bounds...
+    WritableRaster dest =
+      raster.createWritableChild(x, y, w, h, x, y,
+				 null  // same bands
+				 );
+    
+    // Refer to ComponentDataBlitOp for optimized data blitting:
+    ComponentDataBlitOp.INSTANCE.filter(src, dest);
+  }
+
+  public void setRGB(int x, int y, int argb)
+  {
+    Object rgbElem = colorModel.getDataElements(argb, null);
+    raster.setDataElements(x, y, rgbElem);
+  }
+  
+  public void setRGB(int startX, int startY, int w, int h,
+		     int[] argbArray, int offset, int scanlineStride)
+  {
+    int endX = startX + w;
+    int endY = startY + h;
+    
+    Object rgbElem = null;
+    for (int y=startY; y<endY; y++)
+      {
+	int xoffset = offset;
+	for (int x=startX; x<endX; x++)
+	  {
+	    int argb = argbArray[xoffset++];
+	    rgbElem = colorModel.getDataElements(argb, rgbElem);
+	    raster.setDataElements(x, y, rgbElem);
+	  }
+	offset += scanlineStride;    
+      }
+  }
+    
+  public String toString()
+  {
+    // FIXME: implement:
+    return super.toString();
+  }
+}
Index: libjava/java/awt/image/RasterOp.java
===================================================================
RCS file: RasterOp.java
diff -N RasterOp.java
--- /dev/null	Tue May  5 13:32:27 1998
+++ RasterOp.java	Fri Aug 11 10:06:47 2000
@@ -0,0 +1,27 @@
+/* Copyright © 2000  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package java.awt.image;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.RenderingHints;
+
+public interface RasterOp {
+
+  WritableRaster filter(Raster src, WritableRaster dest);
+
+  Rectangle2D getBounds2D(Raster src);
+
+  WritableRaster createCompatibleDestRaster(Raster src);
+
+  Point2D getPoint2D(Point2D srcPoint, Point2D destPoint);
+
+  public RenderingHints getRenderingHints();
+}
+
Index: libjava/java/awt/peer/ComponentPeer.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/awt/peer/ComponentPeer.java,v
retrieving revision 1.4
diff -u -r1.4 ComponentPeer.java
--- ComponentPeer.java	2000/07/12 03:32:07	1.4
+++ ComponentPeer.java	2000/08/11 17:06:47
@@ -19,7 +19,13 @@
   void disable();
   void dispose();
   void enable();
-  ColorModel getColorModel();
+
+  /** 
+   * Get the graphics configuration of the component. The color model
+   * of the component can be derived from the configuration.
+   */
+  GraphicsConfiguration getGraphicsConfiguration();
+
   FontMetrics getFontMetrics(Font f);
   Graphics getGraphics();
   Point getLocationOnScreen();
@@ -41,6 +47,7 @@
   void setBounds(int x, int y, int width, int height);
   void setCursor(Cursor cursor);
   void setEnabled(boolean enabled);
+  void setEventMask(long eventMask);
   void setFont(Font font);
   void setForeground(Color color);
   void setVisible(boolean visible);



More information about the Java-patches mailing list