aboutsummaryrefslogtreecommitdiff
path: root/libjava/gnu/awt/xlib
diff options
context:
space:
mode:
authorRolf W. Rasmussen <rolfwr@ii.uib.no>2000-10-22 19:46:09 +0200
committerRolf Rasmussen <rolfwr@gcc.gnu.org>2000-10-22 17:46:09 +0000
commit2622c79d2d51f6bf9122a3b5f458daa50c0baf19 (patch)
tree1165199489e8bc851f2bb5c11ff0228f3667453e /libjava/gnu/awt/xlib
parent9b95cc4a34af1148dc18c7912ab77f19a753bf80 (diff)
downloadgcc-2622c79d2d51f6bf9122a3b5f458daa50c0baf19.zip
gcc-2622c79d2d51f6bf9122a3b5f458daa50c0baf19.tar.gz
gcc-2622c79d2d51f6bf9122a3b5f458daa50c0baf19.tar.bz2
Makefile.am: Added rules for libgcjx library.
* 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. From-SVN: r37005
Diffstat (limited to 'libjava/gnu/awt/xlib')
-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
9 files changed, 1942 insertions, 0 deletions
diff --git a/libjava/gnu/awt/xlib/XCanvasPeer.java b/libjava/gnu/awt/xlib/XCanvasPeer.java
new file mode 100644
index 0000000..5674f5b
--- /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 0000000..4d29320
--- /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 0000000..ea2ad18
--- /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 0000000..4e45a1f
--- /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 0000000..0f55088
--- /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 0000000..27b07a2
--- /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 0000000..af2663b
--- /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 0000000..c4ff3f1
--- /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 0000000..e400b05
--- /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);
+ */
+}