summaryrefslogtreecommitdiff
path: root/libjava/gnu/awt
diff options
context:
space:
mode:
authorrolfwr <rolfwr@138bc75d-0d04-0410-961f-82ee72b054a4>2000-10-22 17:46:09 +0000
committerrolfwr <rolfwr@138bc75d-0d04-0410-961f-82ee72b054a4>2000-10-22 17:46:09 +0000
commite2d342dffa63aea98643515fd3b8c782ee8bd15e (patch)
tree1165199489e8bc851f2bb5c11ff0228f3667453e /libjava/gnu/awt
parentcfed8d62a245d6113c86f79ffb2e4f09b2becc8d (diff)
downloadgcc-e2d342dffa63aea98643515fd3b8c782ee8bd15e.tar.gz
* Makefile.am: Added rules for libgcjx library.
* Makefile.in: Rebuilt. * configure.in: Added check for X. * configure: Rebuilt. * gnu/awt/LightweightRedirector.java: New file. * gnu/awt/j2d/AbstractGraphicsState.java: New file. * gnu/awt/j2d/DirectRasterGraphics.java: New file. * gnu/awt/j2d/Graphics2DImpl.java: New file. * gnu/awt/j2d/IntegerGraphicsState.java: New file. * gnu/awt/j2d/MappedRaster.java: New file. * gnu/awt/xlib/XCanvasPeer.java: New file. * gnu/awt/xlib/XEventLoop.java: New file. * gnu/awt/xlib/XEventQueue.java: New file. * gnu/awt/xlib/XFontMetrics.java: New file. * gnu/awt/xlib/XFramePeer.java: New file. * gnu/awt/xlib/XGraphics.java: New file. * gnu/awt/xlib/XGraphicsConfiguration.java: New file. * gnu/awt/xlib/XPanelPeer.java: New file. * gnu/awt/xlib/XToolkit.java: New file. * gnu/gcj/xlib/Clip.java: New file. * gnu/gcj/xlib/Colormap.java: New file. * gnu/gcj/xlib/Display.java: New file. * gnu/gcj/xlib/Drawable.java: New file. * gnu/gcj/xlib/Font.java: New file. * gnu/gcj/xlib/GC.java: New file. * gnu/gcj/xlib/Pixmap.java: New file. * gnu/gcj/xlib/Screen.java: New file. * gnu/gcj/xlib/Visual.java: New file. * gnu/gcj/xlib/WMSizeHints.java: New file. * gnu/gcj/xlib/Window.java: New file. * gnu/gcj/xlib/WindowAttributes.java: New file. * gnu/gcj/xlib/XAnyEvent.java: New file. * gnu/gcj/xlib/XButtonEvent.java: New file. * gnu/gcj/xlib/XColor.java: New file. * gnu/gcj/xlib/XConfigureEvent.java: New file. * gnu/gcj/xlib/XConnectException.java: New file. * gnu/gcj/xlib/XEvent.java: New file. * gnu/gcj/xlib/XException.java: New file. * gnu/gcj/xlib/XExposeEvent.java: New file. * gnu/gcj/xlib/XID.java: New file. * gnu/gcj/xlib/XImage.java: New file. * gnu/gcj/xlib/XUnmapEvent.java: New file. * gnu/gcj/xlib/natClip.cc: New file. * gnu/gcj/xlib/natColormap.cc: New file. * gnu/gcj/xlib/natDisplay.cc: New file. * gnu/gcj/xlib/natDrawable.cc: New file. * gnu/gcj/xlib/natFont.cc: New file. * gnu/gcj/xlib/natGC.cc: New file. * gnu/gcj/xlib/natPixmap.cc: New file. * gnu/gcj/xlib/natScreen.cc: New file. * gnu/gcj/xlib/natVisual.cc: New file. * gnu/gcj/xlib/natWMSizeHints.cc: New file. * gnu/gcj/xlib/natWindow.cc: New file. * gnu/gcj/xlib/natWindowAttributes.cc: New file. * gnu/gcj/xlib/natXAnyEvent.cc: New file. * gnu/gcj/xlib/natXButtonEvent.cc: New file. * gnu/gcj/xlib/natXColor.cc: New file. * gnu/gcj/xlib/natXConfigureEvent.cc: New file. * gnu/gcj/xlib/natXException.cc: New file. * gnu/gcj/xlib/natXExposeEvent.cc: New file. * gnu/gcj/xlib/natXImage.cc: New file. * gnu/gcj/xlib/natXUnmapEvent.cc: New file. * java/awt/EventDispatchThread.java: Start thead on creation. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@37005 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/gnu/awt')
-rw-r--r--libjava/gnu/awt/LightweightRedirector.java183
-rw-r--r--libjava/gnu/awt/j2d/AbstractGraphicsState.java128
-rw-r--r--libjava/gnu/awt/j2d/DirectRasterGraphics.java82
-rw-r--r--libjava/gnu/awt/j2d/Graphics2DImpl.java454
-rw-r--r--libjava/gnu/awt/j2d/IntegerGraphicsState.java409
-rw-r--r--libjava/gnu/awt/j2d/MappedRaster.java72
-rw-r--r--libjava/gnu/awt/xlib/XCanvasPeer.java388
-rw-r--r--libjava/gnu/awt/xlib/XEventLoop.java268
-rw-r--r--libjava/gnu/awt/xlib/XEventQueue.java34
-rw-r--r--libjava/gnu/awt/xlib/XFontMetrics.java47
-rw-r--r--libjava/gnu/awt/xlib/XFramePeer.java174
-rw-r--r--libjava/gnu/awt/xlib/XGraphics.java279
-rw-r--r--libjava/gnu/awt/xlib/XGraphicsConfiguration.java367
-rw-r--r--libjava/gnu/awt/xlib/XPanelPeer.java52
-rw-r--r--libjava/gnu/awt/xlib/XToolkit.java333
15 files changed, 3270 insertions, 0 deletions
diff --git a/libjava/gnu/awt/LightweightRedirector.java b/libjava/gnu/awt/LightweightRedirector.java
new file mode 100644
index 00000000000..a0ea7bcff4b
--- /dev/null
+++ b/libjava/gnu/awt/LightweightRedirector.java
@@ -0,0 +1,183 @@
+/* Copyright (C) 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.awt;
+
+import java.awt.AWTEvent;
+import java.awt.AWTError;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.event.MouseEvent;
+import java.awt.event.InputEvent;
+
+/**
+ * Encapsulates the logic required to dispatch events to the correct
+ * component in a component tree that may contain lightweight
+ * components. Toolkits typically only identify heavyweight components
+ * as the source of events. This class redirects the events to the
+ * appropriate lightweight children of the heavyweight component.
+ */
+public class LightweightRedirector
+{
+ final static int LAST_BUTTON_NUMBER = 3;
+
+ /* We sacrifice one array element to allow the button number to
+ match the index of this array. */
+ Component[] releaseTargets = new Component[LAST_BUTTON_NUMBER+1];
+
+ /**
+ *
+ * Modifies or replaces the given event with an event that has been
+ * properly redirected. State of button presses are kept so that
+ * button releases can be redirected to the same component as the
+ * button press. It is required that all events are sent through
+ * this method in chronological order.
+ */
+ public AWTEvent redirect(AWTEvent event)
+ {
+ if (event instanceof MouseEvent)
+ return redirectMouse((MouseEvent) event);
+
+ /* In case we don't know how to redirect the event, simply return
+ the event unchanged. */
+ return event;
+ }
+
+ MouseEvent redirectMouse(MouseEvent event)
+ {
+ int button = getButtonNumber(event);
+ int id = event.getID();
+
+ Component heavySource = (Component) event.getSource();
+ Component source = heavySource;
+ int x = event.getX();
+ int y = event.getY();
+
+ if (id == MouseEvent.MOUSE_RELEASED)
+ {
+ Component target = releaseTargets[button];
+
+ if (target != null)
+ {
+ releaseTargets[button] = null;
+ source = target;
+
+ Component child = source;
+ while (child != heavySource)
+ {
+ x -= child.getX();
+ y -= child.getY();
+ child = child.getParent();
+ if (child == null)
+ System.err.println("warning, orphaned release target");
+ }
+ }
+ }
+ else
+ {
+ /* Find real component, and adjust source, x and y
+ accordingly. */
+
+ while (true)
+ {
+ Component parent = source;
+
+ Component child = parent.getComponentAt(x, y);
+
+ if (parent == child)
+ break;
+
+ // maybe ignoring would be better?
+ if (child == null)
+ {
+ String msg = "delivered event not within component. " +
+ "Heavyweight source was " + heavySource + ". " +
+ "Component was " + parent;
+ throw new AWTError(msg);
+ }
+ if (child.isLightweight())
+ {
+ // descend down to child
+ source = child;
+ x -= child.getX();
+ y -= child.getY();
+ }
+ else
+ {
+ System.err.println("warning: event delivered to wrong " +
+ "heavyweight component. Was " +
+ "delivered to " + source + ". " +
+ "Should have been delivered to " +
+ child + ". Maybe the native window " +
+ "system is bubbling events up the " +
+ "containment hierarchy.");
+ break;
+ }
+ }
+
+ /* ensure that the release event is delivered to the same
+ component as the press event. For most toolkits this is
+ only necessary for lightweight components, since the
+ underlying windowing system takes care of its heavyweight
+ components. */
+ if (id == MouseEvent.MOUSE_PRESSED)
+ releaseTargets[button] = source;
+ }
+
+
+ if (source == heavySource)
+ return event; // no change in event
+
+ // print warning for heavyweights
+ /* this warning can safely be removed if a toolkit that
+ needs heavyweight redirection support is ever created. */
+ if (!source.isLightweight())
+ System.err.println("warning: redirecting to heavyweight");
+
+ MouseEvent redirected = new MouseEvent(source, event.getID(),
+ event.getWhen(),
+ event.getModifiers(),
+ x, y,
+ event.getClickCount(),
+ event.isPopupTrigger());
+
+ return redirected;
+ }
+
+ /**
+ * Identifies the button number for an input event.
+ *
+ * @returns the button number, or 0 if no button modifier was set
+ * for the event.
+ */
+ int getButtonNumber(InputEvent event)
+ {
+ int modifiers = event.getModifiers();
+
+ modifiers &=
+ InputEvent.BUTTON1_MASK |
+ InputEvent.BUTTON2_MASK |
+ InputEvent.BUTTON3_MASK;
+
+ switch (modifiers)
+ {
+ case InputEvent.BUTTON1_MASK:
+ return 1;
+ case InputEvent.BUTTON2_MASK:
+ return 2;
+ case InputEvent.BUTTON3_MASK:
+ return 3;
+ case 0:
+ return 0;
+
+ default:
+ System.err.println("FIXME: multibutton event");
+ return 0;
+ }
+ }
+}
diff --git a/libjava/gnu/awt/j2d/AbstractGraphicsState.java b/libjava/gnu/awt/j2d/AbstractGraphicsState.java
new file mode 100644
index 00000000000..e3b3ec61599
--- /dev/null
+++ b/libjava/gnu/awt/j2d/AbstractGraphicsState.java
@@ -0,0 +1,128 @@
+/* Copyright (C) 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.awt.j2d;
+
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.Shape;
+import java.awt.Rectangle;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.image.ImageObserver;
+
+/**
+ * Base class for graphics state objects (State pattern, GOF book)
+ * that represents the current pipeline configuration. The Graphics2D
+ * object forwards most of the requests to the state object. The
+ * Graphics2D object itself only administers properties that are not
+ * specific for a certain state.
+ */
+public abstract class AbstractGraphicsState implements Cloneable
+{
+ Graphics2DImpl frontend;
+
+ public void setFrontend(Graphics2DImpl frontend)
+ {
+ this.frontend = frontend;
+ }
+
+ public void dispose()
+ {
+ frontend = null;
+ }
+
+ // -------- Graphics methods:
+
+ public abstract void setColor(Color color);
+
+ public abstract void setPaintMode();
+
+ public abstract void setXORMode(Color altColor);
+
+ public abstract void setFont(Font font);
+
+ public abstract FontMetrics getFontMetrics(Font font);
+
+ public abstract void setClip(Shape clip);
+
+ public abstract Shape getClip();
+ public abstract Rectangle getClipBounds();
+
+ 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 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 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 abstract void fillPolygon(int[] xPoints, int[] yPoints, int nPoints);
+
+ public abstract boolean drawImage(Image image, int x, int y,
+ ImageObserver observer);
+
+
+ // -------- Graphics2D methods:
+
+ public abstract void draw(Shape shape);
+
+ public abstract void fill(Shape shape);
+
+ public abstract boolean hit(Rectangle rect, Shape text, boolean onStroke);
+
+ public abstract void drawString(String text, int x, int y);
+
+ public abstract void drawString(String text, float x, float y);
+
+ 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);
+}
diff --git a/libjava/gnu/awt/j2d/DirectRasterGraphics.java b/libjava/gnu/awt/j2d/DirectRasterGraphics.java
new file mode 100644
index 00000000000..6bbdbd1d23e
--- /dev/null
+++ b/libjava/gnu/awt/j2d/DirectRasterGraphics.java
@@ -0,0 +1,82 @@
+/* Copyright (C) 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.awt.j2d;
+
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.Shape;
+import java.awt.Rectangle;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.image.Raster;
+import java.awt.image.ImageObserver;
+
+/**
+ * Interface for a simple pixel based backend graphics object that
+ * does not handle translation/transforms, curves, nor advanced
+ * compositing.
+ */
+public interface DirectRasterGraphics extends Cloneable
+{
+ public void dispose();
+
+ public void setColor(Color color);
+
+ public void setPaintMode();
+
+ public void setXORMode(Color altColor);
+
+ public void setFont(Font font);
+
+ public FontMetrics getFontMetrics(Font font);
+
+ // supports rects, multi-rects and polygons
+ public void setClip(Shape clip);
+
+ public void copyArea(int x, int y, int width, int height,
+ int dx, int dy);
+
+ public void drawLine(int x1, int y1, int x2, int y2);
+
+ public void drawRect(int x, int y, int width, int height);
+
+ public void fillRect(int x, int y, int width, int height);
+
+ public void drawArc(int x, int y, int width, int height,
+ int startAngle, int arcAngle);
+
+ public void fillArc(int x, int y, int width, int height,
+ int startAngle, int arcAngle);
+
+ public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints);
+
+ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints);
+
+ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints);
+
+ public void drawString(String str, int x, int y);
+
+ public boolean drawImage(Image image, int x, int y,
+ ImageObserver observer);
+
+ /**
+ * Map the data for screen pixels in the requested bounds to a
+ * raster object. This gives read/write access to the screen
+ * pixels, allowing neat alpha and composite tricks.
+ */
+ public MappedRaster mapRaster(Rectangle bounds);
+
+ /**
+ * Detach previously mapped pixel data from a raster object.
+ */
+ public void unmapRaster(MappedRaster mappedRaster);
+}
diff --git a/libjava/gnu/awt/j2d/Graphics2DImpl.java b/libjava/gnu/awt/j2d/Graphics2DImpl.java
new file mode 100644
index 00000000000..7c08295c027
--- /dev/null
+++ b/libjava/gnu/awt/j2d/Graphics2DImpl.java
@@ -0,0 +1,454 @@
+/* Copyright (C) 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.awt.j2d;
+
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.Shape;
+import java.awt.Rectangle;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Paint;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.image.ImageObserver;
+
+/**
+ * Delegates almost all work to a state object, that allows us to
+ * hot-swap rendering strategies based on state changes inflicted on
+ * this Graphics object. This class keeps track of properties that are
+ * not affected by the state, (such as clip shape,
+ * foreground/background color, font, etc.).
+ *
+ * <p>The far front-end of the rendering pipeline consists of the
+ * Graphics2D API. In the far back-end, lies the native graphics
+ * libraries. In most cases the native graphics libraries only have
+ * direct support for a subset of the properties of Graphics2D. To
+ * make up missing features in the native graphics libraries, the
+ * pipeline between the front-end and the back-end need to translate
+ * drawing request to primitive operations that are supported by the
+ * back-end. E.g. for X11, drawing a straight line will translate to
+ * an XDrawLine, drawing a bezier curve will trigger flattening of the
+ * curve and will result in a call to XDrawLines.
+ *
+ * <p>This is the basic strategy for the rendering pipeline: Whenever
+ * a graphics property change occurs, that causes the current pipeline
+ * to be insufficient, amend or replace parts of the pipeline so that
+ * the pipeline will once again be able to translate requests to the
+ * set of primitives supported by the native graphics library.
+ *
+ * <p>Most graphics libraries share common subsets of
+ * functionality. To be able to reuse pieces of the rendering pipeline
+ * for several backends, we define interfaces that describe subsets of
+ * characteristics supported by the backends. A wrapper for the native
+ * library can implement several interfaces to describe its range of
+ * functionality.
+ *
+ * <p>Typically, most painting is done with a graphics object with
+ * simple properties. Unless one is using a complex Look & Feel, the
+ * painting of Swing components will never require affine transforms,
+ * alpha blending, non-rectangular clipping, etc. When graphics
+ * objects are created, they start off in a state where all the
+ * properties are simple. Most graphics objects experience only
+ * trivial property changes, and never leave this simple state. It is
+ * therefore wise to ensure that the rendering pipeline for this
+ * initial state is lean and as much as possible plugs directly into
+ * the backend.
+ *
+ * <p>The initial state for graphics object of most raster displays
+ * would call for two levels of indirection:
+ *
+ * <pre>
+ * Graphics2D object ---> IntegerGraphicsState ---> DirectRasterGraphics
+ * </pre>
+ */
+public class Graphics2DImpl extends Graphics2D implements Cloneable
+{
+ GraphicsConfiguration config;
+
+ AbstractGraphicsState state;
+
+ Color fg;
+ Color bg;
+
+ Font font;
+
+ public Graphics2DImpl(GraphicsConfiguration config)
+ {
+ this.config = config;
+ }
+
+ public void setState(AbstractGraphicsState state)
+ {
+ this.state = state;
+ this.state.setFrontend(this);
+ }
+
+ public Object clone()
+ {
+ Graphics2DImpl gfxCopy = (Graphics2DImpl) super.clone();
+ AbstractGraphicsState stateCopy =
+ (AbstractGraphicsState) state.clone();
+ gfxCopy.setState(stateCopy);
+
+ return gfxCopy;
+ }
+
+
+ // -------- Graphics methods:
+
+ public Graphics create()
+ {
+ Graphics2DImpl gfxCopy = (Graphics2DImpl) clone();
+ return gfxCopy;
+ }
+
+ public Color getColor()
+ {
+ return fg;
+ }
+
+ public void setColor(Color color)
+ {
+ fg = color;
+ state.setColor(color);
+ }
+
+ public void setPaintMode()
+ {
+ state.setPaintMode();
+ }
+
+ public void setXORMode(Color altColor)
+ {
+ state.setXORMode(altColor);
+ }
+
+ public Font getFont()
+ {
+ return font;
+ }
+
+ public void setFont(Font font)
+ {
+ this.font = font;
+ state.setFont(font);
+ }
+
+ public FontMetrics getFontMetrics(Font font)
+ {
+ return state.getFontMetrics(font);
+ }
+
+ public Rectangle getClipBounds()
+ {
+ return state.getClipBounds();
+ }
+
+ public void clipRect(int x, int y, int width, int height)
+ {
+ Shape clip = state.getClip();
+ if (clip instanceof Rectangle)
+ {
+ Rectangle clipRect = (Rectangle) clip;
+ clip = clipRect.intersection(new Rectangle(x, y, width, height));
+ setClip(clip);
+ return;
+ }
+
+ String msg =
+ "intersecting current clip shape " + clip + " with new rectangle " +
+ "has not been implemented yet";
+ throw new UnsupportedOperationException(msg);
+ }
+
+ public void setClip(int x, int y, int width, int height)
+ {
+ Rectangle clip = new Rectangle(x, y, width, height);
+ setClip(clip);
+ }
+
+ public Shape getClip()
+ {
+ return state.getClip();
+ }
+
+ public void setClip(Shape clip)
+ {
+ state.setClip(clip);
+ }
+
+ public void copyArea(int x, int y, int width, int height,
+ int dx, int dy)
+ {
+ state.copyArea(x, y, width, height, dx, dy);
+ }
+
+ public void drawLine(int x1, int y1, int x2, int y2)
+ {
+ state.drawLine(x1, y1, x2, y2);
+ }
+
+ public void fillRect(int x, int y, int width, int height)
+ {
+ state.fillRect(x, y, width, height);
+ }
+
+ public void clearRect(int x, int y, int width, int height)
+ {
+ state.clearRect(x, y, width, height);
+ }
+
+ public void drawRoundRect(int x, int y, int width, int height,
+ int arcWidth, int arcHeight)
+ {
+ state.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
+ }
+
+ public void fillRoundRect(int x, int y, int width, int height,
+ int arcWidth, int arcHeight)
+ {
+ state.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
+ }
+
+ public void drawOval(int x, int y, int width, int height)
+ {
+ state.drawOval(x, y, width, height);
+ }
+
+ public void fillOval(int x, int y, int width, int height)
+ {
+ state.fillOval(x, y, width, height);
+ }
+
+ public void drawArc(int x, int y, int width, int height,
+ int startAngle, int arcAngle)
+ {
+ state.drawArc(x, y, width, height, startAngle, arcAngle);
+ }
+
+ public void fillArc(int x, int y, int width, int height,
+ int startAngle, int arcAngle)
+ {
+ state.fillArc(x, y, width, height, startAngle, arcAngle);
+ }
+
+ public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ state.drawPolyline(xPoints, yPoints, nPoints);
+ }
+
+ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ state.drawPolygon(xPoints, yPoints, nPoints);
+ }
+
+ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ state.fillPolygon(xPoints, yPoints, nPoints);
+ }
+
+ public boolean drawImage(Image image, int x, int y,
+ ImageObserver observer)
+ {
+ return state.drawImage(image, x, y, observer);
+ }
+
+ public boolean drawImage(Image img, int x, int y,
+ int width, int height,
+ ImageObserver observer)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public boolean drawImage(Image img, int x, int y, Color bgcolor,
+ ImageObserver observer)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public boolean drawImage(Image img, int x, int y,
+ int width, int height, Color bgcolor,
+ ImageObserver observer)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public boolean drawImage(Image img,
+ int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2,
+ ImageObserver observer)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public boolean drawImage(Image img,
+ int dx1, int dy1, int dx2, int dy2,
+ int sx1, int sy1, int sx2, int sy2,
+ Color bgcolor, ImageObserver observer)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void dispose()
+ {
+ AbstractGraphicsState lState = state;
+
+ state = null;
+ config = null;
+ font = null;
+ fg = null;
+ bg = null;
+
+ if (lState != null)
+ lState.dispose();
+ }
+
+
+
+ // -------- Graphics2D methods:
+
+ public void draw(Shape shape)
+ {
+ state.draw(shape);
+ }
+
+ public boolean drawImage(Image image, AffineTransform xform,
+ ImageObserver obs)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+
+ public void drawString(String text, int x, int y)
+ {
+ state.drawString(text, x, y);
+ }
+
+ public void drawString(String text, float x, float y)
+ {
+ state.drawString(text, x, y);
+ }
+
+ public void fill(Shape shape)
+ {
+ state.fill(shape);
+ }
+
+ public boolean hit(Rectangle rect, Shape text, boolean onStroke)
+ {
+ return state.hit(rect, text, onStroke);
+ }
+
+ public GraphicsConfiguration getDeviceConfiguration()
+ {
+ return config;
+ }
+
+ public void setPaint(Paint paint)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void setRenderingHint(RenderingHints.Key hintKey,
+ Object hintValue)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public Object getRenderingHint(RenderingHints.Key hintKey)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public RenderingHints getRenderingHints()
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void translate(int x, int y)
+ {
+ state.translate(x, y);
+ }
+
+ public void translate(double tx, double ty)
+ {
+ state.translate(tx, ty);
+ }
+
+ public void rotate(double theta)
+ {
+ state.rotate(theta);
+ }
+
+ public void rotate(double theta, double x, double y)
+ {
+ state.rotate(theta, x, y);
+ }
+
+ public void scale(double scaleX, double scaleY)
+ {
+ state.scale(scaleX, scaleY);
+ }
+
+ public void shear(double shearX, double shearY)
+ {
+ state.shear(shearX, shearY);
+ }
+
+ public void transform(AffineTransform Tx)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void setTransform(AffineTransform Tx)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public AffineTransform getTransform()
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public Paint getPaint()
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void setBackground(Color color)
+ {
+ bg = color;
+ }
+
+ public Color getBackground()
+ {
+ return bg;
+ }
+
+ public void clip(Shape shape)
+ {
+ Shape clip = state.getClip();
+
+ if ((shape instanceof Rectangle) && (clip instanceof Rectangle))
+ {
+ clip = ((Rectangle) clip).intersection((Rectangle) shape);
+ state.setClip(clip);
+ return;
+ }
+
+ String msg =
+ "intersecting current clip shape " + clip + " with new shape " + shape +
+ "has not been implemented yet";
+ throw new UnsupportedOperationException(msg);
+ }
+}
diff --git a/libjava/gnu/awt/j2d/IntegerGraphicsState.java b/libjava/gnu/awt/j2d/IntegerGraphicsState.java
new file mode 100644
index 00000000000..923720e06ae
--- /dev/null
+++ b/libjava/gnu/awt/j2d/IntegerGraphicsState.java
@@ -0,0 +1,409 @@
+/* Copyright (C) 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.awt.j2d;
+
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.Shape;
+import java.awt.Rectangle;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.awt.image.ColorModel;
+
+/**
+ * IntegerGraphicsState is one of several graphics state
+ * implementations. This graphics state is used when the graphics
+ * object has simple properties, (coordinate translation only, no
+ * transform) and the backend supports integer coordinates (pixel
+ * based). For primitive paint operations, this object translates the
+ * coordinates and forwards the request to the backend. For requests
+ * to draw arbitrary shapes and paths, this object translates the
+ * requests to primitive drawing operations supported by the
+ * backend. IntegerGraphicsState is meant to support the most common
+ * state of an graphics object. The degree of functionality is roughly
+ * equivalent with the old java.awt.Graphics API.
+ */
+public class IntegerGraphicsState extends AbstractGraphicsState
+{
+ int tx;
+ int ty;
+
+ DirectRasterGraphics directGfx;
+ Shape clip;
+
+ public IntegerGraphicsState(DirectRasterGraphics directGfx)
+ {
+ this.directGfx = directGfx;
+ }
+
+ public Object clone()
+ {
+ IntegerGraphicsState clone = (IntegerGraphicsState) super.clone();
+ clone.directGfx = (DirectRasterGraphics) directGfx.clone();
+
+ return clone;
+ }
+
+ public void dispose()
+ {
+ DirectRasterGraphics lDeviceGfx = directGfx;
+
+ directGfx = null;
+
+ if (lDeviceGfx != null)
+ lDeviceGfx.dispose();
+
+ super.dispose();
+ }
+
+
+ // -------- Graphics methods:
+
+ public void setColor(Color color)
+ {
+ directGfx.setColor(color);
+ }
+
+ public void setPaintMode()
+ {
+ directGfx.setPaintMode();
+ }
+
+ public void setXORMode(Color altColor)
+ {
+ directGfx.setXORMode(altColor);
+ }
+
+ public void setFont(Font font)
+ {
+ directGfx.setFont(font);
+ }
+
+ public FontMetrics getFontMetrics(Font font)
+ {
+ return directGfx.getFontMetrics(font);
+ }
+
+ public void setClip(Shape clip)
+ {
+ if (clip instanceof Rectangle)
+ {
+ Rectangle clipRect = (Rectangle) clip.clone();
+ clipRect.x += tx;
+ clipRect.y += ty;
+
+ this.clip = clipRect;
+
+ directGfx.setClip(clipRect);
+ return;
+ }
+
+ String msg =
+ "translating clip shape " + clip + " into device " +
+ "coordinate space has not been implemented yet";
+
+ throw new UnsupportedOperationException(msg);
+ }
+
+ public Shape getClip()
+ {
+ if (clip instanceof Rectangle)
+ {
+ Rectangle clipRect = (Rectangle) clip;
+ clipRect.x -= tx;
+ clipRect.y -= ty;
+ return clipRect;
+ }
+
+ String msg =
+ "translating clip shape " + clip + " into user " +
+ "coordinate space has not been implemented yet";
+
+ throw new UnsupportedOperationException(msg);
+ }
+
+ public Rectangle getClipBounds()
+ {
+ Rectangle clipRect = clip.getBounds();
+
+ clipRect.x -= tx;
+ clipRect.y -= ty;
+ return clipRect;
+ }
+
+ public void copyArea(int x, int y,
+ int width, int height,
+ int dx, int dy)
+ {
+ directGfx.copyArea(x+tx, y+ty, width, height, dx, dy);
+ }
+
+ public void drawLine(int x1, int y1,
+ int x2, int y2)
+ {
+ directGfx.drawLine(x1+tx, y1+ty, x2+tx, y2+ty);
+ }
+
+ public void fillRect(int x, int y,
+ int width, int height)
+ {
+ directGfx.fillRect(x+tx, y+ty, width, height);
+ }
+
+ public void clearRect(int x, int y,
+ int width, int height)
+ {
+ directGfx.setColor(frontend.getBackground());
+ directGfx.fillRect(x+tx, y+ty, width, height);
+ directGfx.setColor(frontend.getColor());
+ }
+
+ public void drawRoundRect(int x, int y,
+ int width, int height,
+ int arcWidth, int arcHeight)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void fillRoundRect(int x, int y,
+ int width, int height,
+ int arcWidth, int arcHeight)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void drawOval(int x, int y,
+ int width, int height)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void fillOval(int x, int y,
+ int width, int height)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void drawArc(int x, int y,
+ int width, int height,
+ int startAngle, int arcAngle)
+ {
+ directGfx.drawArc(x+tx, y+ty, width, height, startAngle, arcAngle);
+ }
+
+ public void fillArc(int x, int y,
+ int width, int height,
+ int startAngle, int arcAngle)
+ {
+ directGfx.fillArc(x+tx, y+ty, width, height, startAngle, arcAngle);
+ }
+
+ public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ if ((tx == 0) || (ty == 0))
+ {
+ directGfx.drawPolyline(xPoints, yPoints, nPoints);
+ return;
+ }
+
+ throw new UnsupportedOperationException("translate not implemented");
+ }
+
+ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ if ((tx == 0) || (ty == 0))
+ {
+ directGfx.drawPolygon(xPoints, yPoints, nPoints);
+ return;
+ }
+
+ throw new UnsupportedOperationException("translate not implemented");
+ }
+
+ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
+ {
+ if ((tx == 0) || (ty == 0))
+ {
+ directGfx.fillPolygon(xPoints, yPoints, nPoints);
+ return;
+ }
+
+ throw new UnsupportedOperationException("translate not implemented");
+ }
+
+ public boolean drawImage(Image image, int x, int y,
+ ImageObserver observer)
+ {
+ x += tx;
+ y += ty;
+
+ if (image instanceof BufferedImage)
+ {
+ BufferedImage bImage = (BufferedImage) image;
+ Object config =
+ bImage.getProperty("java.awt.GraphicsConfiguration");
+
+ if (config == frontend.config)
+ return directGfx.drawImage(image, x, y, observer);
+
+ int width = image.getWidth(null);
+ int height = image.getHeight(null);
+
+ Rectangle bounds = new Rectangle(x, y, width, height);
+
+ MappedRaster mr = directGfx.mapRaster(bounds);
+
+ // manipulate raster here...
+ ColorModel colorModel = mr.getColorModel();
+ WritableRaster raster = mr.getRaster();
+
+ int xEnd = x + width;
+ int yEnd = y + height;
+
+ // FIXME: Use the following code only as a fallback. It's SLOW!
+
+ Object rgbElem = null;
+ for (int yy=0; yy<height; yy++)
+ {
+ for (int xx=0; xx<width; xx++)
+ {
+ int srgb = bImage.getRGB(xx, yy);
+ int sa = ((srgb >>> 24) & 0xff) + 1;
+ int sr = ((srgb >>> 16) & 0xff) + 1;
+ int sg = ((srgb >>> 8) & 0xff) + 1;
+ int sb = (srgb & 0xff) + 1;
+
+ rgbElem = raster.getDataElements(xx+x, yy+y, rgbElem);
+ int drgb = colorModel.getRGB(rgbElem);
+ int dr = ((drgb >>> 16) & 0xff) + 1;
+ int dg = ((drgb >>> 8) & 0xff) + 1;
+ int db = (drgb & 0xff) + 1;
+ int da = 256 - sa;
+
+ dr = ((sr*sa + dr*da) >>> 8) - 1;
+ dg = ((sg*sa + dg*da) >>> 8) - 1;
+ db = ((sb*sa + db*da) >>> 8) - 1;
+
+ drgb = (dr<<16) | (dg<<8) | db;
+
+ rgbElem = colorModel.getDataElements(drgb, rgbElem);
+
+ raster.setDataElements(xx+x, yy+y, rgbElem);
+ }
+ }
+ directGfx.unmapRaster(mr);
+ return true;
+
+ }
+ throw new UnsupportedOperationException("drawing image " + image +
+ "not implemented");
+ }
+
+
+ // -------- Graphics2D methods:
+
+ public void draw(Shape shape)
+ {
+ if (shape instanceof Rectangle)
+ {
+ Rectangle rect = (Rectangle) shape;
+ directGfx.drawRect(rect.x+tx, rect.y+ty, rect.width, rect.height);
+ return;
+ }
+
+ throw new UnsupportedOperationException("shape not implemented");
+ }
+
+ public void fill(Shape shape)
+ {
+ if (shape instanceof Rectangle)
+ {
+ Rectangle rect = (Rectangle) shape;
+ directGfx.fillRect(rect.x+tx, rect.y+ty, rect.width, rect.height);
+ return;
+ }
+
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public boolean hit(Rectangle rect, Shape text,
+ boolean onStroke)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void drawString(String text, int x, int y)
+ {
+ directGfx.drawString(text, x+tx, y+ty);
+ }
+
+ public void drawString(String text, float x, float y)
+ {
+ drawString(text, (int) x, (int) y);
+ }
+
+ public void translate(int x, int y)
+ {
+ tx += x;
+ ty += y;
+ }
+
+ public void translate(double tx, double ty)
+ {
+ if ((tx == 0) && (ty == 0))
+ return;
+
+ needAffineTransform();
+ }
+
+ public void rotate(double theta)
+ {
+ if (theta == 0)
+ return;
+
+ needAffineTransform();
+ }
+
+ public void rotate(double theta, double x, double y)
+ {
+ if (theta == 0)
+ return;
+
+ needAffineTransform();
+ }
+
+ public void scale(double scaleX, double scaleY)
+ {
+ if ((scaleX == 1) && (scaleY == 1))
+ return;
+
+ needAffineTransform();
+ }
+
+ public void shear(double shearX, double shearY)
+ {
+ if ((shearX == 0) && (shearY == 0))
+ return;
+
+ needAffineTransform();
+ }
+
+ private void needAffineTransform()
+ {
+ throw new UnsupportedOperationException("state with affine " +
+ "transform not implemented");
+ }
+}
diff --git a/libjava/gnu/awt/j2d/MappedRaster.java b/libjava/gnu/awt/j2d/MappedRaster.java
new file mode 100644
index 00000000000..eb41eecf9ad
--- /dev/null
+++ b/libjava/gnu/awt/j2d/MappedRaster.java
@@ -0,0 +1,72 @@
+/* Copyright (C) 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.awt.j2d;
+
+import java.awt.image.WritableRaster;
+import java.awt.image.ColorModel;
+
+/* The raster and associated properties of a mapped screen region.
+ * The compositing capabilities of backends are often insufficient.
+ * The backend may not support alpha blending, or may not support some
+ * other special compositing rule. This means that compositing must
+ * sometimes be done within the rendering pipeline. The general
+ * compositing operation consists of combining new color and alpha
+ * values with existing color values on the drawing surface, to find
+ * the new color values for the drawing surface. The way the values
+ * are combined, determines what kind of compositing operation that is
+ * performed. The default compositing operation is alpha compositing.
+ *
+ * <p>In order to perform alpha compositing and other compositing
+ * operations, we need access to the color values of the imagery that
+ * has already been drawn on the drawing surface. The
+ * DirectRasterGraphics interface must therefore contain methods that
+ * makes it possible to gain access to the pixel values of the drawing
+ * surface. The methods are modeled after the POSIX mmap() and
+ * munmap() functions. But, instead of mapping and unmapping portions
+ * of data from a file descriptor to memory, the methods in
+ * DirectRasterGraphics maps and unmaps portions of the drawing
+ * surface to data arrays within writable raster objects. A call to
+ * mapRaster() will return a writable raster object, encapsulating the
+ * image data of the drawing surface in the requested domain. The data
+ * encapsulated by this raster object can be modified using the
+ * WritableRaster API, or the data buffers can be retrieved from the
+ * raster, so that the data arrays can be manipulated directly. When
+ * the raster image has been modified as desired, the data can be
+ * resynchronized with the drawing surface by calling mapRaster().
+ *
+ * <p>As with mmap() and munmap() the methods may work by direct
+ * manipulation of shared memory, (i.e. the raster object directly
+ * wraps the actual image data of the drawing surface), or may make a
+ * private copy that is resynched when the raster is unmapped. The
+ * backend may choose to implement either mechanism, and the pipeline
+ * code should not care what mechanism is actually used. This design
+ * allows us to make full use of speedups such as X shared memory
+ * extentions when available.
+ */
+public class MappedRaster
+{
+ WritableRaster raster;
+ ColorModel cm;
+
+ public MappedRaster(WritableRaster raster, ColorModel cm)
+ {
+ this.raster = raster;
+ this.cm = cm;
+ }
+
+ public final WritableRaster getRaster()
+ {
+ return raster;
+ }
+
+ public final ColorModel getColorModel()
+ {
+ return cm;
+ }
+}
diff --git a/libjava/gnu/awt/xlib/XCanvasPeer.java b/libjava/gnu/awt/xlib/XCanvasPeer.java
new file mode 100644
index 00000000000..5674f5bf2ad
--- /dev/null
+++ b/libjava/gnu/awt/xlib/XCanvasPeer.java
@@ -0,0 +1,388 @@
+/* Copyright (C) 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.awt.xlib;
+
+import java.awt.Dimension;
+import java.awt.Component;
+import java.awt.EventQueue;
+import java.awt.Rectangle;
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Image;
+import java.awt.GraphicsConfiguration;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Toolkit;
+import java.awt.AWTEvent;
+import java.awt.Cursor;
+import java.awt.Shape;
+
+import java.awt.peer.*;
+import java.awt.image.*;
+
+import java.awt.event.MouseListener;
+import java.awt.event.PaintEvent;
+
+import java.util.EventListener;
+
+import gnu.gcj.xlib.WMSizeHints;
+import gnu.gcj.xlib.Window;
+import gnu.gcj.xlib.WindowAttributes;
+import gnu.gcj.xlib.Display;
+import gnu.gcj.xlib.Visual;
+import gnu.gcj.xlib.Screen;
+import gnu.gcj.xlib.XImage;
+
+import gnu.awt.j2d.*;
+
+public class XCanvasPeer implements CanvasPeer
+{
+ static final Dimension MIN_SIZE = new Dimension(1, 1);
+
+ public // temporary
+
+ Window window;
+ Window parent;
+
+ Component component;
+ XGraphicsConfiguration config;
+
+ public XCanvasPeer(Component component)
+ {
+ this.component = component;
+
+ // Set up graphics configuration (ie. screen + visual):
+
+ config = (XGraphicsConfiguration)
+ component.getGraphicsConfiguration();
+
+ if (config == null)
+ {
+ // This will usually only happen for toplevel windows
+ config = getXToolkit().getDefaultXGraphicsConfiguration();
+ }
+
+ Rectangle bounds = component.getBounds();
+ parent = locateParentWindow(bounds);
+
+ // Windows in X must atleast be of size 1x1
+ boolean boundsChanged = false;
+ if (bounds.width < 1)
+ {
+ boundsChanged = true;
+ bounds.width = 1;
+ }
+ if (bounds.height < 1)
+ {
+ boundsChanged = true;
+ bounds.height = 1;
+ }
+
+ /* don't worry about this calling back to us, since the real
+ component object has not yet received a reference to this peer
+ object. */
+ component.setBounds(bounds);
+
+ WindowAttributes attributes = new WindowAttributes();
+
+ /* Set background color */
+ Color bg = component.getBackground();
+ if (bg != null)
+ {
+ int[] components =
+ {
+ bg.getRed(),
+ bg.getGreen(),
+ bg.getBlue(),
+ 0xff
+ };
+
+ ColorModel cm = config.getColorModel();
+ long pixel = cm.getDataElement(components, 0);
+ attributes.setBackground(pixel);
+ }
+
+ /* Set exposure mask so that we get exposure events
+ that can be translated into paint() calls. */
+ long eventMask = WindowAttributes.MASK_EXPOSURE;
+
+ /* It would be nice to set up all other required events here, but
+ it is not possible to do so before after all the children of
+ this component has been realized. The reason is that it is not
+ determined whether a component is lightweight before after the
+ addNotify() method has been called. Thus, it is not possible
+ for parent component to determine what events it needs to
+ furnish for lightweight children. Instead, we currently rely
+ on the component calling our setEventMask() method after the
+ correct event mask has been determined. */
+
+ attributes.setEventMask(eventMask);
+
+
+ // TODO: set more window attributes?
+
+ /* don't allow event queue to process events from the newly
+ created window before this peer has been registered as client
+ data. */
+ synchronized (getXToolkit().eventLoop)
+ {
+ window = new gnu.gcj.xlib.Window(parent, bounds, attributes);
+ window.setClientData(this); /* make it possible to find back
+ to this peer object. Used by
+ XEventQueue. */
+ }
+
+ initWindowProperties();
+
+ if (component.isVisible())
+ EventQueue.invokeLater(new DoMap(window));
+ }
+
+ /**
+ * Override this in subclasses to implement other ways of obtaining
+ * parent windows. Toplevel windows will typically have a different
+ * implementation.
+ */
+ gnu.gcj.xlib.Window locateParentWindow(Rectangle bounds)
+ {
+ Container parent = component.getParent();
+ while (parent.isLightweight())
+ {
+ bounds.x += parent.getX();
+ bounds.y += parent.getY();
+ parent = parent.getParent();
+ // a null pointer here is a genuine error
+ }
+
+ XCanvasPeer parentPeer = (XCanvasPeer) parent.getPeer();
+ if (parentPeer == null)
+ throw new NullPointerException("Parent has no peer. This should " +
+ "not be possible, since the " +
+ "calls leading here should come " +
+ "from parent, after it has " +
+ "set the parent peer.");
+ return parentPeer.window;
+ }
+
+
+ /**
+ * Template method to allow subclasses to apply properties to X11
+ * window right after creation.
+ */
+ void initWindowProperties()
+ {
+ }
+
+ XToolkit getXToolkit()
+ {
+ return XToolkit.INSTANCE;
+ }
+
+ protected void ensureFlush()
+ {
+ getXToolkit().flushIfIdle();
+ }
+
+ public Component getComponent()
+ {
+ return component;
+ }
+
+ long getBasicEventMask()
+ {
+ return WindowAttributes.MASK_EXPOSURE;
+ }
+
+ // -------- java.awt.peer.ComponentPeer implementation
+
+ public int checkImage(Image img, int width, int height, ImageObserver o)
+ {
+ throw new UnsupportedOperationException("FIXME, not implemented");
+ }
+ public Image createImage(ImageProducer prod)
+ {
+ throw new UnsupportedOperationException("FIXME, not implemented");
+ }
+ public Image createImage(int width, int height)
+ {
+ throw new UnsupportedOperationException("FIXME, not implemented");
+ }
+ public void dispose()
+ {
+ throw new UnsupportedOperationException("FIXME, not implemented");
+ }
+
+ public GraphicsConfiguration getGraphicsConfiguration()
+ {
+ return config;
+ }
+
+ public FontMetrics getFontMetrics(Font f)
+ {
+ throw new UnsupportedOperationException("FIXME, not implemented");
+ }
+
+ public Graphics getGraphics()
+ {
+ DirectRasterGraphics gfxDevice = new XGraphics(window, config);
+ IntegerGraphicsState igState = new IntegerGraphicsState(gfxDevice);
+ Graphics2DImpl gfx2d = new Graphics2DImpl(config);
+
+ gfx2d.setState(igState);
+ gfx2d.setColor(component.getBackground());
+ return gfx2d;
+ }
+
+ public Point getLocationOnScreen()
+ {
+ throw new UnsupportedOperationException("FIXME, not implemented");
+ }
+
+ public Dimension getMinimumSize ()
+ {
+ return MIN_SIZE;
+ }
+
+ public Dimension getPreferredSize ()
+ {
+ return component.getSize();
+ }
+
+ public Toolkit getToolkit()
+ {
+ return getXToolkit();
+ }
+
+ public void handleEvent(AWTEvent event)
+ {
+ }
+
+ public boolean isFocusTraversable()
+ {
+ throw new UnsupportedOperationException("FIXME, not implemented");
+ }
+
+ public void paint(Graphics gfx)
+ {
+ // do nothing by default
+ }
+
+ public boolean prepareImage(Image img, int width, int height,
+ ImageObserver o)
+ {
+ throw new UnsupportedOperationException("FIXME, not implemented");
+ }
+
+ public void print(Graphics graphics)
+ {
+ paint(graphics);
+ }
+
+ public void repaint(long tm, int x, int y, int w, int h)
+ {
+ /* TODO?
+
+ X allows intelligent X servers to do smart
+ refreshing. Perhaps involve X in repainting of components,
+ rather that keeping it all within the local event queue. */
+
+ PaintEvent updateEvent = new PaintEvent(component,
+ PaintEvent.UPDATE,
+ new Rectangle(x, y, w, h));
+ getXToolkit().queue.postEvent(updateEvent);
+ }
+
+ public void requestFocus()
+ {
+ throw new UnsupportedOperationException("FIXME, not implemented");
+ }
+
+ public void setBackground(Color color)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void setBounds(int x, int y, int width, int height)
+ {
+ width = Math.max(width, 1);
+ height = Math.max(height, 1);
+ window.setBounds(x, y, width, height);
+ ensureFlush();
+ }
+
+ public void setCursor(Cursor cursor)
+ {
+ throw new UnsupportedOperationException("FIXME, not implemented");
+ }
+
+ public void setEnabled(boolean enabled)
+ {
+ throw new UnsupportedOperationException("FIXME, not implemented");
+ }
+
+ public void setEventMask(long eventMask)
+ {
+ WindowAttributes attributes = new WindowAttributes();
+
+ long xEventMask = getBasicEventMask();
+
+ if ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)
+ {
+ xEventMask |=
+ WindowAttributes.MASK_BUTTON_PRESS |
+ WindowAttributes.MASK_BUTTON_RELEASE;
+ }
+
+ attributes.setEventMask(xEventMask);
+ window.setAttributes(attributes);
+ ensureFlush();
+ }
+
+ public void setFont(Font font)
+ {
+ /* default canvas peer does keep track of font, since it won't
+ write anything. */
+ }
+
+ public void setForeground(Color color)
+ {
+ /* default canvas peer does keep track of foreground, since it won't
+ paint anything. */
+ }
+
+ public void setVisible(boolean visible)
+ {
+ if (visible)
+ {
+ window.map();
+ ensureFlush();
+ }
+ else
+ {
+ throw new UnsupportedOperationException("unmap not implemented");
+ }
+ }
+
+ static class DoMap implements Runnable
+ {
+ Window window;
+ public DoMap(Window w)
+ {
+ this.window = w;
+ }
+
+ public void run()
+ {
+ window.map();
+ }
+ }
+}
+
diff --git a/libjava/gnu/awt/xlib/XEventLoop.java b/libjava/gnu/awt/xlib/XEventLoop.java
new file mode 100644
index 00000000000..4d293208939
--- /dev/null
+++ b/libjava/gnu/awt/xlib/XEventLoop.java
@@ -0,0 +1,268 @@
+package gnu.awt.xlib;
+
+/* Copyright (C) 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. */
+
+import java.awt.*;
+
+import gnu.awt.LightweightRedirector;
+import gnu.gcj.xlib.Display;
+import gnu.gcj.xlib.XAnyEvent;
+import gnu.gcj.xlib.XExposeEvent;
+import gnu.gcj.xlib.XButtonEvent;
+import gnu.gcj.xlib.XConfigureEvent;
+import java.awt.event.PaintEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.util.Vector;
+
+public class XEventLoop implements Runnable
+{
+ Display display;
+ EventQueue queue;
+ XAnyEvent anyEvent;
+ Thread eventLoopThread;
+
+ LightweightRedirector lightweightRedirector = new LightweightRedirector();
+
+ public XEventLoop(Display display, EventQueue queue)
+ {
+ this.display = display;
+ this.queue = queue;
+
+ anyEvent = new XAnyEvent(display);
+ eventLoopThread = new Thread(this, "AWT thread for XEventLoop");
+ eventLoopThread.start();
+ }
+
+ public void run()
+ {
+ while (true)
+ postNextEvent();
+ }
+
+ void postNextEvent()
+ {
+ try
+ {
+ AWTEvent evt = getNextEvent();
+ queue.postEvent(evt);
+
+ }
+ catch (InterruptedException ie)
+ {
+ // FIXME: what now?
+ System.err.println(ie);
+ }
+ }
+
+ /** get next event. Will block until events become available. */
+
+ public AWTEvent getNextEvent()
+ {
+ // ASSERT:
+ if (isIdle())
+ throw new Error("should not be idle");
+
+ AWTEvent event = null;
+ while (event == null)
+ {
+ loadNextEvent();
+ event = createEvent();
+ }
+
+ event = lightweightRedirector.redirect(event);
+
+ return event;
+ }
+
+ void loadNextEvent()
+ {
+ try
+ {
+ setIdle(true);
+
+ /* The code below will result in an XFlush(). However,
+ while we are waiting for events after calling XFlush(),
+ new X requests issued on other threads will not
+ automatically be flushed. This can lead to a deadlock
+ since XFlush() will not be called before after the
+ processing of the next event, and new events arriving
+ might be dependent on the delivery of the X
+ requests.
+
+ Code that issues X requests should therefore call
+ flushIfIdle() after they're done, to ensure that the
+ requests are delivered in a timely manner. XFlush is not
+ run if event processing is underway, since we are assured
+ that the event loop execution will return to this point,
+ where requests are flushed again, before waiting for new
+ events.
+
+ Alternatively, do the work on the AWT thread, since the
+ XEventQueue knows how to flush the display when it runs out
+ of events. */
+
+ //display.flush(); // implicit?
+ anyEvent.loadNext();
+ }
+ catch (RuntimeException re)
+ {
+ System.err.println("Exception thrown on event thread:" + re);
+ }
+ finally
+ {
+ setIdle(false);
+ }
+ }
+
+ /**
+ * @returns an AWT event created based on the current XEvent.
+ * Returns null if the current XEvent does not map to any perticular
+ * AWT event.
+ */
+
+ AWTEvent createEvent()
+ {
+ /* avoid attempting to get client data before client data has
+ been set. */
+ Object peer;
+ synchronized (this)
+ {
+ peer = anyEvent.getWindow().getClientData();
+ }
+
+ Component source = null;
+
+ // Try to identify source component
+
+ if (peer instanceof XCanvasPeer)
+ {
+ source = ((XCanvasPeer) peer).getComponent();
+ }
+
+ if (source == null)
+ {
+ String msg = "unable to locate source for event (" +
+ anyEvent + ")";
+ throw new RuntimeException(msg);
+ }
+
+ /* if a mapping from anyEvent to AWTEvent is possible, construct a
+ new AWTEvent and return it. */
+
+ int type = anyEvent.getType();
+ switch (type)
+ {
+ case XAnyEvent.TYPE_EXPOSE:
+ return createPaintEvent(source);
+ case XAnyEvent.TYPE_BUTTON_PRESS:
+ case XAnyEvent.TYPE_BUTTON_RELEASE:
+ return createMouseEvent(type, source);
+ case XAnyEvent.TYPE_UNMAP_NOTIFY:
+ case XAnyEvent.TYPE_MAP_NOTIFY:
+ case XAnyEvent.TYPE_REPARENT_NOTIFY:
+ return null; // ignore for now
+ case XAnyEvent.TYPE_CONFIGURE_NOTIFY:
+ configureNotify(peer);
+ return null;
+
+ default:
+ String msg = "Do no know how to handle event (" + anyEvent + ")";
+ throw new RuntimeException(msg);
+ }
+ }
+
+ AWTEvent createPaintEvent(Component src)
+ {
+ XExposeEvent expose = new XExposeEvent(anyEvent);
+ PaintEvent pe = new PaintEvent(src, PaintEvent.PAINT,
+ expose.getBounds());
+ return pe;
+ }
+
+ AWTEvent createMouseEvent(int type, Component src)
+ {
+ XButtonEvent buttonEvt = new XButtonEvent(anyEvent);
+
+ int modifiers = 0; //buttonToModifierMap[buttonEvt.button];
+
+ /* Warning: this makes assumptions on the contents of
+ X.h... Button1 = 1, Button2 = 2, etc... */
+ switch (buttonEvt.button)
+ {
+ case 1:
+ modifiers = InputEvent.BUTTON1_MASK;
+ break;
+ case 2:
+ modifiers = InputEvent.BUTTON2_MASK;
+ break;
+ case 3:
+ modifiers = InputEvent.BUTTON2_MASK;
+ break;
+ }
+
+ int state = buttonEvt.state;
+
+ // remap bits from state to modifiers:
+
+ if ((state & XButtonEvent.MASK_SHIFT) != 0)
+ modifiers |= InputEvent.SHIFT_MASK;
+
+
+ if ((state & XButtonEvent.MASK_CONTROL) != 0)
+ modifiers |= InputEvent.CTRL_MASK;
+
+
+ /* FIXME: we need additional X code to properly map MODn states to
+ input modifiers */
+
+ int clickCount = 1; // FIXME... Can't get this from X.
+ boolean popupTrigger = false; // FIXME: look up policy somewhere
+
+ int x = buttonEvt.x;
+ int y = buttonEvt.y;
+
+ int id = (type == XAnyEvent.TYPE_BUTTON_PRESS) ?
+ MouseEvent.MOUSE_PRESSED :
+ MouseEvent.MOUSE_RELEASED;
+
+ MouseEvent me = new MouseEvent(src,
+ id,
+ buttonEvt.time, modifiers,
+ buttonEvt.x, buttonEvt.y,
+ clickCount, popupTrigger);
+ return me;
+ }
+
+ void configureNotify(Object peerObj)
+ {
+ XConfigureEvent configEvent = new XConfigureEvent(anyEvent);
+ XFramePeer peer = (XFramePeer) peerObj;
+
+ peer.configureNotify(configEvent);
+ }
+
+ public void flushIfIdle()
+ {
+ if (isIdle())
+ display.flush();
+ }
+
+ volatile boolean idle = false;
+
+ final synchronized void setIdle(boolean idle)
+ {
+ this.idle = idle;
+ }
+
+ final synchronized boolean isIdle()
+ {
+ return idle;
+ }
+}
diff --git a/libjava/gnu/awt/xlib/XEventQueue.java b/libjava/gnu/awt/xlib/XEventQueue.java
new file mode 100644
index 00000000000..ea2ad186060
--- /dev/null
+++ b/libjava/gnu/awt/xlib/XEventQueue.java
@@ -0,0 +1,34 @@
+/* Copyright (C) 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.awt.xlib;
+
+import java.awt.*;
+
+import gnu.gcj.xlib.Display;
+
+/**
+ * The only difference here from a standard EventQueue is that the X
+ * display connection is flushed before waiting for more events.
+ */
+public class XEventQueue extends EventQueue
+{
+ Display display;
+
+ public XEventQueue(Display display)
+ {
+ this.display = display;
+ }
+
+ public AWTEvent getNextEvent() throws InterruptedException
+ {
+ if ((peekEvent() == null) && (display != null))
+ display.flush();
+ return super.getNextEvent();
+ }
+}
diff --git a/libjava/gnu/awt/xlib/XFontMetrics.java b/libjava/gnu/awt/xlib/XFontMetrics.java
new file mode 100644
index 00000000000..4e45a1f8250
--- /dev/null
+++ b/libjava/gnu/awt/xlib/XFontMetrics.java
@@ -0,0 +1,47 @@
+/* Copyright (C) 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.awt.xlib;
+
+import java.awt.FontMetrics;
+
+public class XFontMetrics extends FontMetrics
+{
+ gnu.gcj.xlib.Font xfont;
+
+ public XFontMetrics(gnu.gcj.xlib.Font xfont, java.awt.Font awtFont)
+ {
+ super(awtFont);
+ this.xfont = xfont;
+ }
+
+ public int getAscent()
+ {
+ return xfont.getAscent();
+ }
+
+ public int getDescent()
+ {
+ return xfont.getDescent();
+ }
+
+ public int getMaxAscent()
+ {
+ return xfont.getMaxAscent();
+ }
+
+ public int getMaxDescent()
+ {
+ return xfont.getMaxDescent();
+ }
+
+ public int stringWidth(String str)
+ {
+ return xfont.getStringWidth(str);
+ }
+}
diff --git a/libjava/gnu/awt/xlib/XFramePeer.java b/libjava/gnu/awt/xlib/XFramePeer.java
new file mode 100644
index 00000000000..0f55088d023
--- /dev/null
+++ b/libjava/gnu/awt/xlib/XFramePeer.java
@@ -0,0 +1,174 @@
+/* Copyright (C) 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.awt.xlib;
+
+import java.awt.*;
+import java.awt.peer.*;
+import java.awt.image.*;
+import gnu.gcj.xlib.WMSizeHints;
+import gnu.gcj.xlib.WindowAttributes;
+import gnu.gcj.xlib.Display;
+import gnu.gcj.xlib.Visual;
+import gnu.gcj.xlib.Screen;
+import gnu.gcj.xlib.XConfigureEvent;
+
+/** FIXME: a lot of the code here should be moved down to XWindowPeer. */
+
+public class XFramePeer extends XCanvasPeer implements FramePeer
+{
+
+ public XFramePeer(Frame frame)
+ {
+ super(frame);
+
+ // Set some defaults for a toplevel component:
+ if (frame.getFont() == null)
+ frame.setFont(new Font("helvetica", Font.PLAIN, 12));
+
+ if (frame.getBackground() == null)
+ frame.setBackground(Color.lightGray);
+
+ if (frame.getForeground() == null)
+ frame.setForeground(Color.black);
+ }
+
+ /** Find parent window for toplevel window, ie. root window of
+ selected screen. Bounds are not changed. */
+ gnu.gcj.xlib.Window locateParentWindow(Rectangle bounds)
+ {
+ Screen screen = config.getVisual().getScreen();
+ return screen.getRootWindow();
+ }
+
+ void initWindowProperties()
+ {
+ Frame frame = (Frame) component;
+ setResizable(frame.isResizable());
+ String title = frame.getTitle();
+ if (!title.equals("")) setTitle(title);
+ }
+
+ long getBasicEventMask()
+ {
+ return super.getBasicEventMask() |
+ WindowAttributes.MASK_STRUCTURE_NOTIFY;
+ }
+
+ void configureNotify(XConfigureEvent configEvent)
+ {
+ component.setBounds(configEvent.getBounds());
+
+ /* FIXME: Validation should probably not be done here. The best
+ strategy is probably to validate on the AWT thread in response
+ to an ComponentEvent. This will make it possible to coalesce
+ resize validations. */
+ component.validate();
+ }
+
+ /* Overridden to ignore request to set bounds if the request occurs
+ on the X event loop thread. It is assumed that all requests that
+ occur on the X event loop thread are results of XConfigureNotify
+ events, in which case the X window already has the desired
+ bounds. */
+ public void setBounds(int x, int y, int width, int height)
+ {
+ if (Thread.currentThread() == getXToolkit().eventLoop.eventLoopThread)
+ return;
+
+ super.setBounds(x, y, width, height);
+ }
+
+ // Implementing ContainerPeer:
+
+ static final Insets INSETS_0_PROTOTYPE = new Insets(0, 0, 0, 0);
+
+ public Insets getInsets()
+ {
+ return (Insets) INSETS_0_PROTOTYPE.clone();
+ }
+
+ public void beginValidate()
+ {
+ }
+
+ public void endValidate()
+ {
+ // reassert sizing hints
+ Frame frame = (Frame) component;
+ setResizable(frame.isResizable());
+ }
+
+
+ // Implementing WindowPeer:
+
+ public void toBack()
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void toFront()
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+
+ // Implementing FramePeer:
+
+ public void setIconImage(Image image)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void setMenuBar(MenuBar mb)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+
+ public void setTitle(String title)
+ {
+ synchronized (window.getDisplay())
+ {
+ // Oh, what a nice implementation :-)
+ window.setProperty("WM_NAME", "STRING", title);
+
+ ensureFlush();
+ }
+ }
+
+ public void setResizable(boolean resizable)
+ {
+ Frame frame = (Frame) component;
+
+ WMSizeHints sizeHints = new WMSizeHints();
+ if (resizable)
+ {
+ Dimension minSize = frame.getMinimumSize();
+ sizeHints.setMinSize(minSize.width, minSize.height);
+
+ Dimension maxSize = frame.getMaximumSize();
+
+ if ((maxSize.width < Short.MAX_VALUE) ||
+ (maxSize.height < Short.MAX_VALUE))
+ {
+ maxSize.width = Math.min(maxSize.width, Short.MAX_VALUE);
+ maxSize.height = Math.min(maxSize.height, Short.MAX_VALUE);
+ sizeHints.setMaxSize(maxSize.width, maxSize.height);
+ }
+ }
+ else
+ {
+ // lock resizing to current bounds
+ Dimension size = frame.getSize();
+ sizeHints.setMinSize(size.width, size.height);
+ sizeHints.setMaxSize(size.width, size.height);
+ }
+ sizeHints.applyNormalHints(window);
+ }
+}
diff --git a/libjava/gnu/awt/xlib/XGraphics.java b/libjava/gnu/awt/xlib/XGraphics.java
new file mode 100644
index 00000000000..27b07a2369a
--- /dev/null
+++ b/libjava/gnu/awt/xlib/XGraphics.java
@@ -0,0 +1,279 @@
+/* Copyright (C) 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.awt.xlib;
+
+import java.awt.*;
+import java.awt.image.WritableRaster;
+import java.awt.image.Raster;
+import java.awt.image.DataBuffer;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.BufferedImage;
+import gnu.gcj.xlib.GC;
+import gnu.gcj.xlib.XImage;
+import gnu.gcj.xlib.Drawable;
+import gnu.gcj.xlib.Window;
+import gnu.gcj.xlib.Drawable;
+import gnu.gcj.xlib.Visual;
+import gnu.awt.j2d.DirectRasterGraphics;
+import gnu.awt.j2d.MappedRaster;
+
+public class XGraphics implements Cloneable, DirectRasterGraphics
+{
+ static class XRaster extends MappedRaster
+ {
+ XImage ximage;
+
+ public XRaster(WritableRaster raster, XImage ximage, ColorModel cm)
+ {
+ super(raster, cm);
+ this.ximage = ximage;
+ }
+ }
+
+ GC context;
+ XGraphicsConfiguration config;
+ Rectangle clipBounds;
+
+ XFontMetrics metrics;
+
+
+ public Object clone()
+ {
+ XGraphics gfxCopy = (XGraphics) super.clone();
+ gfxCopy.context = context.create();
+
+ return gfxCopy;
+ }
+
+ public void dispose()
+ {
+ GC lContext = context;
+ context = null;
+ config = null;
+ clipBounds = null;
+
+ if (lContext != null)
+ {
+ lContext.dispose();
+ }
+ }
+
+ public XGraphics(Drawable drawable, XGraphicsConfiguration config)
+ {
+ context = new GC(drawable);
+ this.config = config;
+ }
+
+ public void setColor(Color color)
+ {
+ context.setForeground(config.getPixel(color));
+ }
+
+ public void setPaintMode()
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void setXORMode(Color c1)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void setFont(Font font)
+ {
+ if ((metrics != null) && font.equals(metrics.getFont())) return;
+
+ metrics = config.getXFontMetrics(font);
+ context.setFont(metrics.xfont);
+ }
+
+ public FontMetrics getFontMetrics(Font font)
+ {
+ if ((metrics != null) && font.equals(metrics.getFont()))
+ return metrics;
+
+ return config.getXFontMetrics(font);
+ }
+
+ public void setClip(int x, int y, int width, int height)
+ {
+ Rectangle[] rects = { new Rectangle(x, y, width, height) };
+ context.setClipRectangles(rects);
+ }
+
+ public void setClip(Shape clip)
+ {
+ /* TODO: create a special RectangleUnion shape that can be
+ used to draw advantage of the GCs ability to set multiple
+ rectangles.
+ */
+
+ /* FIXME: creating all these objects is wasteful and can be
+ costly in the long run, since this code is run at every
+ expose. */
+ Rectangle newClipBounds = clip.getBounds();
+
+ if ((clipBounds != null) && !clipBounds.contains(newClipBounds))
+ {
+ System.err.println("warning: old clip ("+ clipBounds +") does " +
+ "not fully contain new clip (" +
+ newClipBounds + ")");
+ }
+ clipBounds = newClipBounds;
+ Rectangle[] rects = { clipBounds };
+ context.setClipRectangles(rects);
+ }
+
+ public void copyArea(int x, int y, int width, int height, int
+ dx, int dy)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void drawLine(int x1, int y1, int x2, int y2)
+ {
+ context.drawLine(x1, y1, x2, y2);
+ }
+
+ public void drawRect(int x, int y, int width, int height)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void fillRect(int x, int y, int width, int height)
+ {
+ context.fillRectangle(x, y, width, height);
+ }
+
+ public void drawArc(int x, int y, int width, int height, int
+ startAngle, int arcAngle)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void fillArc(int x, int y, int width, int height, int
+ startAngle, int arcAngle)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void drawPolyline(int[] xPoints, int[] yPoints, int
+ nPoints)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void drawPolygon(int[] xPoints, int[] yPoints, int
+ nPoints)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void fillPolygon(int[] xPoints, int[] yPoints, int
+ nPoints)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void drawString(String str, int x, int y)
+ {
+ context.drawString(str, x, y);
+ }
+
+ public boolean drawImage(Image img, int x, int y,
+ ImageObserver observer)
+ {
+ if (clipBounds == null)
+ return false; // ***FIXME***
+
+ if (!(img instanceof BufferedImage))
+ {
+ throw new AWTError("unknown image class");
+ }
+
+ BufferedImage bimg = (BufferedImage) img;
+
+ XImage ximg = (XImage) bimg.getProperty("gnu.gcj.xlib.XImage");
+ if (ximg == null)
+ {
+ System.err.println("FIXME: skipping null XImage, should " +
+ "really do on the spot conversion");
+ return false;
+ }
+
+ /*
+ +------------------
+ | clip
+ | +---------+
+ | img | |
+ | +--+-------+ |
+ | | | | |
+ | | | | |
+ | | +-------+-+
+ | | |
+ | +----------+
+ */
+
+ int iLeft = Math.max(x, clipBounds.x);
+ int iTop = Math.max(y, clipBounds.y);
+ int iRight = Math.min(x + bimg.getWidth(),
+ clipBounds.x + clipBounds.width);
+ int iBottom = Math.min(y + bimg.getHeight(),
+ clipBounds.y + clipBounds.height);
+
+ int srcX = iLeft - x;
+ int srcY = iTop - y;
+
+ int width = iRight - iLeft;
+ int height = iBottom - iTop;
+
+ if ((width > 0) && (height > 0))
+ context.putImage(ximg, srcX, srcY, iLeft, iTop, width, height);
+
+ return true;
+ }
+
+ public MappedRaster mapRaster(Rectangle bounds)
+ {
+ Visual visual = config.getVisual();
+ XImage ximage = new XImage(visual, bounds.width, bounds.height,
+ false // do not auto allocate memory
+ );
+
+ WritableRaster raster =
+ config.createRasterForXImage(ximage,
+ new Point(bounds.x, bounds.y));
+
+ DataBuffer dataB = raster.getDataBuffer();
+ XGraphicsConfiguration.attachData(ximage, dataB, 0);
+
+ Drawable drawable = context.getDrawable();
+
+ // TODO: restrict to clipping
+
+ Rectangle mBounds = drawable.copyIntoXImage(ximage, bounds, 0, 0);
+
+ return new XRaster(raster, ximage, config.imageCM);
+ }
+
+
+ public void unmapRaster(MappedRaster mappedRaster)
+ {
+ XRaster xraster = (XRaster) mappedRaster;
+ XImage ximage = xraster.ximage;
+ Raster raster = xraster.getRaster();
+ int x = raster.getMinX();
+ int y = raster.getMinY();
+ int width = raster.getWidth();
+ int height = raster.getHeight();
+
+ context.putImage(ximage, 0, 0, x, y, width, height);
+ }
+}
diff --git a/libjava/gnu/awt/xlib/XGraphicsConfiguration.java b/libjava/gnu/awt/xlib/XGraphicsConfiguration.java
new file mode 100644
index 00000000000..af2663ba58b
--- /dev/null
+++ b/libjava/gnu/awt/xlib/XGraphicsConfiguration.java
@@ -0,0 +1,367 @@
+/* Copyright (C) 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.awt.xlib;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.Rectangle;
+import java.awt.Graphics2D;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Color;
+import java.awt.color.ColorSpace;
+import java.awt.image.*;
+import java.awt.geom.AffineTransform;
+import gnu.gcj.xlib.GC;
+import gnu.gcj.xlib.Drawable;
+import gnu.gcj.xlib.Window;
+import gnu.gcj.xlib.XImage;
+import gnu.gcj.xlib.Visual;
+import gnu.gcj.xlib.Colormap;
+import gnu.gcj.xlib.XColor;
+import gnu.gcj.xlib.Screen;
+import gnu.gcj.xlib.Display;
+import gnu.gcj.awt.Buffers;
+import java.util.Hashtable;
+
+public class XGraphicsConfiguration extends GraphicsConfiguration
+{
+ //public abstract GraphicsDevice getDevice();
+
+ Visual visual;
+ int format;
+ Colormap colormap;
+ ColorModel imageCM;
+ ColorModel pixelCM;
+
+ public XGraphicsConfiguration(Visual visual)
+ {
+ this.visual = visual;
+ }
+
+ public BufferedImage createCompatibleImage(int width, int height)
+ {
+ XImage ximg = new XImage(visual, width, height,
+ false // do not auto allocate memory
+ );
+
+ Point origin = new Point(0, 0);
+ WritableRaster raster = createRasterForXImage(ximg, origin);
+
+ /* This is not a good way of doing this. Multiple toolkits may
+ want to share the BufferedImage. */
+ Hashtable props = new Hashtable();
+ props.put("gnu.gcj.xlib.XImage", ximg);
+ props.put("java.awt.GraphicsConfiguration", this);
+
+ BufferedImage bimg = new BufferedImage(imageCM,raster, false, props);
+
+ DataBuffer dataB = raster.getDataBuffer();
+ attachData(ximg, dataB, 0);
+ return bimg;
+ }
+
+ WritableRaster createRasterForXImage(XImage ximage, Point origin)
+ {
+ if (imageCM == null) prepareColorModel(ximage);
+
+ /*
+ This will not work, since it creates a sample model that
+ does not necessarily match the format of the XImage.
+
+ WritableRaster raster =
+ imageCM.createCompatibleWritableRaster(width, height); */
+
+ // Create a sample model matching the XImage:
+
+ SampleModel imageSM = null;
+
+ int width = ximage.getWidth();
+ int height = ximage.getHeight();
+ int bitsPerPixel = ximage.getBitsPerPixel();
+ int dataType =
+ Buffers.smallestAppropriateTransferType(bitsPerPixel);
+ int bitsPerDataElement = DataBuffer.getDataTypeSize(dataType);
+ int scanlineStride = ximage.getBytesPerLine()*8/bitsPerDataElement;
+
+ if (imageCM instanceof IndexColorModel)
+ {
+ int[] bandOffsets = {0};
+ imageSM = new ComponentSampleModel(dataType,
+ width, height,
+ 1, // pixel stride
+ scanlineStride,
+ bandOffsets);
+ }
+ else if (imageCM instanceof PackedColorModel)
+ {
+ PackedColorModel pcm = (PackedColorModel) imageCM;
+ int[] masks = pcm.getMasks();
+
+ imageSM = new SinglePixelPackedSampleModel(dataType,
+ width, height,
+ scanlineStride,
+ masks);
+ }
+
+ if (imageSM == null)
+ {
+ throw new UnsupportedOperationException("creating sample model " +
+ "for " + imageCM +
+ " not implemented");
+ }
+
+ WritableRaster raster = Raster.createWritableRaster(imageSM, origin);
+ return raster;
+ }
+
+
+
+ /**
+ * Attach a the memory of a data buffer to an XImage
+ * structure. [This method is not gnu.awt.xlib specific, and should
+ * maybe be moved to a different location.]
+ *
+ * @param offset Offset to data. The given offset does not include
+ * data buffer offset, which will also be added. */
+ static void attachData(XImage ximage, DataBuffer dataB, int offset)
+ {
+ offset += dataB.getOffset();
+ switch (dataB.getDataType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ ximage.setData(((DataBufferByte) dataB).getData(), offset);
+ break;
+ case DataBuffer.TYPE_USHORT:
+ ximage.setData(((DataBufferUShort) dataB).getData(), offset);
+ break;
+ case DataBuffer.TYPE_INT:
+ ximage.setData(((DataBufferInt) dataB).getData(), offset);
+ break;
+ default:
+ throw
+ new UnsupportedOperationException("Do not know how to " +
+ "set data for data " +
+ "type " +
+ dataB.getDataType());
+ }
+ }
+
+ void prepareColorModel(XImage ximage)
+ {
+ format = ximage.getFormat();
+ int bitsPerPixel = ximage.getBitsPerPixel();
+ switch (format) {
+ case XImage.ZPIXMAP_FORMAT:
+ calcZPixmapModels(bitsPerPixel);
+ break;
+
+ default:
+ throw new UnsupportedOperationException("unimplemented format");
+ }
+ }
+
+ void calcZPixmapModels(int bitsPerPixel)
+ {
+ switch (visual.getVisualClass())
+ {
+ case Visual.VC_TRUE_COLOR:
+ calcDecomposedRGBModels(bitsPerPixel);
+ break;
+ case Visual.VC_PSEUDO_COLOR:
+ calcPseudoColorModels(bitsPerPixel);
+ break;
+ default:
+ String msg = "unimplemented visual class";
+ throw new UnsupportedOperationException(msg);
+ }
+ }
+
+ void calcDecomposedRGBModels(int bitsPerPixel)
+ {
+ int dataType = Buffers.smallestAppropriateTransferType(bitsPerPixel);
+
+
+ if (DataBuffer.getDataTypeSize(dataType) == bitsPerPixel)
+ {
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+
+ imageCM = new DirectColorModel(cs,
+ visual.getDepth(),
+ visual.getRedMask(),
+ visual.getGreenMask(),
+ visual.getBlueMask(),
+ 0, // no alpha
+ false,
+ dataType);
+ }
+ else
+ {
+ throw new
+ UnsupportedOperationException("unimplemented bits per pixel");
+ }
+ }
+
+ void calcPseudoColorModels(int bitsPerPixel)
+ {
+ if (colormap == null)
+ colormap = visual.getScreen().getDefaultColormap();
+
+ XColor[] colArray = colormap.getXColors();
+
+ int numCol = colArray.length;
+ byte[] rmap = new byte[numCol];
+ byte[] gmap = new byte[numCol];
+ byte[] bmap = new byte[numCol];
+ byte[] amap = new byte[numCol];
+
+ for (int i=0; i < numCol; i++)
+ {
+ XColor color = colArray[i];
+ if (color.getFlags() == Colormap.FLAG_SHARED)
+ {
+ rmap[i] = (byte) (color.getRed() >> 8);
+ gmap[i] = (byte) (color.getGreen() >> 8);
+ bmap[i] = (byte) (color.getBlue() >> 8);
+ amap[i] = (byte) 0xff;
+ } // else, leave default zero values...
+ }
+
+ imageCM = new IndexColorModel(visual.getDepth(), numCol,
+ rmap, gmap, bmap, amap);
+ }
+
+ public BufferedImage createCompatibleImage(int width,
+ int height,
+ int transparency)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ /**
+ * FIXME: I'm not sure which color model that should be returned here.
+ */
+ public ColorModel getColorModel()
+ {
+ if (pixelCM == null)
+ preparePixelCM();
+ return pixelCM;
+ }
+
+ void preparePixelCM()
+ {
+ switch (visual.getVisualClass())
+ {
+ case Visual.VC_TRUE_COLOR:
+ pixelCM = new DirectColorModel(visual.getDepth(),
+ visual.getRedMask(),
+ visual.getGreenMask(),
+ visual.getBlueMask());
+ break;
+ case Visual.VC_PSEUDO_COLOR:
+
+ if (colormap == null)
+ colormap = visual.getScreen().getDefaultColormap();
+
+ XColor[] colArray = colormap.getXColors();
+
+ int numCol = colArray.length;
+ byte[] rmap = new byte[numCol];
+ byte[] gmap = new byte[numCol];
+ byte[] bmap = new byte[numCol];
+ byte[] amap = new byte[numCol];
+
+ for (int i=0; i < numCol; i++)
+ {
+ XColor color = colArray[i];
+ if (color.getFlags() == Colormap.FLAG_SHARED) {
+ rmap[i] = (byte) (color.getRed() >> 8);
+ gmap[i] = (byte) (color.getGreen() >> 8);
+ bmap[i] = (byte) (color.getBlue() >> 8);
+ amap[i] = (byte) 0xff;
+ } // else, leave default zero values...
+
+ }
+
+ pixelCM = new IndexColorModel(visual.getDepth(), numCol,
+ rmap, gmap, bmap, amap);
+ break;
+ default:
+ throw new UnsupportedOperationException("not implemented");
+ }
+ }
+
+ public ColorModel getColorModel(int transparency)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public AffineTransform getDefaultTransform()
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public AffineTransform getNormalizingTransform()
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public Rectangle getBounds()
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ Visual getVisual()
+ {
+ return visual;
+ }
+
+ /* FIXME: This should be moved to XGraphicsDevice... */
+ XFontMetrics getXFontMetrics(java.awt.Font awtFont)
+ {
+ // FIXME: do caching...
+
+ String family = "*";
+ String name = awtFont.getName();
+ String weight = awtFont.isBold() ? "bold" : "medium";
+ String slant = awtFont.isItalic() ? "i" : "r";
+ String addStyle = "*";
+ String pixelSize = "*";
+ String pointSize = awtFont.getSize() + "0";
+ String xres = "*";
+ String yres = "*";
+ String spacing = "*";
+ String averageWidth = "*";
+ String charset = "*";
+
+ String logicalFontDescription =
+ family + "-" + name + "-" + weight + "-" +
+ slant + "-" + addStyle + "-" + pixelSize + "-" +
+ pointSize + "-" + xres + "-" + yres + "-" +
+ spacing + "-" + averageWidth + "-" + charset;
+
+ Display display = visual.getScreen().getDisplay();
+ gnu.gcj.xlib.Font xfont =
+ new gnu.gcj.xlib.Font(display, logicalFontDescription);
+ return new XFontMetrics(xfont, awtFont);
+ }
+
+ int getPixel(Color color)
+ {
+ int[] components =
+ {
+ color.getRed(),
+ color.getGreen(),
+ color.getBlue(),
+ 0xff
+ };
+
+ ColorModel cm = getColorModel();
+ return cm.getDataElement(components, 0);
+ }
+}
diff --git a/libjava/gnu/awt/xlib/XPanelPeer.java b/libjava/gnu/awt/xlib/XPanelPeer.java
new file mode 100644
index 00000000000..c4ff3f17b71
--- /dev/null
+++ b/libjava/gnu/awt/xlib/XPanelPeer.java
@@ -0,0 +1,52 @@
+/* Copyright (C) 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.awt.xlib;
+
+import java.awt.*;
+import java.awt.peer.*;
+import java.awt.image.*;
+import gnu.gcj.xlib.WMSizeHints;
+import gnu.gcj.xlib.WindowAttributes;
+import gnu.gcj.xlib.Display;
+import gnu.gcj.xlib.Visual;
+import gnu.gcj.xlib.Screen;
+
+public class XPanelPeer extends XCanvasPeer implements PanelPeer
+{
+
+ public XPanelPeer(Panel panel)
+ {
+ super(panel);
+ }
+
+ // no reason to override yet
+ //void initWindowProperties();
+ //gnu.gcj.xlib.Window getParentWindow();
+
+
+ // Implementing ContainerPeer:
+
+ // Default is no insets...
+ static final Insets INSETS_0_PROTOTYPE = new Insets(0, 0, 0, 0);
+
+ public Insets getInsets()
+ {
+ return (Insets) INSETS_0_PROTOTYPE.clone();
+ }
+
+ public void beginValidate()
+ {
+ // NOP
+ }
+
+ public void endValidate()
+ {
+ // NOP
+ }
+}
diff --git a/libjava/gnu/awt/xlib/XToolkit.java b/libjava/gnu/awt/xlib/XToolkit.java
new file mode 100644
index 00000000000..e400b05e648
--- /dev/null
+++ b/libjava/gnu/awt/xlib/XToolkit.java
@@ -0,0 +1,333 @@
+/* Copyright (C) 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.awt.xlib;
+
+import java.awt.*;
+import java.awt.peer.*;
+import java.awt.image.ImageProducer;
+import java.awt.image.ImageObserver;
+import java.net.*;
+import java.awt.datatransfer.Clipboard;
+
+import gnu.gcj.xlib.Display;
+import gnu.gcj.xlib.Screen;
+import gnu.gcj.xlib.Visual;
+
+public class XToolkit extends Toolkit
+{
+ static XToolkit INSTANCE;
+
+ Display display;
+
+ EventQueue queue;
+ XEventLoop eventLoop;
+
+ XGraphicsConfiguration defaultConfig;
+
+ public XToolkit()
+ {
+ INSTANCE = this;
+ display = new Display();
+ synchronized (display)
+ {
+ queue = new XEventQueue(display);
+ eventLoop = new XEventLoop(display, queue);
+ }
+ }
+
+ public void flushIfIdle()
+ {
+ eventLoop.flushIfIdle();
+ }
+
+ protected ButtonPeer createButton(Button frontend)
+ {
+ // FIXME: Stubbed out, needs Swing:
+ /*
+ XCanvasPeer realPeer = new XCanvasPeer(frontend);
+ SButtonPeer sbPeer = new SButtonPeer(frontend, realPeer);
+ return sbPeer;
+ */
+ return null;
+ }
+
+ protected TextFieldPeer createTextField(TextField frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected LabelPeer createLabel(Label frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected ListPeer createList(List frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected CheckboxPeer createCheckbox(Checkbox frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected ScrollbarPeer createScrollbar(Scrollbar frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected ScrollPanePeer createScrollPane(ScrollPane frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected TextAreaPeer createTextArea(TextArea frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected ChoicePeer createChoice(Choice frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected FramePeer createFrame(Frame frontend) {
+ return new XFramePeer(frontend);
+ }
+
+ protected CanvasPeer createCanvas(Canvas frontend) {
+ XCanvasPeer peer = new XCanvasPeer(frontend);
+ return peer;
+ }
+
+ protected PanelPeer createPanel(Panel frontend) {
+ return new XPanelPeer(frontend);
+ }
+
+ protected WindowPeer createWindow(Window frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected DialogPeer createDialog(Dialog frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected MenuBarPeer createMenuBar(MenuBar frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected MenuPeer createMenu(Menu frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected PopupMenuPeer createPopupMenu(PopupMenu frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected MenuItemPeer createMenuItem(MenuItem frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected FileDialogPeer createFileDialog(FileDialog frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected CheckboxMenuItemPeer
+ createCheckboxMenuItem(CheckboxMenuItem frontend)
+ {
+ return null; // FIXME
+ }
+
+ protected java.awt.peer.FontPeer getFontPeer(String name, int style)
+ {
+ return null;
+ }
+
+ public Dimension getScreenSize()
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public int getScreenResolution()
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public java.awt.image.ColorModel getColorModel()
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public String[] getFontList()
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public FontMetrics getFontMetrics(Font font)
+ {
+ return defaultConfig.getXFontMetrics(font);
+ }
+
+ public void sync()
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public Image getImage(String filename)
+ {
+ return createImage(filename);
+ }
+
+ public Image getImage(URL url)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public Image createImage(String filename)
+ {
+ // FIXME: Stubbed out. We need a proper image I/O API.
+
+ /*
+ BufferedImage jpeg;
+ FileInputStream fis = openFile(filename);
+ if (fis == null)
+ return null;
+
+ BasicRasterImageConsumer consumer = new BasicRasterImageConsumer();
+ JPEGImageDecoder jid = new JPEGImageDecoder(fis);
+
+ jid.startProduction(consumer);
+ jpeg = consumer.getImage();
+
+ int w = jpeg.getWidth();
+ int h = jpeg.getHeight();
+
+ BufferedImage img =
+ getDefaultXGraphicsConfiguration().createCompatibleImage(w, h);
+
+ Renderers renderers = Renderers.getInstance();
+
+ RasterOp renderer = renderers.createRenderer(jpeg.getColorModel(),
+ jpeg.getSampleModel(),
+ img.getColorModel(),
+ img.getSampleModel());
+
+ if (renderer == null)
+ {
+ throw new UnsupportedOperationException("couldn't find renderer");
+ }
+
+ renderer.filter(jpeg.getRaster(), img.getRaster());
+
+ return img;
+ */
+
+ return null;
+ }
+
+ public Image createImage(URL url)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public boolean prepareImage(Image image,
+ int width,
+ int height,
+ ImageObserver observer)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public int checkImage(Image image,
+ int width,
+ int height,
+ ImageObserver observer)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public Image createImage(ImageProducer producer)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public Image createImage(byte[] imagedata,
+ int imageoffset,
+ int imagelength)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ /*
+ public PrintJob getPrintJob(Frame frame,
+ String jobtitle,
+ Properties props);
+ */
+
+ public void beep()
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public Clipboard getSystemClipboard()
+ {
+ return null; // FIXME
+ }
+
+ protected EventQueue getSystemEventQueueImpl()
+ {
+ return queue;
+ }
+
+ XGraphicsConfiguration getDefaultXGraphicsConfiguration()
+ {
+ if (defaultConfig == null)
+ {
+ Screen screen = display.getDefaultScreen();
+ Visual visual = screen.getRootVisual();
+ defaultConfig = new XGraphicsConfiguration(visual);
+
+ // ASSERT:
+ if (!defaultConfig.getVisual().getScreen().equals(screen))
+ {
+ String msg = "screen of graphics configuration is not " +
+ "default screen";
+ throw new Error(msg);
+ }
+ }
+
+ return defaultConfig;
+ }
+
+
+ /*
+ public DragSourceContextPeer
+ createDragSourceContextPeer(DragGestureEvent dge)
+ throws InvalidDnDOperationException;
+
+ public DragGestureRecognizer
+ createDragGestureRecognizer(Class abstractRecognizerClass,
+ DragSource ds, Component c,
+ int srcActions, DragGestureListener dgl) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+ */
+
+
+ /*
+ public Map mapInputMethodHighlight(InputMethodHighlight highlight);
+ */
+}