From ac1ed908de999523efc36f38e69bca1aadfe0808 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 14 Aug 2006 23:12:35 +0000 Subject: Imported GNU Classpath 0.92 2006-08-14 Mark Wielaard Imported GNU Classpath 0.92 * HACKING: Add more importing hints. Update automake version requirement. * configure.ac (gconf-peer): New enable AC argument. Add --disable-gconf-peer and --enable-default-preferences-peer to classpath configure when gconf is disabled. * scripts/makemake.tcl: Set gnu/java/util/prefs/gconf and gnu/java/awt/dnd/peer/gtk to bc. Classify gnu/java/security/Configuration.java as generated source file. * gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java, gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java, gnu/java/lang/management/VMClassLoadingMXBeanImpl.java, gnu/java/lang/management/VMRuntimeMXBeanImpl.java, gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java, gnu/java/lang/management/VMThreadMXBeanImpl.java, gnu/java/lang/management/VMMemoryMXBeanImpl.java, gnu/java/lang/management/VMCompilationMXBeanImpl.java: New VM stub classes. * java/lang/management/VMManagementFactory.java: Likewise. * java/net/VMURLConnection.java: Likewise. * gnu/java/nio/VMChannel.java: Likewise. * java/lang/Thread.java (getState): Add stub implementation. * java/lang/Class.java (isEnum): Likewise. * java/lang/Class.h (isEnum): Likewise. * gnu/awt/xlib/XToolkit.java (getClasspathTextLayoutPeer): Removed. * javax/naming/spi/NamingManager.java: New override for StackWalker functionality. * configure, sources.am, Makefile.in, gcj/Makefile.in, include/Makefile.in, testsuite/Makefile.in: Regenerated. From-SVN: r116139 --- .../classpath/gnu/java/awt/ClasspathToolkit.java | 27 +- .../awt/dnd/GtkMouseDragGestureRecognizer.java | 172 +++++ .../awt/dnd/peer/gtk/GtkDragSourceContextPeer.java | 174 +++++ .../awt/dnd/peer/gtk/GtkDropTargetContextPeer.java | 125 ++++ .../java/awt/dnd/peer/gtk/GtkDropTargetPeer.java | 68 ++ .../gnu/java/awt/java2d/AbstractGraphics2D.java | 42 +- .../gnu/java/awt/java2d/CubicSegment.java | 98 ++- .../classpath/gnu/java/awt/java2d/LineSegment.java | 21 +- .../classpath/gnu/java/awt/java2d/QuadSegment.java | 24 +- libjava/classpath/gnu/java/awt/java2d/Segment.java | 37 +- .../gnu/java/awt/peer/ClasspathFontPeer.java | 7 +- .../gnu/java/awt/peer/ClasspathTextLayoutPeer.java | 104 --- .../java/awt/peer/gtk/BufferedImageGraphics.java | 2 - .../gnu/java/awt/peer/gtk/CairoGraphics2D.java | 222 ++++-- .../gnu/java/awt/peer/gtk/CairoSurface.java | 63 +- .../java/awt/peer/gtk/CairoSurfaceGraphics.java | 5 - .../gnu/java/awt/peer/gtk/ComponentGraphics.java | 146 +++- .../java/awt/peer/gtk/ComponentGraphicsCopy.java | 6 - .../gnu/java/awt/peer/gtk/FreetypeGlyphVector.java | 44 +- .../gnu/java/awt/peer/gtk/GdkFontPeer.java | 3 - .../java/awt/peer/gtk/GdkGraphicsEnvironment.java | 6 +- .../gnu/java/awt/peer/gtk/GdkPixbufDecoder.java | 3 - .../gnu/java/awt/peer/gtk/GdkTextLayout.java | 393 ---------- .../gnu/java/awt/peer/gtk/GtkButtonPeer.java | 5 - .../gnu/java/awt/peer/gtk/GtkCanvasPeer.java | 4 +- .../java/awt/peer/gtk/GtkCheckboxGroupPeer.java | 86 --- .../gnu/java/awt/peer/gtk/GtkCheckboxPeer.java | 167 ++++- .../java/awt/peer/gtk/GtkClipboardNotifier.java | 4 +- .../gnu/java/awt/peer/gtk/GtkComponentPeer.java | 93 ++- .../gnu/java/awt/peer/gtk/GtkContainerPeer.java | 3 - .../gnu/java/awt/peer/gtk/GtkDialogPeer.java | 5 +- .../gnu/java/awt/peer/gtk/GtkFramePeer.java | 8 +- .../classpath/gnu/java/awt/peer/gtk/GtkImage.java | 2 - .../gnu/java/awt/peer/gtk/GtkImageConsumer.java | 7 +- .../gnu/java/awt/peer/gtk/GtkLabelPeer.java | 8 +- .../gnu/java/awt/peer/gtk/GtkMenuBarPeer.java | 3 - .../gnu/java/awt/peer/gtk/GtkMenuItemPeer.java | 5 - .../gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java | 76 ++ .../gnu/java/awt/peer/gtk/GtkPanelPeer.java | 3 +- .../gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java | 1 - .../gnu/java/awt/peer/gtk/GtkScrollbarPeer.java | 2 - .../gnu/java/awt/peer/gtk/GtkToolkit.java | 111 ++- .../gnu/java/awt/peer/gtk/GtkVolatileImage.java | 3 + .../gnu/java/awt/peer/gtk/GtkWindowPeer.java | 48 +- .../java/awt/peer/gtk/VolatileImageGraphics.java | 16 +- .../gnu/java/awt/peer/qt/QtCheckboxPeer.java | 3 +- .../gnu/java/awt/peer/qt/QtComponentGraphics.java | 4 +- .../gnu/java/awt/peer/qt/QtComponentPeer.java | 3 +- .../gnu/java/awt/peer/qt/QtContainerPeer.java | 3 +- .../gnu/java/awt/peer/qt/QtDialogPeer.java | 4 +- .../gnu/java/awt/peer/qt/QtEmbeddedWindowPeer.java | 3 +- .../gnu/java/awt/peer/qt/QtFontMetrics.java | 5 +- .../classpath/gnu/java/awt/peer/qt/QtFontPeer.java | 3 +- .../classpath/gnu/java/awt/peer/qt/QtGraphics.java | 16 +- .../java/awt/peer/qt/QtGraphicsEnvironment.java | 3 +- .../classpath/gnu/java/awt/peer/qt/QtImage.java | 3 +- .../gnu/java/awt/peer/qt/QtImageConsumer.java | 7 +- .../java/awt/peer/qt/QtImageDirectGraphics.java | 21 +- .../gnu/java/awt/peer/qt/QtImageGraphics.java | 4 +- .../gnu/java/awt/peer/qt/QtMenuBarPeer.java | 3 +- .../gnu/java/awt/peer/qt/QtMenuItemPeer.java | 3 +- .../gnu/java/awt/peer/qt/QtPopupMenuPeer.java | 5 +- .../awt/peer/qt/QtScreenDeviceConfiguration.java | 4 +- .../gnu/java/awt/peer/qt/QtScrollPanePeer.java | 3 +- .../classpath/gnu/java/awt/peer/qt/QtToolkit.java | 35 +- .../gnu/java/awt/peer/qt/QtVolatileImage.java | 6 +- .../java/awt/peer/swing/SwingComponentPeer.java | 76 +- .../classpath/gnu/java/awt/peer/x/GLGraphics.java | 123 ++++ .../gnu/java/awt/peer/x/ImageConverter.java | 113 +++ .../gnu/java/awt/peer/x/KeyboardMapping.java | 415 +++++++++++ .../classpath/gnu/java/awt/peer/x/XDialogPeer.java | 61 ++ .../classpath/gnu/java/awt/peer/x/XEventPump.java | 287 ++++++++ .../classpath/gnu/java/awt/peer/x/XFontPeer.java | 766 ++++++++++++++++++++ .../classpath/gnu/java/awt/peer/x/XFontPeer2.java | 335 +++++++++ .../classpath/gnu/java/awt/peer/x/XFramePeer.java | 140 ++++ .../classpath/gnu/java/awt/peer/x/XGraphics.java | 792 +++++++++++++++++++++ .../classpath/gnu/java/awt/peer/x/XGraphics2D.java | 295 ++++++++ .../java/awt/peer/x/XGraphicsConfiguration.java | 118 +++ .../gnu/java/awt/peer/x/XGraphicsDevice.java | 166 +++++ .../gnu/java/awt/peer/x/XGraphicsEnvironment.java | 202 ++++++ libjava/classpath/gnu/java/awt/peer/x/XImage.java | 111 +++ .../gnu/java/awt/peer/x/XLightweightPeer.java | 56 ++ .../classpath/gnu/java/awt/peer/x/XToolkit.java | 608 ++++++++++++++++ .../classpath/gnu/java/awt/peer/x/XWindowPeer.java | 255 +++++++ .../gnu/java/awt/print/PostScriptGraphics2D.java | 4 +- 85 files changed, 6482 insertions(+), 1034 deletions(-) create mode 100644 libjava/classpath/gnu/java/awt/dnd/GtkMouseDragGestureRecognizer.java create mode 100644 libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDragSourceContextPeer.java create mode 100644 libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDropTargetContextPeer.java create mode 100644 libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDropTargetPeer.java delete mode 100644 libjava/classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java delete mode 100644 libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java delete mode 100644 libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java create mode 100644 libjava/classpath/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/GLGraphics.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/ImageConverter.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/KeyboardMapping.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XDialogPeer.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XEventPump.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XGraphics.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XGraphicsDevice.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XGraphicsEnvironment.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XImage.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XLightweightPeer.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XToolkit.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java (limited to 'libjava/classpath/gnu/java/awt') diff --git a/libjava/classpath/gnu/java/awt/ClasspathToolkit.java b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java index 1ec5664..968cc3b 100644 --- a/libjava/classpath/gnu/java/awt/ClasspathToolkit.java +++ b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java @@ -1,5 +1,5 @@ /* ClasspathToolkit.java -- Abstract superclass for Classpath toolkits. - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,7 +41,6 @@ package gnu.java.awt; import gnu.java.awt.EmbeddedWindow; import gnu.java.awt.peer.ClasspathFontPeer; import gnu.java.awt.peer.EmbeddedWindowPeer; -import gnu.java.awt.peer.ClasspathTextLayoutPeer; import gnu.java.security.action.SetAccessibleAction; import java.awt.AWTException; @@ -53,6 +52,7 @@ import java.awt.FontMetrics; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Image; +import java.awt.Point; import java.awt.Toolkit; import java.awt.font.FontRenderContext; import java.awt.image.ColorModel; @@ -120,10 +120,6 @@ public abstract class ClasspathToolkit */ public abstract ClasspathFontPeer getClasspathFontPeer (String name, Map attrs); - public abstract ClasspathTextLayoutPeer - getClasspathTextLayoutPeer (AttributedString str, FontRenderContext frc); - - /** * Creates a {@link Font}, in a platform-specific manner. * @@ -193,6 +189,9 @@ public abstract class ClasspathToolkit */ public abstract Font createFont(int format, InputStream stream); + /** + * Creates a RobotPeer on a given GraphicsDevice. + */ public abstract RobotPeer createRobot (GraphicsDevice screen) throws AWTException; @@ -206,8 +205,24 @@ public abstract class ClasspathToolkit /** * Used to register ImageIO SPIs provided by the toolkit. + * + * Our default implementation does nothing. */ public void registerImageIOSpis(IIORegistry reg) { } + + /** + * Returns the number of mouse buttons. + * (used by java.awt.MouseInfo). + * + * This dummy implementation returns -1 (no mouse). + * toolkit implementors should overload this method if possible. + * @since 1.5 + */ + public int getMouseNumberOfButtons() + { + return -1; + } } + diff --git a/libjava/classpath/gnu/java/awt/dnd/GtkMouseDragGestureRecognizer.java b/libjava/classpath/gnu/java/awt/dnd/GtkMouseDragGestureRecognizer.java new file mode 100644 index 0000000..1f0c3ad --- /dev/null +++ b/libjava/classpath/gnu/java/awt/dnd/GtkMouseDragGestureRecognizer.java @@ -0,0 +1,172 @@ +/* GtkMouseDragGestureRecognizer.java -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.dnd; + +import java.awt.Component; +import java.awt.Point; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.MouseDragGestureRecognizer; +import java.awt.event.MouseEvent; + +public class GtkMouseDragGestureRecognizer + extends MouseDragGestureRecognizer +{ + + public GtkMouseDragGestureRecognizer (DragSource ds) + { + this(ds, null, 0, null); + } + + public GtkMouseDragGestureRecognizer (DragSource ds, Component c) + { + this (ds, c, 0, null); + } + + public GtkMouseDragGestureRecognizer (DragSource ds, Component c, int act) + { + this(ds, c, act, null); + } + + public GtkMouseDragGestureRecognizer (DragSource ds, Component c, int act, + DragGestureListener dgl) + { + super(ds, c, act, dgl); + } + + public void registerListeners () + { + super.registerListeners(); + } + + public void unregisterListeners () + { + super.unregisterListeners(); + } + + public void mouseClicked (MouseEvent e) + { + // Nothing to do here. + } + + public void mousePressed (MouseEvent e) + { + events.clear(); + if (getDropActionFromEvent(e) != DnDConstants.ACTION_NONE) + appendEvent(e); + } + + public void mouseReleased (MouseEvent e) + { + events.clear(); + } + + public void mouseEntered (MouseEvent e) + { + events.clear(); + } + + public void mouseExited(MouseEvent e) + { + if (!events.isEmpty()) + if (getDropActionFromEvent(e) == DnDConstants.ACTION_NONE) + events.clear(); + } + + public void mouseDragged(MouseEvent e) + { + if (!events.isEmpty()) + { + int act = getDropActionFromEvent(e); + + if (act == DnDConstants.ACTION_NONE) + return; + + Point origin = ((MouseEvent) events.get(0)).getPoint(); + Point current = e.getPoint(); + int dx = Math.abs(origin.x - current.x); + int dy = Math.abs(origin.y - current.y); + int threshold = DragSource.getDragThreshold(); + + if (dx > threshold || dy > threshold) + fireDragGestureRecognized(act, origin); + else + appendEvent(e); + } + } + + public void mouseMoved (MouseEvent e) + { + // Nothing to do here. + } + + private int getDropActionFromEvent(MouseEvent e) + { + int modEx = e.getModifiersEx(); + int buttons = modEx & (MouseEvent.BUTTON1_DOWN_MASK + | MouseEvent.BUTTON2_DOWN_MASK | MouseEvent.BUTTON3_DOWN_MASK); + if (!(buttons == MouseEvent.BUTTON1_DOWN_MASK || + buttons == MouseEvent.BUTTON2_DOWN_MASK)) + return DnDConstants.ACTION_NONE; + + // Convert modifier to a drop action + int sourceActions = getSourceActions(); + int mod = modEx + & (MouseEvent.SHIFT_DOWN_MASK | MouseEvent.CTRL_DOWN_MASK); + switch (mod) + { + case MouseEvent.SHIFT_DOWN_MASK | MouseEvent.CTRL_DOWN_MASK: + return DnDConstants.ACTION_LINK & sourceActions; + case MouseEvent.CTRL_DOWN_MASK: + return DnDConstants.ACTION_COPY & sourceActions; + case MouseEvent.SHIFT_DOWN_MASK: + return DnDConstants.ACTION_MOVE & sourceActions; + default: + if ((sourceActions & DnDConstants.ACTION_MOVE) != 0) + return DnDConstants.ACTION_MOVE & sourceActions; + else if ((sourceActions & DnDConstants.ACTION_COPY) != 0) + return DnDConstants.ACTION_COPY & sourceActions; + else if ((sourceActions & DnDConstants.ACTION_LINK) != 0) + return DnDConstants.ACTION_LINK & sourceActions; + } + + return DnDConstants.ACTION_NONE & sourceActions; + } +} diff --git a/libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDragSourceContextPeer.java b/libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDragSourceContextPeer.java new file mode 100644 index 0000000..4f92298 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDragSourceContextPeer.java @@ -0,0 +1,174 @@ +/* GtkDragSourceContextPeer.java -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.dnd.peer.gtk; + +import gnu.java.awt.peer.gtk.GtkGenericPeer; + +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Image; +import java.awt.Point; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragSourceContext; +import java.awt.dnd.DragSourceDragEvent; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.InvalidDnDOperationException; +import java.awt.dnd.peer.DragSourceContextPeer; +import java.awt.peer.ComponentPeer; +import java.awt.peer.LightweightPeer; + +public class GtkDragSourceContextPeer + extends GtkGenericPeer + implements DragSourceContextPeer +{ + private ComponentPeer peer; + private Cursor cursor; + private DragSourceContext context; + + native void nativeStartDrag(Image i, int x, int y, int action, String target); + native void connectSignals(ComponentPeer comp); + native void create(ComponentPeer comp); + native void nativeSetCursor(int cursor); + + public GtkDragSourceContextPeer(DragGestureEvent e) + { + super(e.getComponent()); + Component comp = e.getComponent(); + peer = getComponentPeer(comp); + + create(peer); + connectSignals(peer); + cursor = comp.getCursor(); + } + + ComponentPeer getComponentPeer(Component c) + { + Component curr = c; + while (curr.getPeer() instanceof LightweightPeer) + curr = curr.getParent(); + + if (curr != null) + return curr.getPeer(); + return null; + } + + public void startDrag(DragSourceContext context, Cursor c, Image i, Point p) + throws InvalidDnDOperationException + { + this.context = context; + + if (p == null) + p = new Point(); + + // FIXME: use proper DataFlavor, not "text/plain". + // Also, add check to determine if dragging. + + setCursor(c); + nativeStartDrag(i, p.x, p.y, context.getTrigger().getDragAction(), + "text/plain"); + } + + public Cursor getCursor() + { + return cursor; + } + + public void setCursor(Cursor c) throws InvalidDnDOperationException + { + if (c != null) + { + nativeSetCursor(c.getType()); + cursor = c; + } + } + + public void transferablesFlavorsChanged() + { + // Nothing to do here. + } + + /** + * Called from native code. + */ + + public void dragEnter(int action, int modifiers) + { + context.dragEnter(new DragSourceDragEvent(context, action, + action + & context.getSourceActions(), + modifiers)); + } + + public void dragExit(int action, int x, int y) + { + context.dragExit(new DragSourceEvent(context, x, y)); + } + + public void dragDropEnd(int action, boolean success, int x, int y) + { + context.dragDropEnd(new DragSourceDropEvent(context, action, success, x, y)); + } + + public void dragMouseMoved(int action, int modifiers) + { + context.dragMouseMoved(new DragSourceDragEvent(context, + action, + action + & context.getSourceActions(), + modifiers)); + } + + public void dragOver(int action, int modifiers) + { + context.dragOver(new DragSourceDragEvent(context, action, + action + & context.getSourceActions(), + modifiers)); + } + + public void dragActionChanged(int newAction, int modifiers) + { + context.dropActionChanged(new DragSourceDragEvent(context, + newAction, + newAction + & context.getSourceActions(), + modifiers)); + } +} diff --git a/libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDropTargetContextPeer.java b/libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDropTargetContextPeer.java new file mode 100644 index 0000000..50cd95d --- /dev/null +++ b/libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDropTargetContextPeer.java @@ -0,0 +1,125 @@ +/* GtkDropTargetContextPeer.java -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.dnd.peer.gtk; + +import gnu.java.awt.peer.gtk.GtkGenericPeer; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DropTarget; +import java.awt.dnd.InvalidDnDOperationException; +import java.awt.dnd.peer.DropTargetContextPeer; + +public class GtkDropTargetContextPeer + extends GtkGenericPeer + implements DropTargetContextPeer +{ + + public GtkDropTargetContextPeer() + { + super(null); + } + + public void setTargetActions(int actions) + { + // FIXME: Not Implemented + + } + + public int getTargetActions() + { + // FIXME: Not Implemented + return 0; + } + + public DropTarget getDropTarget() + { + // FIXME: Not Implemented + return null; + } + + public DataFlavor[] getTransferDataFlavors() + { + // FIXME: Not Implemented + return null; + } + + public Transferable getTransferable() throws InvalidDnDOperationException + { + // FIXME: Not Implemented + return null; + } + + public boolean isTransferableJVMLocal() + { + // FIXME: Not Implemented + return false; + } + + public void acceptDrag(int dragAction) + { + // FIXME: Not Implemented + + } + + public void rejectDrag() + { + // FIXME: Not Implemented + + } + + public void acceptDrop(int dropAction) + { + // FIXME: Not Implemented + + } + + public void rejectDrop() + { + // FIXME: Not Implemented + + } + + public void dropComplete(boolean success) + { + // FIXME: Not Implemented + + } + +} diff --git a/libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDropTargetPeer.java b/libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDropTargetPeer.java new file mode 100644 index 0000000..88b75ad --- /dev/null +++ b/libjava/classpath/gnu/java/awt/dnd/peer/gtk/GtkDropTargetPeer.java @@ -0,0 +1,68 @@ +/* GtkDropTargetPeer.java -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.dnd.peer.gtk; + +import gnu.java.awt.peer.gtk.GtkGenericPeer; + +import java.awt.dnd.DropTarget; +import java.awt.dnd.peer.DropTargetPeer; + +public class GtkDropTargetPeer + extends GtkGenericPeer + implements DropTargetPeer +{ + + public GtkDropTargetPeer() + { + super(null); + } + + public void addDropTarget(DropTarget target) + { + // FIXME: Not Implemented + + } + + public void removeDropTarget(DropTarget target) + { + // FIXME: Not Implemented + + } + +} diff --git a/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java b/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java index f057d8b..9d01724 100644 --- a/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java @@ -39,6 +39,7 @@ package gnu.java.awt.java2d; import java.awt.AWTError; import java.awt.AlphaComposite; +import java.awt.AWTPermission; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; @@ -72,6 +73,7 @@ import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; import java.awt.image.ImageObserver; import java.awt.image.Raster; import java.awt.image.RenderedImage; @@ -144,7 +146,7 @@ public abstract class AbstractGraphics2D /** * The transformation for this Graphics2D instance */ - private AffineTransform transform; + protected AffineTransform transform; /** * The foreground. @@ -539,6 +541,15 @@ public abstract class AbstractGraphics2D */ public void setComposite(Composite comp) { + if (! (comp instanceof AlphaComposite)) + { + // FIXME: this check is only required "if this Graphics2D + // context is drawing to a Component on the display screen". + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new AWTPermission("readDisplayPixels")); + } + composite = comp; if (! (comp.equals(AlphaComposite.SrcOver))) isOptimized = false; @@ -2054,7 +2065,34 @@ public abstract class AbstractGraphics2D * * @return the destination raster */ - protected abstract WritableRaster getDestinationRaster(); + protected WritableRaster getDestinationRaster() + { + // TODO: Ideally we would fetch the xdrawable's surface pixels for + // initialization of the raster. + Rectangle db = getDeviceBounds(); + if (destinationRaster == null) + { + int[] bandMasks = new int[]{ 0xFF0000, 0xFF00, 0xFF }; + destinationRaster = Raster.createPackedRaster(DataBuffer.TYPE_INT, + db.width, db.height, + bandMasks, null); + // Initialize raster with white. + int x0 = destinationRaster.getMinX(); + int x1 = destinationRaster.getWidth() + x0; + int y0 = destinationRaster.getMinY(); + int y1 = destinationRaster.getHeight() + y0; + int numBands = destinationRaster.getNumBands(); + for (int y = y0; y < y1; y++) + { + for (int x = x0; x < x1; x++) + { + for (int b = 0; b < numBands; b++) + destinationRaster.setSample(x, y, b, 255); + } + } + } + return destinationRaster; + } /** * Notifies the backend that the raster has changed in the specified diff --git a/libjava/classpath/gnu/java/awt/java2d/CubicSegment.java b/libjava/classpath/gnu/java/awt/java2d/CubicSegment.java index 1e568f7..bf66be8 100644 --- a/libjava/classpath/gnu/java/awt/java2d/CubicSegment.java +++ b/libjava/classpath/gnu/java/awt/java2d/CubicSegment.java @@ -39,6 +39,7 @@ exception statement from your version. */ package gnu.java.awt.java2d; +import java.awt.geom.CubicCurve2D; import java.awt.geom.Point2D; /** @@ -78,34 +79,89 @@ public class CubicSegment extends Segment */ public Object clone() { - return new CubicSegment(P1.getX(), P1.getY(), cp1.getX(), cp1.getY(), - cp2.getX(), cp2.getY(), P2.getX(), P2.getY()); + CubicSegment segment = null; + + try + { + segment = (CubicSegment) super.clone(); + + segment.P1 = (Point2D) P1.clone(); + segment.P2 = (Point2D) P2.clone(); + segment.cp1 = (Point2D) cp1.clone(); + segment.cp2 = (Point2D) cp2.clone(); + } + catch (CloneNotSupportedException cnse) + { + InternalError ie = new InternalError(); + ie.initCause(cnse); + throw ie; + } + + return segment; } /** - * Get the "top" and "bottom" segments of this segment. - * First array element is p0 + normal, second is p0 - normal. + * Get the "top" and "bottom" segments of this segment. First array element is + * p0 + normal, second is p0 - normal. */ public Segment[] getDisplacedSegments(double radius) { + // It is, apparently, impossible to derive a curve parallel to a bezier + // curve (unless it's a straight line), so we have no choice but to + // approximate the displaced segments. Similar to FlattenPathIterator. + + Segment segmentTop = null; + Segment segmentBottom = null; this.radius = radius; - double x0 = P1.getX(); - double y0 = P1.getY(); - double x1 = cp1.getX(); - double y1 = cp1.getY(); - double x2 = cp2.getX(); - double y2 = cp2.getY(); - double x3 = P2.getX(); - double y3 = P2.getY(); - double[] p1 = normal(x0, y0, x1, y1); - double[] p2 = normal(x2, y2, x3, y3); - - // FIXME: Doesn't compile. - // return new Segment[]{s1, s2}; - return new Segment[0]; + CubicCurve2D[] curves = new CubicCurve2D[10]; + curves[0] = new CubicCurve2D.Double(P1.getX(), P1.getY(), cp1.getX(), + cp1.getY(), cp2.getX(), cp2.getY(), + P2.getX(), P2.getY()); + int numCurves = 1; + + // Hard-coded a recursion limit of 10 and flatness of 1... should we make + // this an option somewhere? + while (numCurves > 0) + { + // The curve is flat enough, or we've reached our recursion limit, + // so take the current start/end points and add it as a line segment + // to our final approximated curves + if (curves[numCurves - 1].getFlatnessSq() <= (radius / 3) || numCurves == 10) + { + Segment[] displaced = new LineSegment( + curves[numCurves - 1].getP1(), + curves[numCurves - 1].getP2()).getDisplacedSegments(radius); + if (segmentTop == null) + { + segmentTop = displaced[0]; + segmentBottom = displaced[1]; + } + else + { + segmentTop.add(displaced[0]); + segmentBottom.add(displaced[1]); + } + numCurves--; + } + + // Otherwise, subdivide again and continue + else + { + CubicCurve2D left = new CubicCurve2D.Double(); + CubicCurve2D right = new CubicCurve2D.Double(); + curves[numCurves - 1].subdivide(left, right); + curves[numCurves - 1] = right; + curves[numCurves] = left; + curves[numCurves - 1] = right; + curves[numCurves] = left; + numCurves++; + } + } + + return new Segment[] { segmentTop, segmentBottom }; } - + public void reverse() { Point2D temp = P1; @@ -116,12 +172,12 @@ public class CubicSegment extends Segment cp2 = temp; } - public double[] first() + public double[] cp1() { return new double[]{cp1.getX(), cp1.getY()}; } - public double[] last() + public double[] cp2() { return new double[]{cp2.getX(), cp2.getY()}; } diff --git a/libjava/classpath/gnu/java/awt/java2d/LineSegment.java b/libjava/classpath/gnu/java/awt/java2d/LineSegment.java index 9c0bcc7..0395fd0 100644 --- a/libjava/classpath/gnu/java/awt/java2d/LineSegment.java +++ b/libjava/classpath/gnu/java/awt/java2d/LineSegment.java @@ -62,7 +62,22 @@ public class LineSegment extends Segment */ public Object clone() { - return new LineSegment(P1, P2); + LineSegment segment = null; + + try + { + segment = (LineSegment) super.clone(); + segment.P1 = (Point2D) P1.clone(); + segment.P2 = (Point2D) P2.clone(); + } + catch (CloneNotSupportedException cnse) + { + InternalError ie = new InternalError(); + ie.initCause(cnse); + throw ie; + } + + return segment; } /** @@ -91,12 +106,12 @@ public class LineSegment extends Segment P2 = p; } - public double[] first() + public double[] cp1() { return new double[]{P2.getX(), P2.getY()}; } - public double[] last() + public double[] cp2() { return new double[]{P1.getX(), P1.getY()}; } diff --git a/libjava/classpath/gnu/java/awt/java2d/QuadSegment.java b/libjava/classpath/gnu/java/awt/java2d/QuadSegment.java index 9c15a8c..5e15fe8 100644 --- a/libjava/classpath/gnu/java/awt/java2d/QuadSegment.java +++ b/libjava/classpath/gnu/java/awt/java2d/QuadSegment.java @@ -88,8 +88,24 @@ public class QuadSegment extends Segment */ public Object clone() { - return new QuadSegment(P1.getX(), P1.getY(), cp.getX(), cp.getY(), - P2.getX(), P2.getY()); + QuadSegment segment = null; + + try + { + segment = (QuadSegment) super.clone(); + + segment.P1 = (Point2D) P1.clone(); + segment.P2 = (Point2D) P2.clone(); + segment.cp = (Point2D) cp.clone(); + } + catch (CloneNotSupportedException cnse) + { + InternalError ie = new InternalError(); + ie.initCause(cnse); + throw ie; + } + + return segment; } /** @@ -201,12 +217,12 @@ public class QuadSegment extends Segment P2 = p; } - public double[] first() + public double[] cp1() { return new double[]{cp.getX(), cp.getY()}; } - public double[] last() + public double[] cp2() { return new double[]{cp.getX(), cp.getY()}; } diff --git a/libjava/classpath/gnu/java/awt/java2d/Segment.java b/libjava/classpath/gnu/java/awt/java2d/Segment.java index 9a985f6..df1f676 100644 --- a/libjava/classpath/gnu/java/awt/java2d/Segment.java +++ b/libjava/classpath/gnu/java/awt/java2d/Segment.java @@ -42,24 +42,38 @@ import java.awt.geom.Point2D; public abstract class Segment implements Cloneable { - // segment type, PathIterator segment types are used. + // Start and end points of THIS segment public Point2D P1; public Point2D P2; + + // Segments can be linked together internally as a linked list + public Segment first; public Segment next; public Segment last; + + // Half the stroke width protected double radius; + /** + * Create a new, empty segment + */ public Segment() { P1 = P2 = null; + first = this; next = null; last = this; } + /** + * Add a segment to the polygon + * @param newsegment segment to add + */ public void add(Segment newsegment) { + newsegment.first = first; last.next = newsegment; - last = last.next; + last = last.next.last; } /** @@ -68,6 +82,7 @@ public abstract class Segment implements Cloneable public void reverseAll() { reverse(); + first = last; Segment v = next; Segment former = this; next = null; @@ -91,7 +106,7 @@ public abstract class Segment implements Cloneable /** * Get the normal vector to the slope of the line. - * Returns: 0.5*width*(norm of derivative of the (x0,y0)-(x1,y1) vector) + * @return vector of length radius, normal to the (x0,y0)-(x1,y1) vector) */ protected double[] normal(double x0, double y0, double x1, double y1) { @@ -117,6 +132,9 @@ public abstract class Segment implements Cloneable return new double[]{ dx, dy }; } + /** + * Reverse the current segment + */ public abstract void reverse(); /** @@ -125,7 +143,16 @@ public abstract class Segment implements Cloneable */ public abstract Segment[] getDisplacedSegments(double radius); - public abstract double[] first(); - public abstract double[] last(); + /** + * Returns the coordinates of the first control point, or the start point + * for a line segment. + */ + public abstract double[] cp1(); + + /** + * Returns the coordinates of the second control point, or the end point + * for a line segment. + */ + public abstract double[] cp2(); } diff --git a/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java b/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java index 78ab3a9..dad7bb0 100644 --- a/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/ClasspathFontPeer.java @@ -145,7 +145,8 @@ public abstract class ClasspathFontPeer uname.equals ("SERIF") || uname.equals ("MONOSPACED") || uname.equals ("DIALOG") || - uname.equals ("DIALOGINPUT")); + uname.equals ("DIALOGINPUT") || + uname.equals ("DEFAULT")); } protected static String logicalFontNameToFaceName (String name) @@ -161,6 +162,8 @@ public abstract class ClasspathFontPeer return "Helvetica"; else if (uname.equals ("DIALOGINPUT")) return "Helvetica"; + else if (uname.equals ("DEFAULT")) + return "Dialog.plain"; else return "Helvetica"; } @@ -233,7 +236,7 @@ public abstract class ClasspathFontPeer family = (String) attribs.get (TextAttribute.FAMILY); if (name == null) - name = "SansSerif"; + name = "Default"; if (attribs.containsKey (TextAttribute.WEIGHT)) { diff --git a/libjava/classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java b/libjava/classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java deleted file mode 100644 index 70df2ef..0000000 --- a/libjava/classpath/gnu/java/awt/peer/ClasspathTextLayoutPeer.java +++ /dev/null @@ -1,104 +0,0 @@ -/* ClasspathTextLayoutPeer.java - Copyright (C) 2003 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.java.awt.peer; - -import java.awt.Graphics2D; -import java.awt.Shape; -import java.awt.font.TextHitInfo; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; - -/** - * @author Graydon Hoare - */ - -public interface ClasspathTextLayoutPeer -{ - TextHitInfo getStrongCaret (TextHitInfo hit1, - TextHitInfo hit2); - - void draw (Graphics2D g2, float x, float y); - - byte getBaseline (); - - boolean isLeftToRight (); - boolean isVertical (); - - float getAdvance (); - float getAscent (); - float getDescent (); - float getLeading (); - - int getCharacterCount (); - byte getCharacterLevel (int index); - - float[] getBaselineOffsets (); - Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint); - Rectangle2D getBounds (); - - float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds); - Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds); - Shape[] getCaretShapes (int offset, Rectangle2D bounds, - TextLayout.CaretPolicy policy); - - Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint, - Rectangle2D bounds); - int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint, - TextHitInfo secondEndpoint); - - TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy); - TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy); - TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds); - TextHitInfo getVisualOtherHit (TextHitInfo hit); - - float getVisibleAdvance (); - Shape getOutline (AffineTransform tx); - Shape getVisualHighlightShape (TextHitInfo firstEndpoint, - TextHitInfo secondEndpoint, - Rectangle2D bounds); - - TextLayout getJustifiedLayout (float justificationWidth); - void handleJustify (float justificationWidth); - - Object clone (); - int hashCode (); - boolean equals (ClasspathTextLayoutPeer tl); - String toString (); -} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java index d9d300d..6a74eab 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java @@ -40,10 +40,8 @@ package gnu.java.awt.peer.gtk; import java.awt.Color; import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.Image; -import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; import java.awt.font.GlyphVector; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java index 9f8f494..b665f56 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java @@ -40,6 +40,7 @@ package gnu.java.awt.peer.gtk; import gnu.java.awt.ClasspathToolkit; +import java.awt.AWTPermission; import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; @@ -52,11 +53,11 @@ import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.Image; import java.awt.Paint; +import java.awt.Polygon; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; -import java.awt.Polygon; import java.awt.TexturePaint; import java.awt.Toolkit; import java.awt.font.FontRenderContext; @@ -65,8 +66,8 @@ import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.geom.Arc2D; import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; -import java.awt.geom.Line2D; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; @@ -322,6 +323,11 @@ public abstract class CairoGraphics2D extends Graphics2D * Set the current transform matrix */ private native void cairoSetMatrix(long pointer, double[] m); + + /** + * Scaling method + */ + private native void cairoScale(long pointer, double x, double y); /** * Set the compositing operator @@ -369,6 +375,18 @@ public abstract class CairoGraphics2D extends Graphics2D */ private native void cairoRectangle(long pointer, double x, double y, double width, double height); + + /** + * Appends an arc to the current path + */ + private native void cairoArc(long pointer, double x, double y, + double radius, double angle1, double angle2); + + /** + * Save / restore a cairo path + */ + private native void cairoSave(long pointer); + private native void cairoRestore(long pointer); /** * New current path @@ -427,6 +445,46 @@ public abstract class CairoGraphics2D extends Graphics2D */ private native void cairoSurfaceSetFilter(long pointer, int filter); + /** + * Draws a line from (x1,y1) to (x2,y2). + * + * @param pointer the native pointer + * + * @param x1 the x coordinate of the starting point + * @param y1 the y coordinate of the starting point + * @param x2 the x coordinate of the end point + * @param y2 the y coordinate of the end point + */ + private native void cairoDrawLine(long pointer, double x1, double y1, + double x2, double y2); + + /** + * Draws a rectangle at starting point (x,y) and with the specified width + * and height. + * + * @param pointer the native pointer + * @param x the x coordinate of the upper left corner + * @param y the y coordinate of the upper left corner + * @param w the width of the rectangle + * @param h the height of the rectangle + */ + private native void cairoDrawRect(long pointer, double x, double y, double w, + double h); + + /** + * Fills a rectangle at starting point (x,y) and with the specified width + * and height. + * + * @param pointer the native pointer + * @param x the x coordinate of the upper left corner + * @param y the y coordinate of the upper left corner + * @param w the width of the rectangle + * @param h the height of the rectangle + */ + private native void cairoFillRect(long pointer, double x, double y, double w, + double h); + + ///////////////////////// TRANSFORMS /////////////////////////////////// /** * Set the current transform @@ -625,8 +683,8 @@ public abstract class CairoGraphics2D extends Graphics2D int width = (int) tp.getAnchorRect().getWidth(); int height = (int) tp.getAnchorRect().getHeight(); - double scaleX = (width+1) / (double) img.getWidth(); - double scaleY = (height+1) / (double) img.getHeight(); + double scaleX = width / (double) img.getWidth(); + double scaleY = height / (double) img.getHeight(); AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0); AffineTransformOp op = new AffineTransformOp(at, getRenderingHints()); @@ -737,7 +795,7 @@ public abstract class CairoGraphics2D extends Graphics2D else { GeneralPath p = new GeneralPath(); - PathIterator pi = clip.getPathIterator(new AffineTransform()); + PathIterator pi = clip.getPathIterator(null); p.append(pi, false); return p; } @@ -847,6 +905,12 @@ public abstract class CairoGraphics2D extends Graphics2D } else { + // FIXME: this check is only required "if this Graphics2D + // context is drawing to a Component on the display screen". + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new AWTPermission("readDisplayPixels")); + // FIXME: implement general Composite support throw new java.lang.UnsupportedOperationException(); } @@ -857,54 +921,79 @@ public abstract class CairoGraphics2D extends Graphics2D public void draw(Shape s) { if ((stroke != null && ! (stroke instanceof BasicStroke)) - || (comp instanceof AlphaComposite - && ((AlphaComposite) comp).getAlpha() != 1.0)) + || (comp instanceof AlphaComposite && ((AlphaComposite) comp).getAlpha() != 1.0)) { - // FIXME: This is a hack to work around BasicStrokes's current - // limitations wrt cubic curves. - // See CubicSegment.getDisplacedSegments(). - if (stroke instanceof BasicStroke) - { - PathIterator flatten = s.getPathIterator(new AffineTransform(), - 1.0); - GeneralPath p = new GeneralPath(); - p.append(flatten, false); - s = p; - } - fill(stroke.createStrokedShape(s)); - return; + // Cairo doesn't support stroking with alpha, so we create the stroked + // shape and fill with alpha instead + fill(stroke.createStrokedShape(s)); + return; } - cairoNewPath(nativePointer); - - if (s instanceof Rectangle2D) - { - Rectangle2D r = (Rectangle2D) s; - cairoRectangle(nativePointer, shifted(r.getX(), shiftDrawCalls), - shifted(r.getY(), shiftDrawCalls), r.getWidth(), - r.getHeight()); - } - else - walkPath(s.getPathIterator(null), shiftDrawCalls); + createPath(s); cairoStroke(nativePointer); } public void fill(Shape s) { + createPath(s); + + double alpha = 1.0; + if (comp instanceof AlphaComposite) + alpha = ((AlphaComposite) comp).getAlpha(); + cairoFill(nativePointer, alpha); + } + + private void createPath(Shape s) + { cairoNewPath(nativePointer); + + // Optimize rectangles, since there is a direct Cairo function if (s instanceof Rectangle2D) { - Rectangle2D r = (Rectangle2D) s; - cairoRectangle(nativePointer, r.getX(), r.getY(), r.getWidth(), + Rectangle2D r = (Rectangle2D) s; + cairoRectangle(nativePointer, shifted(r.getX(), shiftDrawCalls), + shifted(r.getY(), shiftDrawCalls), r.getWidth(), r.getHeight()); } - else - walkPath(s.getPathIterator(null), false); - double alpha = 1.0; - if (comp instanceof AlphaComposite) - alpha = ((AlphaComposite) comp).getAlpha(); - cairoFill(nativePointer, alpha); + // We can optimize ellipses too; however we don't bother optimizing arcs: + // the iterator is fast enough (an ellipse requires 5 steps using the + // iterator, while most arcs are only 2-3) + else if (s instanceof Ellipse2D) + { + Ellipse2D e = (Ellipse2D) s; + + double radius = Math.min(e.getHeight(), e.getWidth()) / 2; + + // Cairo only draws circular shapes, but we can use a stretch to make + // them into ellipses + double xscale = 1, yscale = 1; + if (e.getHeight() != e.getWidth()) + { + cairoSave(nativePointer); + + if (e.getHeight() < e.getWidth()) + xscale = e.getWidth() / (radius * 2); + else + yscale = e.getHeight() / (radius * 2); + + if (xscale != 1 || yscale != 1) + cairoScale(nativePointer, xscale, yscale); + } + + cairoArc(nativePointer, + shifted(e.getCenterX() / xscale, shiftDrawCalls), + shifted(e.getCenterY() / yscale, shiftDrawCalls), radius, 0, + Math.PI * 2); + + if (xscale != 1 || yscale != 1) + cairoRestore(nativePointer); + } + + // All other shapes are broken down and drawn in steps using the + // PathIterator + else + walkPath(s.getPathIterator(null), shiftDrawCalls); } /** @@ -940,12 +1029,19 @@ public abstract class CairoGraphics2D extends Graphics2D public void drawLine(int x1, int y1, int x2, int y2) { - draw(new Line2D.Double(x1, y1, x2, y2)); + // The coordinates being pairwise identical means one wants + // to draw a single pixel. This is emulated by drawing + // a one pixel sized rectangle. + if (x1 == x2 && y1 == y2) + cairoFillRect(nativePointer, x1, y1, 1, 1); + else + cairoDrawLine(nativePointer, x1 + 0.5, y1 + 0.5, x2 + 0.5, y2 + 0.5); } public void drawRect(int x, int y, int width, int height) { - draw(new Rectangle(x, y, width, height)); + cairoDrawRect(nativePointer, shifted(x, shiftDrawCalls), + shifted(y, shiftDrawCalls), width, height); } public void fillArc(int x, int y, int width, int height, int startAngle, @@ -958,7 +1054,7 @@ public abstract class CairoGraphics2D extends Graphics2D public void fillRect(int x, int y, int width, int height) { - fill(new Rectangle(x, y, width, height)); + cairoFillRect(nativePointer, x, y, width, height); } public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) @@ -1137,6 +1233,9 @@ public abstract class CairoGraphics2D extends Graphics2D if (img == null) return false; + if (xform == null) + xform = new AffineTransform(); + // In this case, xform is an AffineTransform that transforms bounding // box of the specified image from image space to user space. However // when we pass this transform to cairo, cairo will use this transform @@ -1160,6 +1259,7 @@ public abstract class CairoGraphics2D extends Graphics2D // Note - this can get us in trouble when the gdk lock is re-acquired. // for example by VolatileImage. See ComponentGraphics for how we work // around this. + if( !(img instanceof BufferedImage) ) { ImageProducer source = img.getSource(); @@ -1176,6 +1276,7 @@ public abstract class CairoGraphics2D extends Graphics2D // If this BufferedImage has a BufferedImageGraphics object, // use the cached CairoSurface that BIG is drawing onto + if( BufferedImageGraphics.bufferedImages.get( b ) != null ) db = (DataBuffer)BufferedImageGraphics.bufferedImages.get( b ); else @@ -1190,6 +1291,7 @@ public abstract class CairoGraphics2D extends Graphics2D if(db instanceof CairoSurface) { ((CairoSurface)db).drawSurface(nativePointer, i2u, alpha); + updateColor(); return true; } @@ -1206,24 +1308,7 @@ public abstract class CairoGraphics2D extends Graphics2D setPaint( oldPaint ); } - int[] pixels; - - // Shortcut for easy color models. - if( b.getColorModel().equals(rgb32) ) - { - pixels = ((DataBufferInt)db).getData(); - for(int i = 0; i < pixels.length; i++) - pixels[i] |= 0xFF000000; - } - else if( b.getColorModel().equals(argb32) ) - { - pixels = ((DataBufferInt)db).getData(); - } - else - { - pixels = b.getRGB(0, 0, width, height, - null, 0, width); - } + int[] pixels = b.getRGB(0, 0, width, height, null, 0, width); drawPixels(nativePointer, pixels, width, height, width, i2u, alpha); @@ -1249,7 +1334,9 @@ public abstract class CairoGraphics2D extends Graphics2D public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y) { - Image filtered = op.filter(image, null); + Image filtered = image; + if (op != null) + filtered = op.filter(image, null); drawImage(filtered, new AffineTransform(1f, 0f, 0f, 1f, x, y), null, null); } @@ -1317,7 +1404,7 @@ public abstract class CairoGraphics2D extends Graphics2D else { cy = dy2; ch = dy1 - dy2; } - setClip( cx, cy, cw, ch ); + clipRect( cx, cy, cw, ch ); AffineTransform tx = new AffineTransform(); tx.translate( dx1 - sx1*scaleX, dy1 - sy1*scaleY ); @@ -1358,6 +1445,10 @@ public abstract class CairoGraphics2D extends Graphics2D public void drawGlyphVector(GlyphVector gv, float x, float y) { double alpha = 1.0; + + if( gv.getNumGlyphs() <= 0 ) + return; + if (comp instanceof AlphaComposite) alpha = ((AlphaComposite) comp).getAlpha(); if (gv instanceof FreetypeGlyphVector && alpha == 1.0) @@ -1367,8 +1458,11 @@ public abstract class CairoGraphics2D extends Graphics2D float[] positions = gv.getGlyphPositions (0, n, null); setFont (gv.getFont ()); - cairoDrawGlyphVector(nativePointer, (GdkFontPeer)getFont().getPeer(), - x, y, n, codes, positions); + synchronized( this.font ) + { + cairoDrawGlyphVector(nativePointer, (GdkFontPeer)getFont().getPeer(), + x, y, n, codes, positions); + } } else { diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java index 5ccd2e1..78bc1e0 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java @@ -38,26 +38,16 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.Graphics; -import java.awt.Color; -import java.awt.Image; import java.awt.Point; import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; import java.awt.image.DataBuffer; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DirectColorModel; -import java.io.File; -import java.io.IOException; +import java.nio.ByteOrder; import java.util.Hashtable; -import java.util.Vector; -import java.io.ByteArrayOutputStream; -import java.io.BufferedInputStream; -import java.net.URL; -import gnu.classpath.Pointer; /** * CairoSurface - wraps a Cairo surface. @@ -79,10 +69,10 @@ public class CairoSurface extends DataBuffer long bufferPointer; - static ColorModel nativeModel = new DirectColorModel(32, - 0x000000FF, - 0x0000FF00, + static ColorModel nativeModel = new DirectColorModel(32, 0x00FF0000, + 0x0000FF00, + 0x000000FF, 0xFF000000); /** @@ -177,28 +167,45 @@ public class CairoSurface extends DataBuffer height = image.height; create(width, height, width); - + if(surfacePointer == 0 || bufferPointer == 0) throw new Error("Could not allocate bitmap."); - + // Copy the pixel data from the GtkImage. int[] data = image.getPixels(); // Swap ordering from GdkPixbuf to Cairo - for(int i = 0; i < data.length; i++ ) + if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) + { + for (int i = 0; i < data.length; i++ ) + { + // On a big endian system we get a RRGGBBAA data array. + int alpha = data[i] & 0xFF; + if( alpha == 0 ) // I do not know why we need this, but it works. + data[i] = 0; + else + { + // Cairo needs a ARGB32 native array. + data[i] = (data[i] >>> 8) | (alpha << 24); + } + } + } + else { - int alpha = (data[i] & 0xFF000000) >> 24; - if( alpha == 0 ) // I do not know why we need this, but it works. - data[i] = 0; - else + for (int i = 0; i < data.length; i++ ) { - int r = (((data[i] & 0x00FF0000) >> 16) ); - int g = (((data[i] & 0x0000FF00) >> 8) ); - int b = ((data[i] & 0x000000FF) ); - data[i] = (( alpha << 24 ) & 0xFF000000) - | (( b << 16 ) & 0x00FF0000) - | (( g << 8 ) & 0x0000FF00) - | ( r & 0x000000FF); + // On a little endian system we get a AABBGGRR data array. + int alpha = data[i] & 0xFF000000; + if( alpha == 0 ) // I do not know why we need this, but it works. + data[i] = 0; + else + { + int b = (data[i] & 0xFF0000) >> 16; + int g = (data[i] & 0xFF00); + int r = (data[i] & 0xFF) << 16; + // Cairo needs a ARGB32 native array. + data[i] = alpha | r | g | b; + } } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java index 91f0b49..7bd136c 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java @@ -39,14 +39,9 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.Graphics; -import java.awt.Color; import java.awt.GraphicsEnvironment; -import java.awt.Image; -import java.awt.Point; -import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.geom.Rectangle2D; -import java.awt.image.*; /** * Implementation of Graphics2D on a Cairo surface. diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java index d1d3c28..ffa78e9 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java @@ -39,7 +39,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.Color; -import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; @@ -47,16 +46,14 @@ import java.awt.Image; import java.awt.Rectangle; import java.awt.Shape; import java.awt.Toolkit; -import java.awt.Point; -import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; -import java.awt.image.ImagingOpException; import java.awt.image.RenderedImage; +import gnu.classpath.Pointer; /** * ComponentGraphics - context for drawing directly to a component, @@ -66,6 +63,8 @@ import java.awt.image.RenderedImage; */ public class ComponentGraphics extends CairoGraphics2D { + private static final boolean hasXRenderExtension = hasXRender(); + private GtkComponentPeer component; protected long cairo_t; @@ -164,13 +163,27 @@ public class ComponentGraphics extends CairoGraphics2D */ public static native boolean hasXRender(); + /** + * This is a utility method (used by GtkComponentPeer) for grabbing the + * image of a component. + */ + private static native Pointer nativeGrab(GtkComponentPeer component); private native void copyAreaNative(GtkComponentPeer component, int x, int y, int width, int height, int dx, int dy); private native void drawVolatile(GtkComponentPeer component, long vimg, int x, int y, - int width, int height); + int width, int height, int cx, int cy, + int cw, int ch); + + /** + * Not really related (moveme?). Utility method used by GtkComponent. + */ + public static GtkImage grab( GtkComponentPeer component ) + { + return new GtkImage( nativeGrab( component ) ); + } /** * Returns a Graphics2D object for a component, either an instance of this @@ -178,7 +191,7 @@ public class ComponentGraphics extends CairoGraphics2D */ public static Graphics2D getComponentGraphics(GtkComponentPeer component) { - if( hasXRender() ) + if( hasXRenderExtension ) return new ComponentGraphics(component); Rectangle r = component.awtComponent.getBounds(); @@ -285,21 +298,24 @@ public class ComponentGraphics extends CairoGraphics2D if (img instanceof GtkVolatileImage) { GtkVolatileImage vimg = (GtkVolatileImage) img; - int type = transform.getType(); - if (type == AffineTransform.TYPE_IDENTITY) - { - drawVolatile(component, vimg.nativePointer, - x, y, vimg.width, vimg.height); - return true; - } - else if (type == AffineTransform.TYPE_TRANSLATION) - { - x += transform.getTranslateX(); - y += transform.getTranslateY(); - drawVolatile(component, vimg.nativePointer, - x, y, vimg.width, vimg.height); - return true; - } + int type = transform.getType(); + if ((type == AffineTransform.TYPE_IDENTITY + || type == AffineTransform.TYPE_TRANSLATION) + && (clip == null || clip instanceof Rectangle2D)) + { + Rectangle2D r = (Rectangle2D) clip; + if (r == null) + r = getRealBounds(); + x += transform.getTranslateX(); + y += transform.getTranslateY(); + drawVolatile(component, vimg.nativePointer, + x, y, vimg.width, vimg.height, + (int) (r.getX() + transform.getTranslateX()), + (int) (r.getY() + transform.getTranslateY()), + (int) r.getWidth(), + (int) r.getHeight()); + return true; + } else return super.drawImage(vimg.getSnapshot(), x, y, observer); } @@ -323,24 +339,28 @@ public class ComponentGraphics extends CairoGraphics2D // If it is a GtkVolatileImage with an "easy" transform then // draw directly. Always pass a BufferedImage to super to avoid // deadlock (see Note in CairoGraphics.drawImage()). - if (img instanceof GtkVolatileImage) + if (img instanceof GtkVolatileImage + && (clip == null || clip instanceof Rectangle2D)) { GtkVolatileImage vimg = (GtkVolatileImage) img; - int type = transform.getType(); - if (type == AffineTransform.TYPE_IDENTITY) - { - drawVolatile(component, vimg.nativePointer, - x, y, width, height); - return true; - } - else if (type == AffineTransform.TYPE_TRANSLATION) - { - x += transform.getTranslateX(); - y += transform.getTranslateY(); - drawVolatile(component, vimg.nativePointer, - x, y, width, height); - return true; - } + int type = transform.getType(); + if ((type == AffineTransform.TYPE_IDENTITY + || type == AffineTransform.TYPE_TRANSLATION) + && (clip == null || clip instanceof Rectangle2D)) + { + Rectangle2D r = (Rectangle2D) clip; + if (r == null) + r = getRealBounds(); + x += transform.getTranslateX(); + y += transform.getTranslateY(); + drawVolatile(component, vimg.nativePointer, + x, y, width, height, + (int) (r.getX() + transform.getTranslateX()), + (int) (r.getY() + transform.getTranslateY()), + (int) r.getWidth(), + (int) r.getHeight()); + return true; + } else return super.drawImage(vimg.getSnapshot(), x, y, width, height, observer); @@ -359,5 +379,57 @@ public class ComponentGraphics extends CairoGraphics2D return super.drawImage(bimg, x, y, width, height, observer); } + public void drawLine(int x1, int y1, int x2, int y2) + { + lock(); + try + { + super.drawLine(x1, y1, x2, y2); + } + finally + { + unlock(); + } + } + + public void drawRect(int x, int y, int width, int height) + { + lock(); + try + { + super.drawRect(x, y, width, height); + } + finally + { + unlock(); + } + } + + public void fillRect(int x, int y, int width, int height) + { + lock(); + try + { + super.fillRect(x, y, width, height); + } + finally + { + unlock(); + } + } + + public void setClip(Shape s) + { + lock(); + try + { + super.setClip(s); + } + finally + { + unlock(); + } + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java index 286fbea..2216d45 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java @@ -39,17 +39,11 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.Color; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; import java.awt.Image; -import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; import java.awt.image.RenderedImage; import java.awt.image.ImageObserver; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java b/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java index 4978c6a..2c9d917 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java @@ -137,6 +137,35 @@ public class FreetypeGlyphVector extends GlyphVector } /** + * Cloning constructor + */ + private FreetypeGlyphVector( FreetypeGlyphVector gv ) + { + font = gv.font; + peer = gv.peer; + frc = gv.frc; + s = gv.s; + nGlyphs = gv.nGlyphs; + logicalBounds = gv.logicalBounds.getBounds2D(); + + if( gv.metricsCache != null ) + { + metricsCache = new GlyphMetrics[ nGlyphs ]; + System.arraycopy(gv.metricsCache, 0, metricsCache, 0, nGlyphs); + } + + glyphCodes = new int[ nGlyphs ]; + glyphPositions = new float[ nGlyphs ]; + glyphTransforms = new AffineTransform[ nGlyphs ]; + for(int i = 0; i < nGlyphs; i++ ) + { + glyphTransforms[ i ] = new AffineTransform( gv.glyphTransforms[ i ] ); + glyphCodes[i] = gv.glyphCodes[ i ]; + glyphPositions[i] = gv.glyphPositions[ i ]; + } + } + + /** * Create the array of glyph codes. */ private void getGlyphs() @@ -172,6 +201,12 @@ public class FreetypeGlyphVector extends GlyphVector private native GeneralPath getGlyphOutlineNative(int glyphIndex); + + public Object clone() + { + return new FreetypeGlyphVector( this ); + } + /** * Duh, compares two instances. */ @@ -260,8 +295,11 @@ public class FreetypeGlyphVector extends GlyphVector if( gm == null ) return null; Rectangle2D r = gm.getBounds2D(); - return new Rectangle2D.Double( r.getX() - gm.getLSB(), r.getY(), - gm.getAdvanceX(), r.getHeight() ); + Point2D p = getGlyphPosition( glyphIndex ); + return new Rectangle2D.Double( p.getX() + r.getX() - gm.getLSB(), + p.getY() + r.getY(), + gm.getAdvanceX(), + r.getHeight() ); } /* @@ -385,8 +423,6 @@ public class FreetypeGlyphVector extends GlyphVector for( int i = 1; i < nGlyphs; i++ ) { Rectangle2D r2 = (Rectangle2D)getGlyphLogicalBounds( i ); - Point2D p = getGlyphPosition( i ); - r2.setRect( p.getX(), p.getY(), r2.getWidth(), r2.getHeight() ); rect = rect.createUnion( r2 ); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java index f5ed8a7..11635c3 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java @@ -38,7 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import gnu.classpath.Configuration; import gnu.java.awt.peer.ClasspathFontPeer; import gnu.java.awt.font.opentype.NameDecoder; @@ -50,9 +49,7 @@ import java.awt.font.GlyphVector; import java.awt.font.GlyphMetrics; import java.awt.font.LineMetrics; import java.awt.geom.Rectangle2D; -import java.awt.geom.Point2D; import java.text.CharacterIterator; -import java.text.StringCharacterIterator; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java index 035819d..e095c7d 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java @@ -134,5 +134,9 @@ public class GdkGraphicsEnvironment extends GraphicsEnvironment { throw new java.lang.UnsupportedOperationException (); } - + + /** + * Used by GtkMouseInfoPeer. + */ + native int[] getMouseCoordinates(); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java index cd047f2..6d0a52b 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java @@ -38,13 +38,10 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import gnu.classpath.Configuration; - import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DirectColorModel; import java.awt.image.ImageConsumer; -import java.awt.image.ImageProducer; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.io.DataInput; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java deleted file mode 100644 index a876522..0000000 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java +++ /dev/null @@ -1,393 +0,0 @@ -/* GdkTextLayout.java - Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.java.awt.peer.gtk; - -import gnu.classpath.Configuration; -import gnu.java.awt.peer.ClasspathTextLayoutPeer; - -import java.awt.Font; -import java.awt.Graphics2D; -import java.awt.Shape; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphMetrics; -import java.awt.font.GlyphVector; -import java.awt.font.TextAttribute; -import java.awt.font.TextHitInfo; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.GeneralPath; -import java.awt.geom.Rectangle2D; -import java.text.AttributedCharacterIterator; -import java.text.AttributedString; -import java.text.CharacterIterator; - -/** - * This is an implementation of the text layout peer interface which - * delegates all the hard work to pango. - * - * @author Graydon Hoare - */ - -public class GdkTextLayout - implements ClasspathTextLayoutPeer -{ - // native side, plumbing, etc. - static - { - System.loadLibrary("gtkpeer"); - - initStaticState (); - } - private native void setText(String str); - private native void setFont(GdkFontPeer font); - private native void getExtents(double[] inkExtents, - double[] logExtents); - private native void indexToPos(int idx, double[] pos); - - private native void initState (); - - private native void dispose (); - - private native void cairoDrawGdkTextLayout(long cg2d, float x, float y); - - static native void initStaticState(); - - private final int native_state = GtkGenericPeer.getUniqueInteger (); - - protected void finalize () - { - dispose (); - } - - // we hold on to these to make sure we can render when presented - // with non-GdkGraphics2D paint targets - private AttributedString attributedString; - private FontRenderContext fontRenderContext; - - public GdkTextLayout(AttributedString str, FontRenderContext frc) - { - initState(); - attributedString = str; - fontRenderContext = frc; - AttributedCharacterIterator aci = str.getIterator(); - char[] chars = new char[aci.getEndIndex() - aci.getBeginIndex()]; - for(int i = aci.getBeginIndex(); i < aci.getEndIndex(); i++) - chars[i] = aci.setIndex(i); - setText(new String(chars)); - - Object fnt = aci.getAttribute(TextAttribute.FONT); - if (fnt != null && fnt instanceof Font) - setFont( (GdkFontPeer) ((Font)fnt).getPeer() ); - } - - protected class CharacterIteratorProxy - implements CharacterIterator - { - public CharacterIterator target; - public int begin; - public int limit; - public int index; - - public CharacterIteratorProxy (CharacterIterator ci) - { - target = ci; - } - - public int getBeginIndex () - { - return begin; - } - - public int getEndIndex () - { - return limit; - } - - public int getIndex () - { - return index; - } - - public char setIndex (int idx) - throws IllegalArgumentException - { - if (idx < begin || idx >= limit) - throw new IllegalArgumentException (); - char ch = target.setIndex (idx); - index = idx; - return ch; - } - - public char first () - { - int save = target.getIndex (); - char ch = target.setIndex (begin); - target.setIndex (save); - return ch; - } - - public char last () - { - if (begin == limit) - return this.first (); - - int save = target.getIndex (); - char ch = target.setIndex (limit - 1); - target.setIndex (save); - return ch; - } - - public char current () - { - return target.current(); - } - - public char next () - { - if (index >= limit - 1) - return CharacterIterator.DONE; - else - { - index++; - return target.next(); - } - } - - public char previous () - { - if (index <= begin) - return CharacterIterator.DONE; - else - { - index--; - return target.previous (); - } - } - - public Object clone () - { - CharacterIteratorProxy cip = new CharacterIteratorProxy (this.target); - cip.begin = this.begin; - cip.limit = this.limit; - cip.index = this.index; - return cip; - } - - } - - - // public side - - public void draw (Graphics2D g2, float x, float y) - { - cairoDrawGdkTextLayout(((CairoGraphics2D) g2).nativePointer, x, y); - } - - public TextHitInfo getStrongCaret (TextHitInfo hit1, - TextHitInfo hit2) - { - throw new Error("not implemented"); - } - - public byte getBaseline () - { - throw new Error("not implemented"); - } - - public boolean isLeftToRight () - { - throw new Error("not implemented"); - } - - public boolean isVertical () - { - throw new Error("not implemented"); - } - - public float getAdvance () - { - throw new Error("not implemented"); - } - - public float getAscent () - { - throw new Error("not implemented"); - } - - public float getDescent () - { - throw new Error("not implemented"); - } - - public float getLeading () - { - throw new Error("not implemented"); - } - - public int getCharacterCount () - { - throw new Error("not implemented"); - } - - public byte getCharacterLevel (int index) - { - throw new Error("not implemented"); - } - - public float[] getBaselineOffsets () - { - throw new Error("not implemented"); - } - - public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint) - { - throw new Error("not implemented"); - } - - public Rectangle2D getBounds () - { - double[] inkExtents = new double[4]; - double[] logExtents = new double[4]; - getExtents(inkExtents, logExtents); - return new Rectangle2D.Double(logExtents[0], logExtents[1], - logExtents[2], logExtents[3]); - } - - public float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds) - { - throw new Error("not implemented"); - } - - public Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds) - { - throw new Error("not implemented"); - } - - public Shape[] getCaretShapes (int offset, Rectangle2D bounds, - TextLayout.CaretPolicy policy) - { - throw new Error("not implemented"); - } - - public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint, - Rectangle2D bounds) - { - AffineTransform at = new AffineTransform(); - GeneralPath gp = new GeneralPath(); - double [] rect = new double[4]; - Rectangle2D tmp = new Rectangle2D.Double(); - for (int i = firstEndpoint; i <= secondEndpoint; ++i) - { - indexToPos(i, rect); - tmp.setRect(rect[0], rect[1], rect[2], rect[3]); - Rectangle2D.intersect(tmp, bounds, tmp); - gp.append(tmp.getPathIterator(at), false); - } - return gp; - } - - public int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint, - TextHitInfo secondEndpoint) - { - throw new Error("not implemented"); - } - - public TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy) - { - throw new Error("not implemented"); - } - public TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy) - { - throw new Error("not implemented"); - } - public TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds) - { - throw new Error("not implemented"); - } - public TextHitInfo getVisualOtherHit (TextHitInfo hit) - { - throw new Error("not implemented"); - } - - public float getVisibleAdvance () - { - throw new Error("not implemented"); - } - - public native Shape getOutline (AffineTransform tx); - - public Shape getVisualHighlightShape (TextHitInfo firstEndpoint, - TextHitInfo secondEndpoint, - Rectangle2D bounds) - { - throw new Error("not implemented"); - } - - - public TextLayout getJustifiedLayout (float justificationWidth) - { - throw new Error("not implemented"); - } - - public void handleJustify (float justificationWidth) - { - throw new Error("not implemented"); - } - - public Object clone () - { - throw new Error("not implemented"); - } - - public int hashCode () - { - throw new Error("not implemented"); - } - - public boolean equals (ClasspathTextLayoutPeer tl) - { - throw new Error("not implemented"); - } - - public String toString () - { - throw new Error("not implemented"); - } - -} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java index 63d9cd4..f18db7a 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkButtonPeer.java @@ -38,13 +38,8 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.AWTEvent; import java.awt.Button; -import java.awt.Component; -import java.awt.Point; import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; -import java.awt.event.MouseEvent; import java.awt.peer.ButtonPeer; // A composite widget. GtkButtons have transparent backgrounds. An diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java index edfc9cee..30c39de 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java @@ -53,8 +53,8 @@ public class GtkCanvasPeer extends GtkComponentPeer implements CanvasPeer // Preferred size for a drawing widget is always what the user // requested. - public Dimension getPreferredSize () + public Dimension preferredSize() { - return awtComponent.getSize (); + return awtComponent.getSize(); } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java deleted file mode 100644 index 46b0733..0000000 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxGroupPeer.java +++ /dev/null @@ -1,86 +0,0 @@ -/* GtkCheckboxGroupPeer.java - Wrap a CheckboxGroup - Copyright (C) 2002 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.java.awt.peer.gtk; - -import java.awt.CheckboxGroup; -import java.util.WeakHashMap; - -// Note that there is no peer interface for a CheckboxGroup. We -// introduce our own in order to make it easier to keep a piece of -// native state for each one. -public class GtkCheckboxGroupPeer extends GtkGenericPeer -{ - // This maps from a CheckboxGroup to the native peer. - private static WeakHashMap map = new WeakHashMap (); - - // Find the native peer corresponding to a CheckboxGroup. - public static synchronized GtkCheckboxGroupPeer - getCheckboxGroupPeer (CheckboxGroup group) - { - if (group == null) - return null; - GtkCheckboxGroupPeer nat = (GtkCheckboxGroupPeer) map.get (group); - if (nat == null) - { - nat = new GtkCheckboxGroupPeer (); - map.put (group, nat); - } - return nat; - } - - private GtkCheckboxGroupPeer () - { - // We don't need any special state here. Note that we can't store - // a reference to the java-side CheckboxGroup. That would mean - // they could never be collected. - super (null); - } - - // Dispose of our native resources. - public native void dispose (); - - // Remove a given checkbox from this group. - public native void remove (GtkCheckboxPeer box); - - // When collected, clean up the native state. - protected void finalize () - { - dispose (); - } -} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java index 094aa3c..90d16c5 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java @@ -40,20 +40,32 @@ package gnu.java.awt.peer.gtk; import java.awt.Checkbox; import java.awt.CheckboxGroup; -import java.awt.peer.CheckboxPeer; - import java.awt.event.ItemEvent; +import java.awt.peer.CheckboxPeer; +import java.util.WeakHashMap; +/** + * This class wraps either a GtkCheckButton or a GtkOptionButton + * depending on if this peer's owner belongs to a CheckboxGroup. + */ public class GtkCheckboxPeer extends GtkComponentPeer implements CheckboxPeer { - // Group from last time it was set. - public GtkCheckboxGroupPeer old_group; + // The CheckboxGroup to which this GtkCheckboxPeer's owner belongs. + public CheckboxGroup current_group; // The current state of the GTK checkbox. - private boolean currentState; + private boolean currentState; + + // A map from CheckboxGroup to GSList* GTK option group pointer. + private static WeakHashMap groupMap = new WeakHashMap(); + + public native void createCheckButton (); + public native void createRadioButton (long groupPointer); - public native void create (GtkCheckboxGroupPeer group); - public native void nativeSetCheckboxGroup (GtkCheckboxGroupPeer group); + public native void addToGroup (long groupPointer); + public native void removeFromGroup (); + public native void switchToGroup (long groupPointer); + public native void connectSignals (); /** @@ -68,17 +80,47 @@ public class GtkCheckboxPeer extends GtkComponentPeer super (c); } - // FIXME: we must be able to switch between a checkbutton and a - // radiobutton dynamically. public void create () { Checkbox checkbox = (Checkbox) awtComponent; - CheckboxGroup g = checkbox.getCheckboxGroup (); - old_group = GtkCheckboxGroupPeer.getCheckboxGroupPeer (g); - create (old_group); + current_group = checkbox.getCheckboxGroup (); + if (current_group == null) + { + // Initially we're not part of a group so we're backed by a + // GtkCheckButton. + createCheckButton(); + } + else + { + // Initially we're part of a group. + + // See if this group is already stored in our map. + Long groupPointer = null; + synchronized (groupMap) + { + groupPointer = (Long) groupMap.get(current_group); + } + + if (groupPointer == null) + { + // We don't know about this group. Create a new native + // group pointer for this group and store it in our map. + createRadioButton(0); + } + else + { + // We already know about this group. Pass the + // corresponding native group pointer value to the native + // create method. + createRadioButton(groupPointer.longValue()); + } + } currentState = checkbox.getState(); gtkToggleButtonSetActive(currentState); - gtkButtonSetLabel (checkbox.getLabel ()); + + String label = checkbox.getLabel(); + if (label != null) + gtkButtonSetLabel(label); } /** @@ -87,7 +129,7 @@ public class GtkCheckboxPeer extends GtkComponentPeer * event since events should only be posted for user initiated * clicks on the GtkCheckButton. */ - synchronized public void setState (boolean state) + public synchronized void setState (boolean state) { if (currentState != state) { @@ -103,21 +145,87 @@ public class GtkCheckboxPeer extends GtkComponentPeer public void setCheckboxGroup (CheckboxGroup group) { - GtkCheckboxGroupPeer gp - = GtkCheckboxGroupPeer.getCheckboxGroupPeer (group); - if (gp != old_group) + if (current_group == null && group != null) { - if (old_group != null) - old_group.remove (this); - nativeSetCheckboxGroup (gp); - old_group = gp; + // This peer's owner is currently not in a group, and now + // we're adding it to a group. This means that the backing + // GtkWidget will change from a GtkCheckButton to a + // GtkRadioButton. + + current_group = group; + + // See if the new group is already stored in our map. + Long groupPointer = null; + synchronized (groupMap) + { + groupPointer = (Long) groupMap.get(current_group); + } + + if (groupPointer == null) + { + // We don't know about this group. Create a new native + // group pointer for this group and store it in our map. + addToGroup(0); + } + else + { + // We already know about this group. Pass the + // corresponding native group pointer value to the native + // create method. + addToGroup(groupPointer.longValue()); + } + } + else if (current_group != null && group == null) + { + // This peer's owner is currently in a group, and now we're + // removing it from a group. This means that the backing + // GtkWidget will change from a GtkRadioButton to a + // GtkCheckButton. + removeFromGroup(); + current_group = null; + } + else if (current_group == null && group == null) + { + // This peer's owner is currently not in a group, and we're + // not adding it to a group, so simply return. + return; + } + else if (current_group != group) + { + // This peer's owner is currently in a group, and now we're + // putting it in another group. This means that we must + // remove the backing GtkRadioButton from one group and add it + // to the other group. + + current_group = group; + + // See if the new group is already stored in our map. + Long groupPointer = null; + synchronized (groupMap) + { + groupPointer = (Long) groupMap.get(current_group); + } + + if (groupPointer == null) + { + // We don't know about this group. Create a new native + // group pointer for this group and store it in our map. + switchToGroup(0); + } + else + { + // We already know about this group. Pass the + // corresponding native group pointer value to the native + // create method. + switchToGroup(groupPointer.longValue()); + } } } // Override the superclass postItemEvent so that the peer doesn't // need information that we have. // called back by native side: item_toggled_cb - synchronized public void postItemEvent(Object item, boolean state) + public synchronized void postItemEvent(Object item, boolean state) { // Only fire event is state actually changed. if (currentState != state) @@ -127,13 +235,20 @@ public class GtkCheckboxPeer extends GtkComponentPeer state ? ItemEvent.SELECTED : ItemEvent.DESELECTED); } } + + public void addToGroupMap(long groupPointer) + { + synchronized (groupMap) + { + groupMap.put(current_group, new Long (groupPointer)); + } + } public void dispose () { - // Notify the group so that the native state can be cleaned up - // appropriately. - if (old_group != null) - old_group.remove (this); + groupMap.clear(); + current_group = null; + currentState = false; super.dispose (); } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java index fdc7d50..61df796 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java @@ -1,5 +1,5 @@ /* GtkClipboardNotifier.java -- Helper for announcing GtkSelection changes. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,8 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.datatransfer.*; -import java.util.*; class GtkClipboardNotifier extends Thread { diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java index 625855f..c11c45e 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -52,9 +52,12 @@ import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.awt.Image; import java.awt.Insets; import java.awt.ItemSelectable; +import java.awt.KeyboardFocusManager; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; @@ -66,13 +69,13 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.PaintEvent; import java.awt.event.TextEvent; -import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.awt.image.VolatileImage; import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; +import java.awt.peer.LightweightPeer; import java.awt.peer.WindowPeer; import java.util.Timer; import java.util.TimerTask; @@ -109,6 +112,9 @@ public class GtkComponentPeer extends GtkGenericPeer native void gtkWidgetRequestFocus (); native void gtkWidgetDispatchKeyEvent (int id, long when, int mods, int keyCode, int keyLocation); + native boolean gtkWidgetHasFocus(); + native boolean gtkWidgetCanFocus(); + native void realize(); native void setNativeEventMask (); @@ -365,7 +371,7 @@ public class GtkComponentPeer extends GtkGenericPeer public void print (Graphics g) { - throw new RuntimeException (); + g.drawImage( ComponentGraphics.grab( this ), 0, 0, null ); } public void repaint (long tm, int x, int y, int width, int height) @@ -414,8 +420,7 @@ public class GtkComponentPeer extends GtkGenericPeer public void requestFocus () { - gtkWidgetRequestFocus(); - postFocusEvent(FocusEvent.FOCUS_GAINED, false); + assert false: "Call new requestFocus() method instead"; } public void reshape (int x, int y, int width, int height) @@ -628,6 +633,12 @@ public class GtkComponentPeer extends GtkGenericPeer q.postEvent(keyEvent); } + /** + * Referenced from native code. + * + * @param id + * @param temporary + */ protected void postFocusEvent (int id, boolean temporary) { q().postEvent (new FocusEvent (awtComponent, id, temporary)); @@ -647,8 +658,10 @@ public class GtkComponentPeer extends GtkGenericPeer public GraphicsConfiguration getGraphicsConfiguration () { - // FIXME: just a stub for now. - return null; + // FIXME: The component might be showing on a non-default screen. + GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice dev = env.getDefaultScreenDevice(); + return dev.getDefaultConfiguration(); } public void setEventMask (long mask) @@ -661,10 +674,72 @@ public class GtkComponentPeer extends GtkGenericPeer return false; } - public boolean requestFocus (Component source, boolean b1, - boolean b2, long x) + public boolean requestFocus (Component request, boolean temporary, + boolean allowWindowFocus, long time) { - return false; + assert request == awtComponent || isLightweightDescendant(request); + boolean retval = false; + if (gtkWidgetHasFocus()) + { + KeyboardFocusManager kfm = + KeyboardFocusManager.getCurrentKeyboardFocusManager(); + Component currentFocus = kfm.getFocusOwner(); + if (currentFocus == request) + // Nothing to do in this trivial case. + retval = true; + else + { + // Requested component is a lightweight descendant of this one + // or the actual heavyweight. + // Since this (native) component is already focused, we simply + // change the actual focus and be done. + postFocusEvent(FocusEvent.FOCUS_GAINED, temporary); + retval = true; + } + } + else + { + if (gtkWidgetCanFocus()) + { + if (allowWindowFocus) + { + Window window = getWindowFor(request); + GtkWindowPeer wPeer = (GtkWindowPeer) window.getPeer(); + if (! wPeer.gtkWindowHasFocus()) + wPeer.requestWindowFocus(); + } + // Store requested focus component so that the corresponding + // event is dispatched correctly. + gtkWidgetRequestFocus(); + retval = true; + } + } + return retval; + } + + private Window getWindowFor(Component c) + { + Component comp = c; + while (! (comp instanceof Window)) + comp = comp.getParent(); + return (Window) comp; + } + + /** + * Returns true if the component is a direct (== no intermediate + * heavyweights) lightweight descendant of this peer's component. + * + * @param c the component to check + * + * @return true if the component is a direct (== no intermediate + * heavyweights) lightweight descendant of this peer's component + */ + protected boolean isLightweightDescendant(Component c) + { + Component comp = c; + while (comp.getPeer() instanceof LightweightPeer) + comp = comp.getParent(); + return comp == awtComponent; } public boolean isObscured () diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java index 06076e7..541de3d 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java @@ -42,10 +42,7 @@ import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Font; -import java.awt.Graphics; import java.awt.Insets; -import java.awt.Window; -import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; public class GtkContainerPeer extends GtkComponentPeer diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java index 3254f56..1390654 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java @@ -1,5 +1,5 @@ /* GtkDialogPeer.java -- Implements DialogPeer with GTK - Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2002, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,9 +39,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.Dialog; -import java.awt.Graphics; -import java.awt.Rectangle; -import java.awt.event.PaintEvent; import java.awt.peer.DialogPeer; public class GtkDialogPeer extends GtkWindowPeer diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java index 6ec0b72..bb6f8b3 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java @@ -39,11 +39,9 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.Frame; -import java.awt.Graphics; import java.awt.Image; import java.awt.MenuBar; import java.awt.Rectangle; -import java.awt.event.PaintEvent; import java.awt.peer.FramePeer; import java.awt.peer.MenuBarPeer; @@ -218,11 +216,7 @@ public class GtkFramePeer extends GtkWindowPeer // TODO Auto-generated method stub } - public void updateAlwaysOnTop() - { - // TODO Auto-generated method stub - - } + public boolean requestWindowFocus() { // TODO Auto-generated method stub diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java index ef96518..0fd98bb 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java @@ -39,12 +39,10 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.Graphics; -import java.awt.Color; import java.awt.Image; import java.awt.image.ColorModel; import java.awt.image.DirectColorModel; import java.awt.image.MemoryImageSource; -import java.awt.image.ImageConsumer; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.io.File; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java index 299f01d..f1a74b8 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImageConsumer.java @@ -1,5 +1,5 @@ /* GtkImageConsumer.java - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,16 +38,11 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.Graphics; -import java.awt.Image; import java.awt.image.ColorModel; -import java.awt.image.DirectColorModel; import java.awt.image.ImageConsumer; -import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.awt.image.MemoryImageSource; import java.util.Hashtable; -import java.util.Vector; /** * Helper class to GtkImage. Sits and gathers pixels for a GtkImage and then diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java index bbf4230..02db90d 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkLabelPeer.java @@ -56,7 +56,7 @@ public class GtkLabelPeer extends GtkComponentPeer native void nativeSetAlignment (float alignment); - public native void setText(String text); + public native void setNativeText(String text); native void setNativeBounds (int x, int y, int width, int height); // Because this is a composite widget, we need to retrieve the @@ -69,6 +69,12 @@ public class GtkLabelPeer extends GtkComponentPeer create (label.getText (), getGtkAlignment (label.getAlignment ())); } + public void setText(String text) + { + if (text != null) + setNativeText(text); + } + public GtkLabelPeer (Label l) { super (l); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java index d203b43..898f224 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuBarPeer.java @@ -38,12 +38,9 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.Font; import java.awt.Menu; import java.awt.MenuBar; -import java.awt.MenuComponent; import java.awt.peer.MenuBarPeer; -import java.awt.peer.MenuPeer; public class GtkMenuBarPeer extends GtkMenuComponentPeer implements MenuBarPeer diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java index 251bab2..ea523e9 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java @@ -38,13 +38,8 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.Font; -import java.awt.Menu; -import java.awt.MenuBar; -import java.awt.MenuComponent; import java.awt.MenuItem; import java.awt.peer.MenuItemPeer; -import java.awt.peer.MenuPeer; public class GtkMenuItemPeer extends GtkMenuComponentPeer implements MenuItemPeer diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java new file mode 100644 index 0000000..02bf84d --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMouseInfoPeer.java @@ -0,0 +1,76 @@ +/* GtkToolkit.java -- Implements an AWT Toolkit using GTK for peers + Copyright (C) 2006 + Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.gtk; + +import java.awt.Point; +import java.awt.GraphicsDevice; +import java.awt.Window; +import java.awt.peer.MouseInfoPeer; + +/** + * The MouseInfoPeer is so small, I'm including it here. + */ +public class GtkMouseInfoPeer implements MouseInfoPeer +{ + private static GdkGraphicsEnvironment gde = new GdkGraphicsEnvironment(); + + public int fillPointWithCoords(Point p) + { + int[] coords = gde.getMouseCoordinates(); + p.x = coords[1]; + p.y = coords[2]; + return coords[0]; + } + + public boolean isWindowUnderMouse(Window w) + { + int[] coords = gde.getMouseCoordinates(); + GraphicsDevice[] gds = gde.getScreenDevices(); + + // Check if the screen of the Window and the cursor match + if( gds[ coords[0] ] != w.getGraphicsConfiguration().getDevice() ) + return false; + + // Return the bounds-check. + Point p = w.getLocationOnScreen(); + return (coords[1] >= p.x && coords[1] < p.x + w.getWidth() && + coords[2] >= p.y && coords[2] < p.y + w.getHeight() ); + } +} + diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java index 51fe2bc..e0053f7 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java @@ -1,5 +1,5 @@ /* GtkPanelPeer.java -- Implements PanelPeer with GTK - Copyright (C) 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,7 +41,6 @@ package gnu.java.awt.peer.gtk; import java.awt.AWTEvent; import java.awt.Panel; import java.awt.event.MouseEvent; -import java.awt.event.PaintEvent; import java.awt.peer.PanelPeer; public class GtkPanelPeer extends GtkContainerPeer diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java index 525a910..4d66a3f 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPopupMenuPeer.java @@ -40,7 +40,6 @@ package gnu.java.awt.peer.gtk; import java.awt.Component; import java.awt.Event; -import java.awt.MenuItem; import java.awt.Point; import java.awt.PopupMenu; import java.awt.peer.PopupMenuPeer; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java index 9b31a73..e4147d3 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java @@ -38,8 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.Adjustable; -import java.awt.EventQueue; import java.awt.Scrollbar; import java.awt.event.AdjustmentEvent; import java.awt.peer.ScrollbarPeer; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java index 163fc52..6aa87fc 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -39,32 +39,83 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import gnu.classpath.Configuration; import gnu.java.awt.EmbeddedWindow; +import gnu.java.awt.dnd.GtkMouseDragGestureRecognizer; +import gnu.java.awt.dnd.peer.gtk.GtkDragSourceContextPeer; import gnu.java.awt.peer.ClasspathFontPeer; -import gnu.java.awt.peer.ClasspathTextLayoutPeer; import gnu.java.awt.peer.EmbeddedWindowPeer; -import java.awt.*; +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Checkbox; +import java.awt.CheckboxMenuItem; +import java.awt.Choice; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FileDialog; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Label; +import java.awt.List; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.Point; +import java.awt.PopupMenu; +import java.awt.PrintJob; +import java.awt.Rectangle; +import java.awt.ScrollPane; +import java.awt.Scrollbar; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.Window; import java.awt.datatransfer.Clipboard; import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; import java.awt.dnd.peer.DragSourceContextPeer; -import java.awt.font.FontRenderContext; import java.awt.im.InputMethodHighlight; -import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DirectColorModel; -import java.awt.image.ImageConsumer; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; -import java.awt.peer.*; +import java.awt.peer.ButtonPeer; +import java.awt.peer.CanvasPeer; +import java.awt.peer.CheckboxMenuItemPeer; +import java.awt.peer.CheckboxPeer; +import java.awt.peer.ChoicePeer; +import java.awt.peer.DialogPeer; +import java.awt.peer.FileDialogPeer; +import java.awt.peer.FontPeer; +import java.awt.peer.FramePeer; +import java.awt.peer.LabelPeer; +import java.awt.peer.ListPeer; +import java.awt.peer.MenuBarPeer; +import java.awt.peer.MenuItemPeer; +import java.awt.peer.MouseInfoPeer; +import java.awt.peer.MenuPeer; +import java.awt.peer.PanelPeer; +import java.awt.peer.PopupMenuPeer; +import java.awt.peer.RobotPeer; +import java.awt.peer.ScrollPanePeer; +import java.awt.peer.ScrollbarPeer; +import java.awt.peer.TextAreaPeer; +import java.awt.peer.TextFieldPeer; +import java.awt.peer.WindowPeer; import java.io.InputStream; import java.net.URL; -import java.text.AttributedString; import java.util.HashMap; -import java.util.HashSet; import java.util.Hashtable; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; @@ -310,6 +361,11 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit public PrintJob getPrintJob (Frame frame, String jobtitle, Properties props) { + SecurityManager sm; + sm = System.getSecurityManager(); + if (sm != null) + sm.checkPrintJobAccess(); + return null; } @@ -528,12 +584,6 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit } } - public ClasspathTextLayoutPeer getClasspathTextLayoutPeer (AttributedString str, - FontRenderContext frc) - { - return new GdkTextLayout(str, frc); - } - protected EventQueue getSystemEventQueueImpl() { synchronized (GtkToolkit.class) @@ -555,7 +605,26 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e) { - throw new Error("not implemented"); + return new GtkDragSourceContextPeer(e); + } + + public DragGestureRecognizer createDragGestureRecognizer(Class recognizer, + DragSource ds, + Component comp, + int actions, + DragGestureListener l) + { + if (recognizer.getName().equals("java.awt.dnd.MouseDragGestureRecognizer")) + { + GtkMouseDragGestureRecognizer gestureRecognizer + = new GtkMouseDragGestureRecognizer(ds, comp, actions, l); + gestureRecognizer.registerListeners(); + return gestureRecognizer; + } + else + { + return null; + } } public Map mapInputMethodHighlight(InputMethodHighlight highlight) @@ -593,4 +662,12 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit } public static native void gtkMain(); + + protected MouseInfoPeer getMouseInfoPeer() + { + return new GtkMouseInfoPeer(); + } + + public native int getMouseNumberOfButtons(); + } // class GtkToolkit diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java index f38007f..44e7b02 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java @@ -50,6 +50,8 @@ public class GtkVolatileImage extends VolatileImage int width, height; private ImageCapabilities caps; + final GtkComponentPeer component; + /** * Don't touch, accessed from native code. */ @@ -85,6 +87,7 @@ public class GtkVolatileImage extends VolatileImage this.width = width; this.height = height; this.caps = caps; + this.component = component; nativePointer = init( component, width, height ); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java index d15beac..866d9c8 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java @@ -38,13 +38,14 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.AWTEvent; import java.awt.Component; import java.awt.Frame; import java.awt.Graphics; +import java.awt.KeyboardFocusManager; import java.awt.Rectangle; import java.awt.Window; import java.awt.event.ComponentEvent; +import java.awt.event.FocusEvent; import java.awt.event.PaintEvent; import java.awt.event.WindowEvent; import java.awt.peer.WindowPeer; @@ -70,7 +71,8 @@ public class GtkWindowPeer extends GtkContainerPeer native void gtkWindowSetTitle (String title); native void gtkWindowSetResizable (boolean resizable); native void gtkWindowSetModal (boolean modal); - + native void gtkWindowSetAlwaysOnTop ( boolean alwaysOnTop ); + native boolean gtkWindowHasFocus(); native void realize (); /** Returns the cached width of the AWT window component. */ @@ -275,10 +277,13 @@ public class GtkWindowPeer extends GtkContainerPeer else q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite)); } + + /** + * Update the always-on-top status of the native window. + */ public void updateAlwaysOnTop() { - // TODO Auto-generated method stub - + gtkWindowSetAlwaysOnTop( ((Window)awtComponent).isAlwaysOnTop() ); } protected void postExposeEvent (int x, int y, int width, int height) @@ -299,7 +304,40 @@ public class GtkWindowPeer extends GtkContainerPeer // TODO Auto-generated method stub return false; } - + + public boolean requestFocus (Component request, boolean temporary, + boolean allowWindowFocus, long time) + { + assert request == awtComponent || isLightweightDescendant(request); + boolean retval = false; + if (gtkWindowHasFocus()) + { + KeyboardFocusManager kfm = + KeyboardFocusManager.getCurrentKeyboardFocusManager(); + Component currentFocus = kfm.getFocusOwner(); + if (currentFocus == request) + // Nothing to do in this trivial case. + retval = true; + else + { + // Requested component is a lightweight descendant of this one + // or the actual heavyweight. + // Since this (native) component is already focused, we simply + // change the actual focus and be done. + postFocusEvent(FocusEvent.FOCUS_GAINED, temporary); + retval = true; + } + } + else + { + if (allowWindowFocus) + { + retval = requestWindowFocus(); + } + } + return retval; + } + public Graphics getGraphics () { Graphics g = super.getGraphics (); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java index fa84ea0..5849655 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java @@ -38,25 +38,11 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.Color; import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.Image; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.Shape; -import java.awt.font.GlyphVector; -import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferInt; -import java.awt.image.ColorModel; -import java.awt.image.DirectColorModel; -import java.awt.image.RenderedImage; import java.awt.image.ImageObserver; -import java.util.WeakHashMap; public class VolatileImageGraphics extends ComponentGraphics { @@ -83,7 +69,7 @@ public class VolatileImageGraphics extends ComponentGraphics public GraphicsConfiguration getDeviceConfiguration() { - return null; + return owner.component.getGraphicsConfiguration(); } public Graphics create() diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtCheckboxPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtCheckboxPeer.java index 788e08e..acac5e4 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtCheckboxPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtCheckboxPeer.java @@ -1,5 +1,5 @@ /* QtCheckboxPeer.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,7 +37,6 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; -import java.awt.Rectangle; import java.awt.Checkbox; import java.awt.CheckboxGroup; import java.awt.event.ItemEvent; diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtComponentGraphics.java b/libjava/classpath/gnu/java/awt/peer/qt/QtComponentGraphics.java index 7395a8e..c5c839e 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtComponentGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtComponentGraphics.java @@ -1,5 +1,5 @@ /* QtComponentGraphics.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,9 +40,7 @@ package gnu.java.awt.peer.qt; import java.awt.Color; import java.awt.GraphicsConfiguration; import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.Rectangle; -import java.awt.Paint; /** * QtComponentPainter is a Graphics2D context for painting directly to AWT diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtComponentPeer.java index d5662a8..4d7b58c 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtComponentPeer.java @@ -1,5 +1,5 @@ /* QtComponentPeer.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,7 +41,6 @@ import java.awt.AWTEvent; import java.awt.AWTException; import java.awt.BufferCapabilities; import java.awt.Component; -import java.awt.Container; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtContainerPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtContainerPeer.java index 3782d78..ec04b05 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtContainerPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtContainerPeer.java @@ -1,5 +1,5 @@ /* QtContainerPeer.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,7 +37,6 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; -import java.awt.Container; import java.awt.Component; import java.awt.Insets; import java.awt.peer.ContainerPeer; diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtDialogPeer.java index 0da2e4e..23e5c06 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtDialogPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtDialogPeer.java @@ -1,5 +1,5 @@ /* QtDialogPeer.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,8 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; import java.awt.Dialog; -import java.awt.MenuBar; -import java.awt.Rectangle; import java.awt.peer.DialogPeer; public class QtDialogPeer extends QtWindowPeer implements DialogPeer diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtEmbeddedWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtEmbeddedWindowPeer.java index cac12b9..0f859b7 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtEmbeddedWindowPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtEmbeddedWindowPeer.java @@ -1,5 +1,5 @@ /* QtEmbeddedWindowPeer.java -- embedded window peer - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,7 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; import java.awt.Component; -import java.awt.peer.WindowPeer; import gnu.java.awt.peer.EmbeddedWindowPeer; /** diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java b/libjava/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java index e403239..2438fcc 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java @@ -1,5 +1,5 @@ /* QtFontMetrics.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,9 +41,6 @@ import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.geom.Rectangle2D; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.font.LineMetrics; public class QtFontMetrics extends FontMetrics { diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtFontPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtFontPeer.java index ee88c7d..d847a80 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtFontPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtFontPeer.java @@ -1,5 +1,5 @@ /* QtFontPeer.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -46,7 +46,6 @@ import java.awt.font.LineMetrics; import java.text.CharacterIterator; import java.util.Locale; import java.util.Map; -import java.awt.peer.FontPeer; import gnu.java.awt.peer.ClasspathFontPeer; diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtGraphics.java b/libjava/classpath/gnu/java/awt/peer/qt/QtGraphics.java index f9b4f26..842cbbbf 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtGraphics.java @@ -1,5 +1,5 @@ /* QtGraphics.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +38,7 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; import java.awt.AlphaComposite; +import java.awt.AWTPermission; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; @@ -57,7 +58,6 @@ import java.awt.Stroke; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; -import java.awt.geom.PathIterator; import java.awt.geom.Arc2D; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; @@ -605,8 +605,16 @@ public abstract class QtGraphics extends Graphics2D composite = comp; } else - throw new UnsupportedOperationException("We don't support custom"+ - " composites yet."); + { + // FIXME: this check is only required "if this Graphics2D + // context is drawing to a Component on the display screen". + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new AWTPermission("readDisplayPixels")); + + throw new UnsupportedOperationException("We don't support custom"+ + " composites yet."); + } } public Composite getComposite() diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/peer/qt/QtGraphicsEnvironment.java index 142b140..15a0159 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtGraphicsEnvironment.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtGraphicsEnvironment.java @@ -1,5 +1,5 @@ /* QtGraphicsEnvironment.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,7 +41,6 @@ import java.awt.Font; import java.awt.Graphics2D; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; -import java.awt.HeadlessException; import java.awt.image.BufferedImage; import java.util.Locale; diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtImage.java b/libjava/classpath/gnu/java/awt/peer/qt/QtImage.java index 9095464..b6fbb1d 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtImage.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtImage.java @@ -1,5 +1,5 @@ /* QtImage.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,7 +43,6 @@ import java.awt.Image; import java.awt.image.ColorModel; import java.awt.image.DirectColorModel; import java.awt.image.MemoryImageSource; -import java.awt.image.ImageConsumer; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.io.File; diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtImageConsumer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtImageConsumer.java index aec0671..7096c21 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtImageConsumer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtImageConsumer.java @@ -1,5 +1,5 @@ /* QtImageConsumer.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,15 +37,10 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; -import java.awt.Graphics; -import java.awt.Image; import java.awt.image.ColorModel; -import java.awt.image.DirectColorModel; import java.awt.image.ImageConsumer; -import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.util.Hashtable; -import java.util.Vector; /** * Helper class to QtImage. Sits and gathers pixels for a QtImage and then diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtImageDirectGraphics.java b/libjava/classpath/gnu/java/awt/peer/qt/QtImageDirectGraphics.java index 5a6f318..d49084a 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtImageDirectGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtImageDirectGraphics.java @@ -1,5 +1,5 @@ /* QtImageDirectGraphics.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,29 +38,10 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; import java.awt.Color; -import java.awt.GraphicsConfiguration; -import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.Image; -import java.awt.Paint; -import java.awt.Rectangle; -import java.util.Stack; import java.awt.Shape; -import java.awt.Stroke; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; -import java.awt.geom.PathIterator; -import java.awt.geom.Arc2D; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Line2D; -import java.awt.geom.Rectangle2D; -import java.awt.geom.RoundRectangle2D; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; import java.awt.image.ImageObserver; -import java.awt.image.RenderedImage; -import java.awt.image.renderable.RenderableImage; /** * A QtImagePainter that does an update after every drawing op. diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtImageGraphics.java b/libjava/classpath/gnu/java/awt/peer/qt/QtImageGraphics.java index f8a7e51..1224d69 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtImageGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtImageGraphics.java @@ -1,5 +1,5 @@ /* QtImageGraphics.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,9 +40,7 @@ package gnu.java.awt.peer.qt; import java.awt.Color; import java.awt.GraphicsConfiguration; import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.Image; -import java.awt.Paint; import java.awt.Rectangle; import java.util.Stack; diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtMenuBarPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuBarPeer.java index d8f0d1f..c91b37f 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtMenuBarPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuBarPeer.java @@ -1,5 +1,5 @@ /* QtMenuBarPeer.java -- Qt peer for a menu bar. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,7 +40,6 @@ package gnu.java.awt.peer.qt; import java.awt.Menu; import java.awt.MenuBar; import java.awt.peer.MenuBarPeer; -import java.util.Vector; public class QtMenuBarPeer extends QtMenuComponentPeer implements MenuBarPeer { diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtMenuItemPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuItemPeer.java index 34753cb..7658ff0 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtMenuItemPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuItemPeer.java @@ -1,5 +1,5 @@ /* QtMenuItemPeer.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,7 +37,6 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; -import java.awt.Menu; import java.awt.MenuItem; import java.awt.CheckboxMenuItem; import java.awt.event.ActionEvent; diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtPopupMenuPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtPopupMenuPeer.java index 81577cc..b96c5c5 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtPopupMenuPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtPopupMenuPeer.java @@ -1,5 +1,5 @@ /* QtPopupMenuPeer.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,12 +38,9 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; import java.awt.Component; -import java.awt.Menu; -import java.awt.MenuItem; import java.awt.Point; import java.awt.PopupMenu; import java.awt.Event; -import java.awt.event.ActionEvent; import java.awt.peer.PopupMenuPeer; public class QtPopupMenuPeer extends QtMenuPeer implements PopupMenuPeer diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtScreenDeviceConfiguration.java b/libjava/classpath/gnu/java/awt/peer/qt/QtScreenDeviceConfiguration.java index 045cfdf..c67b55b 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtScreenDeviceConfiguration.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtScreenDeviceConfiguration.java @@ -1,5 +1,5 @@ /* QtScreenDeviceConfiguration.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,11 +37,9 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; -import java.awt.DisplayMode; import java.awt.ImageCapabilities; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; -import java.awt.GraphicsConfigTemplate; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtScrollPanePeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtScrollPanePeer.java index 02fa8fb..c3731cb 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtScrollPanePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtScrollPanePeer.java @@ -1,5 +1,5 @@ /* QtScrollPanePeer.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,7 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; import java.awt.Adjustable; -import java.awt.Dimension; import java.awt.Insets; import java.awt.ScrollPane; import java.awt.peer.ScrollPanePeer; diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java b/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java index 73652f8..5116769 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java @@ -1,5 +1,5 @@ /* QtToolkit.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,19 +37,16 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; -import gnu.classpath.Configuration; import gnu.java.awt.EmbeddedWindow; import gnu.java.awt.peer.ClasspathFontPeer; import gnu.java.awt.peer.EmbeddedWindowPeer; -import gnu.java.awt.peer.ClasspathTextLayoutPeer; -import java.awt.AWTEvent; + import java.awt.AWTException; import java.awt.Button; import java.awt.Canvas; import java.awt.Checkbox; import java.awt.CheckboxMenuItem; import java.awt.Choice; -import java.awt.Component; import java.awt.Dialog; import java.awt.Dimension; import java.awt.EventQueue; @@ -68,18 +65,13 @@ import java.awt.TextField; import java.awt.FileDialog; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; -import java.awt.HeadlessException; import java.awt.PopupMenu; import java.awt.PrintJob; import java.awt.Scrollbar; import java.awt.ScrollPane; -import java.awt.Toolkit; import java.awt.Window; import java.awt.datatransfer.Clipboard; import java.awt.dnd.DragGestureEvent; -import java.awt.dnd.DragGestureListener; -import java.awt.dnd.DragGestureRecognizer; -import java.awt.dnd.DragSource; import java.awt.dnd.peer.DragSourceContextPeer; import java.awt.event.AWTEventListener; import java.awt.image.ColorModel; @@ -91,37 +83,29 @@ import java.awt.peer.ButtonPeer; import java.awt.peer.FontPeer; import java.awt.peer.PanelPeer; import java.awt.peer.CanvasPeer; -import java.awt.peer.FramePeer; +import java.awt.peer.FramePeer; import java.awt.peer.PopupMenuPeer; import java.awt.peer.CheckboxMenuItemPeer; import java.awt.peer.LabelPeer; import java.awt.peer.RobotPeer; import java.awt.peer.CheckboxPeer; -import java.awt.peer.LightweightPeer; import java.awt.peer.ScrollPanePeer; -import java.awt.peer.ChoicePeer; +import java.awt.peer.ChoicePeer; import java.awt.peer.ListPeer; import java.awt.peer.ScrollbarPeer; -import java.awt.peer.ComponentPeer; import java.awt.peer.MenuBarPeer; import java.awt.peer.TextAreaPeer; -import java.awt.peer.ContainerPeer; -import java.awt.peer.MenuComponentPeer; -import java.awt.peer.TextComponentPeer; import java.awt.peer.DialogPeer; import java.awt.peer.MenuItemPeer; import java.awt.peer.TextFieldPeer; import java.awt.peer.FileDialogPeer; import java.awt.peer.MenuPeer; import java.awt.peer.WindowPeer; -import java.awt.font.FontRenderContext; import java.io.InputStream; import java.net.URL; -import java.text.AttributedString; import java.util.HashMap; import java.util.Map; import java.util.Properties; -import javax.imageio.spi.IIORegistry; import gnu.java.awt.ClasspathToolkit; @@ -402,6 +386,11 @@ public class QtToolkit extends ClasspathToolkit String jobtitle, Properties props) { + SecurityManager sm; + sm = System.getSecurityManager(); + if (sm != null) + sm.checkPrintJobAccess(); + throw new RuntimeException("Not implemented"); } @@ -445,12 +434,6 @@ public class QtToolkit extends ClasspathToolkit return new QtFontPeer (name, attrs); } - public ClasspathTextLayoutPeer getClasspathTextLayoutPeer(AttributedString str, - FontRenderContext frc) - { - return null; - } - // FIXME public Font createFont(int format, InputStream stream) { diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtVolatileImage.java b/libjava/classpath/gnu/java/awt/peer/qt/QtVolatileImage.java index 0ec61de..c81bb2a 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtVolatileImage.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtVolatileImage.java @@ -1,5 +1,5 @@ /* QtVolatileImage.java -- - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -47,15 +47,11 @@ import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DirectColorModel; import java.awt.image.MemoryImageSource; -import java.awt.image.ImageConsumer; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.awt.image.VolatileImage; -import java.io.File; -import java.io.IOException; import java.util.Hashtable; import java.util.WeakHashMap; -import java.util.Vector; /** * QtVolatileImage - wraps a QImage diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java index f60c8e9..96ccc00 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java @@ -48,8 +48,6 @@ import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; @@ -101,8 +99,8 @@ public class SwingComponentPeer /** * Creates a SwingComponentPeer instance. Subclasses are expected to call * this constructor and thereafter call - * {@link #init(Component, SwingComponent)} in order to setup the AWT and - * Swing components properly. + * {@link #init(Component,SwingComponent)} + * in order to setup the AWT and Swing components properly. */ protected SwingComponentPeer() { @@ -167,12 +165,9 @@ public class SwingComponentPeer */ public Image createImage(int width, int height) { - GraphicsEnvironment graphicsEnv = - GraphicsEnvironment.getLocalGraphicsEnvironment(); - GraphicsDevice dev = graphicsEnv.getDefaultScreenDevice(); - GraphicsConfiguration conf = dev.getDefaultConfiguration(); - Image image = conf.createCompatibleImage(width, height); - return image; + Component parent = awtComponent.getParent(); + ComponentPeer parentPeer = parent.getPeer(); + return parentPeer.createImage(width, height); } /** @@ -336,21 +331,24 @@ public class SwingComponentPeer { case PaintEvent.UPDATE: case PaintEvent.PAINT: - Graphics g = getGraphics(); - Rectangle clip = ((PaintEvent)e).getUpdateRect(); - g.clipRect(clip.x, clip.y, clip.width, clip.height); - //if (this instanceof LightweightPeer) - // { + // This only will work when the component is showing. + if (awtComponent.isShowing()) + { + Graphics g = getGraphics(); + Rectangle clip = ((PaintEvent)e).getUpdateRect(); + g.clipRect(clip.x, clip.y, clip.width, clip.height); + //if (this instanceof LightweightPeer) + // { if (e.getID() == PaintEvent.UPDATE) awtComponent.update(g); else awtComponent.paint(g); - // } - // We paint the 'heavyweights' at last, so that they appear on top of - // everything else. - peerPaint(g); - - g.dispose(); + // } + // We paint the 'heavyweights' at last, so that they appear on top of + // everything else. + peerPaint(g); + g.dispose(); + } break; case MouseEvent.MOUSE_PRESSED: case MouseEvent.MOUSE_RELEASED: @@ -384,6 +382,11 @@ public class SwingComponentPeer { if (swingComponent != null) swingComponent.getJComponent().setVisible(false); + + Component parent = awtComponent.getParent(); + if (parent != null) + parent.repaint(awtComponent.getX(), awtComponent.getY(), + awtComponent.getWidth(), awtComponent.getHeight()); } /** @@ -470,17 +473,15 @@ public class SwingComponentPeer public boolean prepareImage(Image img, int width, int height, ImageObserver ob) { Component parent = awtComponent.getParent(); - boolean res; if(parent != null) - { - ComponentPeer parentPeer = parent.getPeer(); - res = parentPeer.prepareImage(img, width, height, ob); - } + { + ComponentPeer parentPeer = parent.getPeer(); + return parentPeer.prepareImage(img, width, height, ob); + } else - { - res = Toolkit.getDefaultToolkit().prepareImage(img, width, height, ob); - } - return res; + { + return Toolkit.getDefaultToolkit().prepareImage(img, width, height, ob); + } } public void print(Graphics graphics) @@ -662,8 +663,10 @@ public class SwingComponentPeer */ public void setVisible(boolean visible) { - if (swingComponent != null) - swingComponent.getJComponent().setVisible(visible); + if (visible) + show(); + else + hide(); } /** @@ -782,8 +785,13 @@ public class SwingComponentPeer public VolatileImage createVolatileImage(int width, int height) { Component parent = awtComponent.getParent(); - ComponentPeer parentPeer = parent.getPeer(); - return parentPeer.createVolatileImage(width, height); + VolatileImage im = null; + if (parent != null) + { + ComponentPeer parentPeer = parent.getPeer(); + im = parentPeer.createVolatileImage(width, height); + } + return im; } /** diff --git a/libjava/classpath/gnu/java/awt/peer/x/GLGraphics.java b/libjava/classpath/gnu/java/awt/peer/x/GLGraphics.java new file mode 100644 index 0000000..c80c85c --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/GLGraphics.java @@ -0,0 +1,123 @@ +/* GLGraphics.java -- Graphics2D impl on top of GLX + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.x; + +import java.awt.Color; +import java.awt.GraphicsConfiguration; +import java.awt.image.ColorModel; + +import gnu.java.awt.java2d.AbstractGraphics2D; +import gnu.x11.extension.glx.GL; + +/** + * An implementation of Graphics2D on top of the GLX extension of X. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class GLGraphics extends AbstractGraphics2D +{ + + /** + * The rendering context. + */ + private GL gl; + + /** + * Creates a new GLGraphics that paints on the specified GL context. + * + * @param g the GL context to paint to + */ + GLGraphics(GL g) + { + gl = g; + } + + public void setBackground(Color b) + { + super.setBackground(b); + gl.clear_color(b.getRed() / 255.F, b.getGreen() / 255.F, + b.getBlue() / 255.F, b.getAlpha() / 255.F); + } + + public void clearRect(int x, int y, int w, int h) + { + // TODO: Maybe use fillRect(). + gl.clear(GL.COLOR_BUFFER_BIT); + } + + public void drawLine(int x1, int y1, int x2, int y2) + { + gl.begin(GL.LINES); + gl.vertex2i(x1, y1); + gl.vertex2i(x2, y2); + gl.end(); + // TODO: Maybe do: + // gl.flush(); + } + + public void drawRect(int x, int y, int w, int h) + { + gl.polygon_mode(GL.FRONT_AND_BACK, GL.LINE); + gl.begin(GL.POLYGON); + gl.recti(x, y, x + w, y + h); + gl.end(); + // TODO: Maybe do: + // gl.flush(); + } + + public void fillRect(int x, int y, int w, int h) + { + gl.polygon_mode(GL.FRONT_AND_BACK, GL.FILL); + gl.recti(x, y, x + w, y + h); + // TODO: Maybe do: + // gl.flush(); + } + + protected ColorModel getColorModel() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public GraphicsConfiguration getDeviceConfiguration() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/ImageConverter.java b/libjava/classpath/gnu/java/awt/peer/x/ImageConverter.java new file mode 100644 index 0000000..6d32448 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/ImageConverter.java @@ -0,0 +1,113 @@ +/* ImageConverter.java -- Convert arbitrary Image impl to XImage + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.x; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.image.ColorModel; +import java.awt.image.ImageConsumer; +import java.util.Hashtable; + +/** + * Convert a non-XImage to an XImage. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class ImageConverter implements ImageConsumer +{ + + private XImage image; + private Graphics imageGraphics; + + public void setDimensions(int width, int height) + { + image = new XImage(width, height); + } + + public void setProperties(Hashtable props) + { + // Ignore for now. + } + + public void setColorModel(ColorModel model) + { + // Ignore for now. + } + + public void setHints(int flags) + { + // Ignore for now. + } + + public void setPixels(int x, int y, int w, int h, ColorModel model, + byte[] pixels, int offset, int scansize) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void setPixels(int x, int y, int w, int h, ColorModel model, + int[] pixels, int offset, int scansize) + { + System.err.println("transferType: " + model.getTransferType()); + System.err.println("colorModel: " + model); + if (imageGraphics == null) + imageGraphics = image.getGraphics(); + int xend = x + w; + int yend = y + h; + for (int yy = y; yy < yend; yy++) + { + for (int xx = x; xx < xend; xx++) + { + int pixel = pixels[yy * scansize + xx + offset]; + imageGraphics.setColor(new Color(model.getRGB(pixel))); + imageGraphics.fillRect(xx, yy, 1, 1); + } + } + } + + public void imageComplete(int status) + { + // Nothing to do here. + } + + XImage getXImage() + { + return image; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/KeyboardMapping.java b/libjava/classpath/gnu/java/awt/peer/x/KeyboardMapping.java new file mode 100644 index 0000000..8e0a31f --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/KeyboardMapping.java @@ -0,0 +1,415 @@ +/* KeyboardMapping.java -- Maps X keysyms to Java keyCode and keyChar + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.x; + +import gnu.x11.Input; +import gnu.x11.keysym.Latin1; +import gnu.x11.keysym.Misc; + +import java.awt.event.KeyEvent; + +/** + * Defines the keyboard mapping from X keysyms to Java + * keycodes and keychars. + * + * @author Roman Kennke (kennke@aicas.com) + */ +final class KeyboardMapping +{ + + /** + * Maps X keycodes to AWT keycodes. + * + * @param xInput the X input event + * @param xKeyCode the X keycode to map + * @param xMods the X modifiers + * + * @return the AWT keycode and keychar + */ + static int mapToKeyCode(gnu.x11.Input xInput, int xKeyCode, int xMods) + { + int mapped = KeyEvent.VK_UNDEFINED; + int keysym = xInput.keycode_to_keysym(xKeyCode, xMods, true); + + // Special keys. + if (keysym >= 255 << 8) + { + // FIXME: Add missing mappings. + switch (keysym) + { + case Misc.BACKSPACE: + mapped = KeyEvent.VK_BACK_SPACE; + break; + case Misc.TAB: + mapped = KeyEvent.VK_TAB; + break; + case Misc.CLEAR: + mapped = KeyEvent.VK_CLEAR; + break; + case Misc.RETURN: + mapped = KeyEvent.VK_ENTER; + break; + case Misc.PAUSE: + mapped = KeyEvent.VK_PAUSE; + break; + case Misc.SCROLL_LOCK: + mapped = KeyEvent.VK_SCROLL_LOCK; + break; + case Misc.ESCAPE: + mapped = KeyEvent.VK_ESCAPE; + break; + case Misc.HOME: + mapped = KeyEvent.VK_HOME; + break; + case Misc.LEFT: + mapped = KeyEvent.VK_LEFT; + break; + case Misc.UP: + mapped = KeyEvent.VK_UP; + break; + case Misc.RIGHT: + mapped = KeyEvent.VK_RIGHT; + break; + case Misc.DOWN: + mapped = KeyEvent.VK_DOWN; + break; + case Misc.PAGE_UP: + mapped = KeyEvent.VK_PAGE_UP; + break; + case Misc.PAGE_DOWN: + mapped = KeyEvent.VK_PAGE_DOWN; + break; + case Misc.END: + mapped = KeyEvent.VK_END; + break; + case Misc.BEGIN: + mapped = KeyEvent.VK_BEGIN; + break; + case Misc.INSERT: + mapped = KeyEvent.VK_INSERT; + break; + case Misc.UNDO: + mapped = KeyEvent.VK_UNDO; + break; + case Misc.FIND: + mapped = KeyEvent.VK_FIND; + break; + case Misc.CANCEL: + mapped = KeyEvent.VK_CANCEL; + break; + case Misc.HELP: + mapped = KeyEvent.VK_HELP; + break; + case Misc.MODE_SWITCH: + mapped = KeyEvent.VK_MODECHANGE; + break; + case Misc.NUM_LOCK: + mapped = KeyEvent.VK_NUM_LOCK; + break; + case Misc.KP_LEFT: + mapped = KeyEvent.VK_KP_LEFT; + break; + case Misc.KP_UP: + mapped = KeyEvent.VK_KP_UP; + break; + case Misc.KP_RIGHT: + mapped = KeyEvent.VK_KP_RIGHT; + break; + case Misc.KP_DOWN: + mapped = KeyEvent.VK_KP_DOWN; + break; + case Misc.F1: + mapped = KeyEvent.VK_F1; + break; + case Misc.F2: + mapped = KeyEvent.VK_F2; + break; + case Misc.F3: + mapped = KeyEvent.VK_F3; + break; + case Misc.F4: + mapped = KeyEvent.VK_F4; + break; + case Misc.F5: + mapped = KeyEvent.VK_F5; + break; + case Misc.F6: + mapped = KeyEvent.VK_F6; + break; + case Misc.F7: + mapped = KeyEvent.VK_F7; + break; + case Misc.F8: + mapped = KeyEvent.VK_F8; + break; + case Misc.F9: + mapped = KeyEvent.VK_F9; + break; + case Misc.F10: + mapped = KeyEvent.VK_F10; + break; + case Misc.F11: + mapped = KeyEvent.VK_F11; + break; + case Misc.F12: + mapped = KeyEvent.VK_F12; + break; + case Misc.F13: + mapped = KeyEvent.VK_F13; + break; + case Misc.F14: + mapped = KeyEvent.VK_F14; + break; + case Misc.F15: + mapped = KeyEvent.VK_F15; + break; + case Misc.F16: + mapped = KeyEvent.VK_F16; + break; + case Misc.F17: + mapped = KeyEvent.VK_F17; + break; + case Misc.F18: + mapped = KeyEvent.VK_F18; + break; + case Misc.F19: + mapped = KeyEvent.VK_F19; + break; + case Misc.F20: + mapped = KeyEvent.VK_F20; + break; + case Misc.F21: + mapped = KeyEvent.VK_F21; + break; + case Misc.F22: + mapped = KeyEvent.VK_F22; + break; + case Misc.F23: + mapped = KeyEvent.VK_F23; + break; + case Misc.F24: + mapped = KeyEvent.VK_F24; + break; + case Misc.SHIFT_L: + case Misc.SHIFT_R: + mapped = KeyEvent.VK_SHIFT; + break; + case Misc.CONTROL_L: + case Misc.CONTROL_R: + mapped = KeyEvent.VK_CONTROL; + break; + case Misc.CAPS_LOCK: + case Misc.SHIFT_LOCK: + mapped = KeyEvent.VK_CAPS_LOCK; + break; + case Misc.META_L: + case Misc.META_R: + mapped = KeyEvent.VK_META; + break; + case Misc.ALT_L: + case Misc.ALT_R: + mapped = KeyEvent.VK_ALT; + break; + case Misc.DELETE: + mapped = KeyEvent.VK_DELETE; + break; + default: + mapped = KeyEvent.VK_UNDEFINED; + } + } + // Map Latin1 characters. + else if (keysym < 256) + { + // TODO: Add missing mappings, if any. + // Lowercase characters are mapped to + // their corresponding upper case pendants. + if (keysym >= Latin1.A_SMALL && keysym <= Latin1.Z_SMALL) + mapped = keysym - 0x20; + // Uppercase characters are mapped 1:1. + else if (keysym >= Latin1.A && keysym <= Latin1.Z) + mapped = keysym; + // Digits are mapped 1:1. + else if (keysym >= Latin1.NUM_0 && keysym <= Latin1.NUM_9) + mapped = keysym; + else + { + switch (keysym) + { + case Latin1.SPACE: + mapped = KeyEvent.VK_SPACE; + break; + case Latin1.EXCLAM: + mapped = KeyEvent.VK_EXCLAMATION_MARK; + break; + case Latin1.QUOTE_DBL: + mapped = KeyEvent.VK_QUOTEDBL; + break; + case Latin1.NUMBER_SIGN: + mapped = KeyEvent.VK_NUMBER_SIGN; + break; + case Latin1.DOLLAR: + mapped = KeyEvent.VK_DOLLAR; + break; + case Latin1.AMPERSAND: + mapped = KeyEvent.VK_AMPERSAND; + break; + case Latin1.APOSTROPHE: + mapped = KeyEvent.VK_QUOTE; + break; + case Latin1.PAREN_LEFT: + mapped = KeyEvent.VK_LEFT_PARENTHESIS; + break; + case Latin1.PAREN_RIGHT: + mapped = KeyEvent.VK_RIGHT_PARENTHESIS; + break; + case Latin1.ASTERISK: + mapped = KeyEvent.VK_ASTERISK; + break; + case Latin1.PLUS: + mapped = KeyEvent.VK_PLUS; + break; + case Latin1.COMMA: + mapped = KeyEvent.VK_COMMA; + break; + case Latin1.MINUS: + mapped = KeyEvent.VK_MINUS; + break; + case Latin1.PERIOD: + mapped = KeyEvent.VK_PERIOD; + break; + case Latin1.SLASH: + mapped = KeyEvent.VK_SLASH; + break; + case Latin1.COLON: + mapped = KeyEvent.VK_COLON; + break; + case Latin1.SEMICOLON: + mapped = KeyEvent.VK_SEMICOLON; + break; + case Latin1.LESS: + mapped = KeyEvent.VK_LESS; + break; + case Latin1.EQUAL: + mapped = KeyEvent.VK_EQUALS; + break; + case Latin1.GREATER: + mapped = KeyEvent.VK_GREATER; + break; + case Latin1.AT: + mapped = KeyEvent.VK_AT; + break; + case Latin1.BRACKET_LEFT: + mapped = KeyEvent.VK_OPEN_BRACKET; + break; + case Latin1.BACKSLASH: + mapped = KeyEvent.VK_BACK_SLASH; + break; + case Latin1.BRACKET_RIGHT: + mapped = KeyEvent.VK_CLOSE_BRACKET; + break; + case Latin1.ASCII_CIRCUM: + mapped = KeyEvent.VK_CIRCUMFLEX; + break; + case Latin1.UNDERSCORE: + mapped = KeyEvent.VK_UNDERSCORE; + break; + case Latin1.GRAVE: + mapped = KeyEvent.VK_DEAD_GRAVE; + break; + case Latin1.BRACE_LEFT: + mapped = KeyEvent.VK_BRACELEFT; + break; + case Latin1.BRACE_RIGHT: + mapped = KeyEvent.VK_BRACERIGHT; + break; + case Latin1.ASCII_TILDE: + mapped = KeyEvent.VK_DEAD_TILDE; + break; + case Latin1.EXCLAM_DOWN: + mapped = KeyEvent.VK_INVERTED_EXCLAMATION_MARK; + break; + default: + mapped = KeyEvent.VK_UNDEFINED; + } + } + } + return mapped; + } + + /** + * Maps X keycodes+modifiers to Java keychars. + * + * @param xInput The X Input to use for mapping + * @param xKeyCode the X keycode + * @param xMods the X key modifiers + * + * @return the Java keychar + */ + static char mapToKeyChar(gnu.x11.Input xInput, int xKeyCode, int xMods) + { + char mapped = KeyEvent.CHAR_UNDEFINED; + char keysym = (char) xInput.keycode_to_keysym(xKeyCode, xMods, false); + // FIXME: Map other encodings properly. + if (keysym < 256) // Latin1. + { + mapped = keysym; + } + return mapped; + } + + /** + * Maps X modifier masks to AWT modifier masks. + * + * @param xMods the X modifiers + * + * @return the AWT modifiers + */ + static int mapModifiers(int xMods) + { + int mods = 0; + + if ((xMods & Input.SHIFT_MASK) != 0) + mods |= KeyEvent.SHIFT_MASK | KeyEvent.SHIFT_DOWN_MASK; + if ((xMods & Input.ALT_MASK) != 0) + mods |= KeyEvent.ALT_MASK | KeyEvent.ALT_DOWN_MASK; + if ((xMods & Input.CONTROL_MASK) != 0) + mods |= KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK; + + return mods; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/x/XDialogPeer.java new file mode 100644 index 0000000..45ad24d --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XDialogPeer.java @@ -0,0 +1,61 @@ +/* XDialogPeer.java -- The peer for AWT dialogs + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.x; + +import java.awt.Dialog; +import java.awt.peer.DialogPeer; + +public class XDialogPeer + extends XWindowPeer + implements DialogPeer +{ + + XDialogPeer(Dialog target) + { + super(target); + } + + public void setResizable(boolean resizeable) + { + } + + public void setTitle(String title) + { + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XEventPump.java b/libjava/classpath/gnu/java/awt/peer/x/XEventPump.java new file mode 100644 index 0000000..870edf3 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XEventPump.java @@ -0,0 +1,287 @@ +/* XEventPump.java -- Pumps events from X to AWT + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.x; + +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.ComponentEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.PaintEvent; +import java.util.HashMap; + +import gnu.x11.Display; +import gnu.x11.event.ButtonPress; +import gnu.x11.event.ButtonRelease; +import gnu.x11.event.ConfigureNotify; +import gnu.x11.event.Event; +import gnu.x11.event.Expose; +import gnu.x11.event.Input; +import gnu.x11.event.KeyPress; +import gnu.x11.event.KeyRelease; +import gnu.x11.event.MotionNotify; + +/** + * Fetches events from X, translates them to AWT events and pumps them up + * into the AWT event queue. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class XEventPump + implements Runnable +{ + + /** + * The X Display from which we fetch and pump up events. + */ + private Display display; + + /** + * Maps X Windows to AWT Windows to be able to correctly determine the + * event targets. + */ + private HashMap windows; + + /** + * Indicates if we are currently inside a drag operation. This is + * set to the button ID when a button is pressed and to -1 (indicating + * that no drag is active) when the mouse is released. + */ + private int drag; + + /** + * Creates a new XEventPump for the specified X Display. + * + * @param d the X Display + */ + XEventPump(Display d) + { + display = d; + windows = new HashMap(); + drag = -1; + Thread t = new Thread(this); + t.start(); + } + + /** + * The main event pump loop. This basically fetches events from the + * X Display and pumps them into the system event queue. + */ + public void run() + { + while (display.connected) + { + try + { + Event xEvent = display.next_event(); + handleEvent(xEvent); + } + catch (ThreadDeath death) + { + // If someone wants to kill us, let them. + return; + } + catch (Throwable x) + { + System.err.println("Exception during event dispatch:"); + x.printStackTrace(System.err); + } + } + } + + /** + * Adds an X Window to AWT Window mapping. This is required so that the + * event pump can correctly determine the event targets. + * + * @param xWindow the X Window + * @param awtWindow the AWT Window + */ + void registerWindow(gnu.x11.Window xWindow, Window awtWindow) + { + if (XToolkit.DEBUG) + System.err.println("registering window id: " + xWindow.id); + windows.put(new Integer(xWindow.id), awtWindow); + } + + void unregisterWindow(gnu.x11.Window xWindow) + { + windows.remove(new Integer(xWindow.id)); + } + + private void handleEvent(Event xEvent) + { + Integer key = new Integer(xEvent.window_id());; + Window awtWindow = (Window) windows.get(key); + + if (XToolkit.DEBUG) + System.err.println("fetched event: " + xEvent); + switch (xEvent.code()) + { + case ButtonPress.CODE: + ButtonPress bp = (ButtonPress) xEvent; + // Create and post the mouse event. + int button = bp.detail(); + drag = button; + MouseEvent mp = new MouseEvent(awtWindow, MouseEvent.MOUSE_PRESSED, + System.currentTimeMillis(), 0, + bp.event_x(), bp.event_y(), + 1, false, button); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mp); + break; + case ButtonRelease.CODE: + ButtonRelease br = (ButtonRelease) xEvent; + drag = -1; + MouseEvent mr = new MouseEvent(awtWindow, MouseEvent.MOUSE_RELEASED, + System.currentTimeMillis(), 0, + br.event_x(), br.event_y(), + 1, false, br.detail()); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mr); + break; + case MotionNotify.CODE: + MotionNotify mn = (MotionNotify) xEvent; + MouseEvent mm; + if (drag == -1) + { + mm = new MouseEvent(awtWindow, MouseEvent.MOUSE_MOVED, + System.currentTimeMillis(), 0, + mn.event_x(), mn.event_y(), + 1, false); + } + else + { + mm = new MouseEvent(awtWindow, MouseEvent.MOUSE_DRAGGED, + System.currentTimeMillis(), 0, + mn.event_x(), mn.event_y(), + 1, false); + } + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mm); + break; + case ConfigureNotify.CODE: + ConfigureNotify c = (ConfigureNotify) xEvent; + if (XToolkit.DEBUG) + System.err.println("resize request for window id: " + key); + + // Detect and report size changes. + if (c.width() != awtWindow.getWidth() + || c.height() != awtWindow.getHeight()) + { + if (XToolkit.DEBUG) + System.err.println("Setting size on AWT window: " + c.width() + + ", " + c.height() + ", " + awtWindow.getWidth() + + ", " + awtWindow.getHeight()); + ((XWindowPeer) awtWindow.getPeer()).callback = true; + awtWindow.setSize(c.width(), c.height()); + ((XWindowPeer) awtWindow.getPeer()).callback = false; + } + break; + case Expose.CODE: + Expose exp = (Expose) xEvent; + if (XToolkit.DEBUG) + System.err.println("expose request for window id: " + key); + Rectangle r = new Rectangle(exp.x(), exp.y(), exp.width(), + exp.height()); + //System.err.println("expose paint: " + r); + // We need to clear the background of the exposed rectangle. + Graphics g = awtWindow.getGraphics(); + g.clearRect(r.x, r.y, r.width, r.height); + g.dispose(); + PaintEvent pev = new PaintEvent(awtWindow, PaintEvent.PAINT, r); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(pev); + break; + case KeyPress.CODE: + case KeyRelease.CODE: + handleKeyEvent(xEvent, awtWindow); + break; + default: + if (XToolkit.DEBUG) + System.err.println("Unhandled X event: " + xEvent); + } + } + + /** + * Handles key events from X. + * + * @param xEvent the X event + * @param awtWindow the AWT window to which the event gets posted + */ + private void handleKeyEvent(Event xEvent, Window awtWindow) + { + Input keyEvent = (Input) xEvent; + int xKeyCode = keyEvent.detail(); + int xMods = keyEvent.state(); + int keyCode = KeyboardMapping.mapToKeyCode(xEvent.display.input, xKeyCode, + xMods); + char keyChar = KeyboardMapping.mapToKeyChar(xEvent.display.input, xKeyCode, + xMods); + if (XToolkit.DEBUG) + System.err.println("XEventPump.handleKeyEvent: " + xKeyCode + ", " + + xMods + ": " + ((int) keyChar) + ", " + keyCode); + int awtMods = KeyboardMapping.mapModifiers(xMods); + long when = System.currentTimeMillis(); + KeyEvent ke; + if (keyEvent.code() == KeyPress.CODE) + { + ke = new KeyEvent(awtWindow, KeyEvent.KEY_PRESSED, when, + awtMods, keyCode, + KeyEvent.CHAR_UNDEFINED); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ke); + if (keyChar != KeyEvent.CHAR_UNDEFINED) + { + ke = new KeyEvent(awtWindow, KeyEvent.KEY_TYPED, when, + awtMods, KeyEvent.VK_UNDEFINED, + keyChar); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ke); + } + + } + else + { + ke = new KeyEvent(awtWindow, KeyEvent.KEY_RELEASED, when, + awtMods, keyCode, + KeyEvent.CHAR_UNDEFINED); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ke); + } + + } + + +} + diff --git a/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java b/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java new file mode 100644 index 0000000..fd293d8 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java @@ -0,0 +1,766 @@ +/* XFontPeer.java -- The font peer for X + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.x; + +import java.awt.AWTError; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; +import java.awt.font.TextAttribute; +import java.awt.geom.Rectangle2D; +import java.io.IOException; +import java.io.InputStream; +import java.text.CharacterIterator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; + +import gnu.java.awt.peer.ClasspathFontPeer; +import gnu.x11.Display; +import gnu.x11.Fontable; + +/** + * The bridge from AWT to X fonts. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class XFontPeer + extends ClasspathFontPeer +{ + + /** + * The font mapping as specified in the file fonts.properties. + */ + private static Properties fontProperties; + static + { + fontProperties = new Properties(); + InputStream in = XFontPeer.class.getResourceAsStream("fonts.properties"); + try + { + fontProperties.load(in); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + /** + * The FontMetrics implementation for XFontPeer. + */ + private class XFontMetrics + extends FontMetrics + { + /** + * The ascent of the font. + */ + int ascent; + + /** + * The descent of the font. + */ + int descent; + + /** + * The maximum of the character advances. + */ + private int maxAdvance; + + /** + * The internal leading. + */ + int leading; + + /** + * Cached string metrics. This caches string metrics locally so that the + * server doesn't have to be asked each time. + */ + private HashMap metricsCache; + + /** + * The widths of the characters indexed by the characters themselves. + */ + private int[] charWidths; + + /** + * Creates a new XFontMetrics for the specified font. + * + * @param font the font + */ + protected XFontMetrics(Font font) + { + super(font); + metricsCache = new HashMap(); + Fontable.FontReply info = getXFont().info(); + ascent = info.font_ascent(); + descent = info.font_descent(); + maxAdvance = info.max_bounds().character_width(); + leading = 0; // TODO: Not provided by X. Possible not needed. + + if (info.min_byte1() == 0 && info.max_byte1() == 0) + readCharWidthsLinear(info); + else + readCharWidthsNonLinear(info); + } + + /** + * Reads the character widths when specified in a linear fashion. That is + * when the min-byte1 and max-byte2 fields are both zero in the X protocol. + * + * @param info the font info reply + */ + private void readCharWidthsLinear(Fontable.FontReply info) + { + int startIndex = info.min_char_or_byte2(); + int endIndex = info.max_char_or_byte2(); + charWidths = new int[endIndex + 1]; + // All the characters before startIndex are zero width. + for (int i = 0; i < startIndex; i++) + { + charWidths[i] = 0; + } + // All the other character info is fetched from the font info. + int index = startIndex; + Iterator charInfos = info.char_infos().iterator(); + while (charInfos.hasNext()) + { + Fontable.FontReply.CharInfo charInfo = + (Fontable.FontReply.CharInfo) charInfos.next(); + charWidths[index] = charInfo.character_width(); + index++; + } + } + + private void readCharWidthsNonLinear(Fontable.FontReply info) + { + // TODO: Implement. + throw new UnsupportedOperationException("Not yet implemented"); + } + + /** + * Returns the ascent of the font. + * + * @return the ascent of the font + */ + public int getAscent() + { + return ascent; + } + + /** + * Returns the descent of the font. + * + * @return the descent of the font + */ + public int getDescent() + { + return descent; + } + + /** + * Returns the overall height of the font. This is the distance from + * baseline to baseline (usually ascent + descent + leading). + * + * @return the overall height of the font + */ + public int getHeight() + { + return ascent + descent; + } + + /** + * Returns the leading of the font. + * + * @return the leading of the font + */ + public int getLeading() + { + return leading; + } + + /** + * Returns the maximum advance for this font. + * + * @return the maximum advance for this font + */ + public int getMaxAdvance() + { + return maxAdvance; + } + + /** + * Determines the width of the specified character c. + * + * @param c the character + * + * @return the width of the character + */ + public int charWidth(char c) + { + int width; + if (c > charWidths.length) + width = charWidths['?']; + else + width = charWidths[c]; + return width; + } + + /** + * Determines the overall width of the specified string. + * + * @param c the char buffer holding the string + * @param offset the starting offset of the string in the buffer + * @param length the number of characters in the string buffer + * + * @return the overall width of the specified string + */ + public int charsWidth(char[] c, int offset, int length) + { + int width = 0; + if (c.length > 0 && length > 0) + { + String s = new String(c, offset, length); + width = stringWidth(s); + } + return width; + } + + /** + * Determines the overall width of the specified string. + * + * @param s the string + * + * @return the overall width of the specified string + */ + public int stringWidth(String s) + { + int width = 0; + if (s.length() > 0) + { + if (metricsCache.containsKey(s)) + { + width = ((Integer) metricsCache.get(s)).intValue(); + } + else + { + Fontable.TextExtentReply extents = getXFont().text_extent(s); + /* + System.err.println("string: '" + s + "' : "); + System.err.println("ascent: " + extents.getAscent()); + System.err.println("descent: " + extents.getDescent()); + System.err.println("overall ascent: " + extents.getOverallAscent()); + System.err.println("overall descent: " + extents.getOverallDescent()); + System.err.println("overall width: " + extents.getOverallWidth()); + System.err.println("overall left: " + extents.getOverallLeft()); + System.err.println("overall right: " + extents.getOverallRight()); + */ + width = extents.overall_width(); // + extents.overall_left(); + //System.err.println("String: " + s + ", width: " + width); + metricsCache.put(s, new Integer(width)); + } + } + //System.err.print("stringWidth: '" + s + "': "); + //System.err.println(width); + return width; + } + } + + /** + * The LineMetrics implementation for the XFontPeer. + */ + private class XLineMetrics + extends LineMetrics + { + + /** + * Returns the ascent of the font. + * + * @return the ascent of the font + */ + public float getAscent() + { + return fontMetrics.ascent; + } + + public int getBaselineIndex() + { + // FIXME: Implement this. + throw new UnsupportedOperationException(); + } + + public float[] getBaselineOffsets() + { + // FIXME: Implement this. + throw new UnsupportedOperationException(); + } + + /** + * Returns the descent of the font. + * + * @return the descent of the font + */ + public float getDescent() + { + return fontMetrics.descent; + } + + /** + * Returns the overall height of the font. This is the distance from + * baseline to baseline (usually ascent + descent + leading). + * + * @return the overall height of the font + */ + public float getHeight() + { + return fontMetrics.ascent + fontMetrics.descent; + } + + /** + * Returns the leading of the font. + * + * @return the leading of the font + */ + public float getLeading() + { + return fontMetrics.leading; + } + + public int getNumChars() + { + // FIXME: Implement this. + throw new UnsupportedOperationException(); + } + + public float getStrikethroughOffset() + { + return 0.F; // TODO: Provided by X?? + } + + public float getStrikethroughThickness() + { + return 1.F; // TODO: Provided by X?? + } + + public float getUnderlineOffset() + { + return 0.F; // TODO: Provided by X?? + } + + public float getUnderlineThickness() + { + return 1.F; // TODO: Provided by X?? + } + + } + + /** + * The X font. + */ + private gnu.x11.Font xfont; + + private String name; + + private int style; + + private int size; + + /** + * The font metrics for this font. + */ + XFontMetrics fontMetrics; + + /** + * Creates a new XFontPeer for the specified font name, style and size. + * + * @param name the font name + * @param style the font style (bold / italic / normal) + * @param size the size of the font + */ + public XFontPeer(String name, int style, int size) + { + super(name, style, size); + this.name = name; + this.style = style; + this.size = size; + } + + /** + * Creates a new XFontPeer for the specified font name and style + * attributes. + * + * @param name the font name + * @param atts the font attributes + */ + public XFontPeer(String name, Map atts) + { + super(name, atts); + String family = name; + if (family == null || family.equals("")) + family = (String) atts.get(TextAttribute.FAMILY); + if (family == null) + family = "SansSerif"; + + int size = 12; + Float sizeFl = (Float) atts.get(TextAttribute.SIZE); + if (sizeFl != null) + size = sizeFl.intValue(); + + int style = 0; + // Detect italic attribute. + Float posture = (Float) atts.get(TextAttribute.POSTURE); + if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR)) + style |= Font.ITALIC; + + // Detect bold attribute. + Float weight = (Float) atts.get(TextAttribute.WEIGHT); + if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0) + style |= Font.BOLD; + + this.name = name; + this.style = style; + this.size = size; + } + + /** + * Initializes the font peer with the specified attributes. This method is + * called from both constructors. + * + * @param name the font name + * @param style the font style + * @param size the font size + */ + private void init(String name, int style, int size) + { + GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice dev = env.getDefaultScreenDevice(); + if (dev instanceof XGraphicsDevice) + { + Display display = ((XGraphicsDevice) dev).getDisplay(); + String fontDescr = encodeFont(name, style, size); + if (XToolkit.DEBUG) + System.err.println("XLFD font description: " + fontDescr); + xfont = new gnu.x11.Font(display, fontDescr); + } + else + { + throw new AWTError("Local GraphicsEnvironment is not XWindowGraphicsEnvironment"); + } + } + + public boolean canDisplay(Font font, char c) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public String getSubFamilyName(Font font, Locale locale) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public String getPostScriptName(Font font) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public int getNumGlyphs(Font font) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public int getMissingGlyphCode(Font font) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public byte getBaselineFor(Font font, char c) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public String getGlyphName(Font font, int glyphIndex) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public GlyphVector createGlyphVector(Font font, FontRenderContext frc, + CharacterIterator ci) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public GlyphVector createGlyphVector(Font font, FontRenderContext ctx, + int[] glyphCodes) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc, + char[] chars, int start, int limit, + int flags) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + /** + * Returns the font metrics for the specified font. + * + * @param font the font for which to fetch the font metrics + * + * @return the font metrics for the specified font + */ + public FontMetrics getFontMetrics(Font font) + { + if (font.getPeer() != this) + throw new AWTError("The specified font has a different peer than this"); + + if (fontMetrics == null) + fontMetrics = new XFontMetrics(font); + return fontMetrics; + } + + /** + * Frees the font in the X server. + */ + protected void finalize() + { + if (xfont != null) + xfont.close(); + } + + public boolean hasUniformLineMetrics(Font font) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + /** + * Returns the line metrics for this font and the specified string and + * font render context. + */ + public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin, + int limit, FontRenderContext rc) + { + return new XLineMetrics(); + } + + public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public Rectangle2D getStringBounds(Font font, CharacterIterator ci, + int begin, int limit, FontRenderContext frc) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + /** + * Encodes a font name + style + size specification into a X logical font + * description (XLFD) as described here: + * + * http://www.meretrx.com/e93/docs/xlfd.html + * + * This is implemented to look up the font description in the + * fonts.properties of this package. + * + * @param name the font name + * @param atts the text attributes + * + * @return the encoded font description + */ + static String encodeFont(String name, Map atts) + { + String family = name; + if (family == null || family.equals("")) + family = (String) atts.get(TextAttribute.FAMILY); + if (family == null) + family = "SansSerif"; + + int size = 12; + Float sizeFl = (Float) atts.get(TextAttribute.SIZE); + if (sizeFl != null) + size = sizeFl.intValue(); + + int style = 0; + // Detect italic attribute. + Float posture = (Float) atts.get(TextAttribute.POSTURE); + if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR)) + style |= Font.ITALIC; + + // Detect bold attribute. + Float weight = (Float) atts.get(TextAttribute.WEIGHT); + if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0) + style |= Font.BOLD; + + return encodeFont(name, style, size); + } + + /** + * Encodes a font name + style + size specification into a X logical font + * description (XLFD) as described here: + * + * http://www.meretrx.com/e93/docs/xlfd.html + * + * This is implemented to look up the font description in the + * fonts.properties of this package. + * + * @param name the font name + * @param style the font style + * @param size the font size + * + * @return the encoded font description + */ + static String encodeFont(String name, int style, int size) + { + StringBuilder key = new StringBuilder(); + key.append(validName(name)); + key.append('.'); + switch (style) + { + case Font.BOLD: + key.append("bold"); + break; + case Font.ITALIC: + key.append("italic"); + break; + case (Font.BOLD | Font.ITALIC): + key.append("bolditalic"); + break; + case Font.PLAIN: + default: + key.append("plain"); + + } + + String protoType = fontProperties.getProperty(key.toString()); + int s = validSize(size); + return protoType.replaceFirst("%d", String.valueOf(s * 10)); + } + + /** + * Checks the specified font name for a valid font name. If the font name + * is not known, then this returns 'sansserif' as fallback. + * + * @param name the font name to check + * + * @return a valid font name + */ + static String validName(String name) + { + String retVal; + if (name.equalsIgnoreCase("sansserif") + || name.equalsIgnoreCase("serif") + || name.equalsIgnoreCase("monospaced") + || name.equalsIgnoreCase("dialog") + || name.equalsIgnoreCase("dialoginput")) + { + retVal = name.toLowerCase(); + } + else + { + retVal = "sansserif"; + } + return retVal; + } + + /** + * Translates an arbitrary point size to a size that is typically available + * on an X server. These are the sizes 8, 10, 12, 14, 18 and 24. + * + * @param size the queried size + * @return the real available size + */ + private static final int validSize(int size) + { + int val; + if (size <= 9) + val = 8; + else if (size <= 11) + val = 10; + else if (size <= 13) + val = 12; + else if (size <= 17) + val = 14; + else if (size <= 23) + val = 18; + else + val = 24; + return val; + } + + /** + * Returns the X Font reference. This lazily loads the font when first + * requested. + * + * @return the X Font reference + */ + gnu.x11.Font getXFont() + { + if (xfont == null) + { + init(name, style, size); + } + return xfont; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java b/libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java new file mode 100644 index 0000000..25371de --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java @@ -0,0 +1,335 @@ +/* XFontPeer2.java -- A Java based TTF font peer for X + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.x; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.io.File; +import java.io.FileInputStream; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.Locale; +import java.util.Map; + +import gnu.java.awt.font.FontDelegate; +import gnu.java.awt.font.FontFactory; +import gnu.java.awt.peer.ClasspathFontPeer; + +public class XFontPeer2 + extends ClasspathFontPeer +{ + + private class XLineMetrics + extends LineMetrics + { + + private Font font; +// private CharacterIterator characterIterator; +// private int begin; +// private int limit; + private FontRenderContext fontRenderContext; + XLineMetrics(Font f, CharacterIterator ci, int b, int l, + FontRenderContext rc) + { + font = f; +// characterIterator = ci; +// begin = b; +// limit = l; + fontRenderContext = rc; + } + + public float getAscent() + { + return fontDelegate.getAscent(font.getSize(), fontRenderContext.getTransform(), + fontRenderContext.isAntiAliased(), + fontRenderContext.usesFractionalMetrics(), true); + } + + public int getBaselineIndex() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public float[] getBaselineOffsets() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public float getDescent() + { + return (int) fontDelegate.getDescent(font.getSize(), + new AffineTransform(), false, false, + false); + } + + public float getHeight() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public float getLeading() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public int getNumChars() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public float getStrikethroughOffset() + { + return 0.F; + } + + public float getStrikethroughThickness() + { + return 0.F; + } + + public float getUnderlineOffset() + { + return 0.F; + } + + public float getUnderlineThickness() + { + return 0.F; + } + + } + + private class XFontMetrics + extends FontMetrics + { + XFontMetrics(Font f) + { + super(f); + } + + public int getAscent() + { + return (int) fontDelegate.getAscent(getFont().getSize(), + new AffineTransform(), false, false, + false); + } + + public int getDescent() + { + return (int) fontDelegate.getDescent(getFont().getSize(), + new AffineTransform(), false, false, + false); + } + + public int getHeight() + { + GlyphVector gv = fontDelegate.createGlyphVector(getFont(), + new FontRenderContext(new AffineTransform(), false, false), + new StringCharacterIterator("m")); + Rectangle2D b = gv.getVisualBounds(); + return (int) b.getHeight(); + } + + public int charWidth(char c) + { + Point2D advance = new Point2D.Double(); + fontDelegate.getAdvance(c, getFont().getSize(), new AffineTransform(), + false, false, true, advance); + return (int) advance.getX(); + } + + public int charsWidth(char[] chars, int offs, int len) + { + return stringWidth(new String(chars, offs, len)); + } + + public int stringWidth(String s) + { + GlyphVector gv = fontDelegate.createGlyphVector(getFont(), + new FontRenderContext(new AffineTransform(), false, false), + new StringCharacterIterator(s)); + Rectangle2D b = gv.getVisualBounds(); + return (int) b.getWidth(); + } + } + + private FontDelegate fontDelegate; + + XFontPeer2(String name, int style, int size) + { + super(name, style, size); + try + { + File fontfile = new File("/usr/share/fonts/truetype/ttf-bitstream-vera/Vera.ttf"); + FileInputStream in = new FileInputStream(fontfile); + FileChannel ch = in.getChannel(); + ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, + fontfile.length()); + fontDelegate = FontFactory.createFonts(buffer)[0]; + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + XFontPeer2(String name, Map atts) + { + super(name, atts); + try + { + File fontfile = new File("/usr/share/fonts/truetype/freefont/FreeSans.ttf"); + FileInputStream in = new FileInputStream(fontfile); + FileChannel ch = in.getChannel(); + ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, + fontfile.length()); + fontDelegate = FontFactory.createFonts(buffer)[0]; + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + public boolean canDisplay(Font font, char c) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public String getSubFamilyName(Font font, Locale locale) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public String getPostScriptName(Font font) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public int getNumGlyphs(Font font) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public int getMissingGlyphCode(Font font) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public byte getBaselineFor(Font font, char c) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public String getGlyphName(Font font, int glyphIndex) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public GlyphVector createGlyphVector(Font font, FontRenderContext frc, CharacterIterator ci) + { + return fontDelegate.createGlyphVector(font, frc, ci); + } + + public GlyphVector createGlyphVector(Font font, FontRenderContext ctx, int[] glyphCodes) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc, char[] chars, int start, int limit, int flags) + { + StringCharacterIterator i = new StringCharacterIterator(new String(chars), start, limit, 0); + return fontDelegate.createGlyphVector(font, frc, i); + } + + public FontMetrics getFontMetrics(Font font) + { + return new XFontMetrics(font); + } + + public boolean hasUniformLineMetrics(Font font) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin, int limit, FontRenderContext rc) + { + return new XLineMetrics(font, ci, begin, limit, rc); + } + + public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public Rectangle2D getStringBounds(Font font, CharacterIterator ci, int begin, int limit, FontRenderContext frc) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java b/libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java new file mode 100644 index 0000000..439a2a7 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java @@ -0,0 +1,140 @@ +/* XFramePeer.java -- The X FramePeer implementation + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.x; + +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Insets; +import java.awt.MenuBar; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.PaintEvent; +import java.awt.event.WindowEvent; +import java.awt.peer.FramePeer; + +import gnu.java.awt.peer.swing.SwingFramePeer; +import gnu.x11.Window; +import gnu.x11.event.Event; + +public class XFramePeer + extends XWindowPeer + implements FramePeer +{ + + XFramePeer(Frame f) + { + super(f); + } + + public void setIconImage(Image image) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void setMenuBar(MenuBar mb) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void setResizable(boolean resizable) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void setTitle(String title) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public int getState() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void setState(int state) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void setMaximizedBounds(Rectangle r) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + /** + * Check if this frame peer supports being restacked. + * + * @return true if this frame peer can be restacked, + * false otherwise + * @since 1.5 + */ + public boolean isRestackSupported() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + /** + * Sets the bounds of this frame peer. + * + * @param x the new x co-ordinate + * @param y the new y co-ordinate + * @param width the new width + * @param height the new height + * @since 1.5 + */ + public void setBoundsPrivate(int x, int y, int width, int height) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphics.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphics.java new file mode 100644 index 0000000..134d7d3 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XGraphics.java @@ -0,0 +1,792 @@ +/* XGraphics.java -- The Graphics implementation for X + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.x; + +import gnu.x11.Colormap; +import gnu.x11.Data; +import gnu.x11.Display; +import gnu.x11.Drawable; +import gnu.x11.GC; +import gnu.x11.Pixmap; +import gnu.x11.Point; +import gnu.x11.image.ZPixmap; + +import java.awt.AWTError; +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.Toolkit; +import java.awt.Transparency; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.text.AttributedCharacterIterator; +import java.util.HashMap; + +public class XGraphics + extends Graphics + implements Cloneable +{ + + /** + * The X Drawable to draw on. + */ + private Drawable xdrawable; + + /** + * The X graphics context (GC). + */ + private GC xgc; + + /** + * The current translation. + */ + private int translateX; + private int translateY; + + /** + * The current clip. Possibly null. + */ + private Rectangle clip; + + /** + * The current font, possibly null. + */ + private Font font; + + /** + * The current foreground color, possibly null. + */ + private Color foreground; + + /** + * Indicates if this object has been disposed. + */ + private boolean disposed = false; + + // TODO: Workaround for limitation in current Escher. + private Pixmap.Format pixmapFormat; + private int imageByteOrder; + private int pixelByteCount; + + /** + * Creates a new XGraphics on the specified X Drawable. + * + * @param d the X Drawable for which we create the Graphics + */ + XGraphics(Drawable d) + { + xdrawable = d; + xgc = new GC(d); + translateX = 0; + translateY = 0; + clip = new Rectangle(0, 0, d.width, d.height); + + Display display = xdrawable.display; + pixmapFormat = display.default_pixmap_format; + imageByteOrder = display.image_byte_order; + pixelByteCount = pixmapFormat.bits_per_pixel () / 8; + } + + /** + * Creates an exact copy of this graphics context. + * + * @return an exact copy of this graphics context + */ + public Graphics create() + { + XGraphics copy = (XGraphics) clone(); + return copy; + } + + /** + * Translates the origin by (x, y). + */ + public void translate(int x, int y) + { + translateX += x; + translateY += y; + if (clip != null) + { + clip.x -= x; + clip.y -= y; + } + } + + /** + * Returns the current foreground color, possibly null. + * + * @return the current foreground color, possibly null + */ + public Color getColor() + { + return foreground; + } + + /** + * Sets the current foreground color. A null value doesn't + * change the current setting. + * + * @param c the foreground color to set + */ + public void setColor(Color c) + { + if (c != null) + { + XToolkit tk = (XToolkit) Toolkit.getDefaultToolkit(); + HashMap colorMap = tk.colorMap; + gnu.x11.Color col = (gnu.x11.Color) colorMap.get(c); + if (col == null) + { + Colormap map = xdrawable.display.default_colormap; + col = map.alloc_color (c.getRed() * 256, + c.getGreen() * 256, + c.getBlue() * 256); + colorMap.put(c, col); + } + xgc.set_foreground(col); + foreground = c; + } + } + + public void setPaintMode() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void setXORMode(Color color) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + /** + * Returns the current font, possibly null. + * + * @return the current font, possibly null + */ + public Font getFont() + { + return font; + } + + /** + * Sets the font on the graphics context. A null value doesn't + * change the current setting. + * + * @param f the font to set + */ + public void setFont(Font f) + { + if (f != null) + { + XFontPeer xFontPeer = (XFontPeer) f.getPeer(); + xgc.set_font(xFontPeer.getXFont()); + font = f; + } + } + + /** + * Returns the font metrics for the specified font. + * + * @param font the font for which we want the font metrics + * + * @return the font metrics for the specified font + */ + public FontMetrics getFontMetrics(Font font) + { + if (font == null) + { + if (this.font == null) + setFont(new Font("Dialog", Font.PLAIN, 12)); + font = this.font; + } + XFontPeer xFontPeer = (XFontPeer) font.getPeer(); + return xFontPeer.getFontMetrics(font); + } + + /** + * Returns the bounds of the current clip. + * + * @return the bounds of the current clip + */ + public Rectangle getClipBounds() + { + return clip != null ? clip.getBounds() : null; + } + + /** + * Clips the current clip with the specified clip. + */ + public void clipRect(int x, int y, int width, int height) + { + if (clip == null) + { + clip = new Rectangle(x, y, width, height); + } + else + { + computeIntersection(x, y, width, height, clip); + } + // Update the X clip setting. + setXClip(clip.x, clip.y, clip.width, clip.height); + } + + /** + * Returns true when the specified rectangle intersects with + * the current clip, false otherwise. This is overridden to + * avoid unnecessary creation of Rectangles via getBounds(). + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * + * @return true when the specified rectangle intersects with + * the current clip, false otherwise + */ + public boolean hitClip(int x, int y, int w, int h) + { + boolean hit; + if (clip == null) + { + hit = true; + } + else + { + // It's easier to determine if the rectangle lies outside the clip, + // so we determine that and reverse the result (if it's not completely + // outside, it most likely hits the clip rectangle). + int x2 = x + w; + int y2 = y + h; + int clipX2 = clip.x + clip.width; + int clipY2 = clip.y + clip.height; + boolean outside = (x < clip.x && x2 < clip.x) // Left. + || (x > clipX2 && x2 > clipX2) // Right. + || (y < clip.y && y2 < clip.y) // Top. + || (y > clipY2 && y2 > clipY2); // Bottom. + hit = ! outside; + } + return hit; + } + + public void setClip(int x, int y, int width, int height) + { + if (clip != null) + clip.setBounds(x, y, width, height); + else + clip = new Rectangle(x, y, width, height); + setXClip(clip.x, clip.y, clip.width, clip.height); + } + + /** + * Sets the clip on the X server GC. The coordinates are not yet translated, + * this will be performed by the X server. + * + * @param x the clip, X coordinate + * @param y the clip, Y coordinate + * @param w the clip, width + * @param h the clip, height + */ + private void setXClip(int x, int y, int w, int h) + { + gnu.x11.Rectangle[] clipRects = new gnu.x11.Rectangle[] { + new gnu.x11.Rectangle(x, y, w, h) }; + xgc.set_clip_rectangles(translateX, translateY, clipRects, GC.YX_BANDED); + } + + public Shape getClip() + { + // Return a copy here, so nobody can trash our clip. + return clip == null ? null : clip.getBounds(); + } + + /** + * Sets the current clip. + * + * @param c the clip to set + */ + public void setClip(Shape c) + { + if (c != null) + { + Rectangle b; + if (c instanceof Rectangle) + { + b = (Rectangle) c; + } + else + { + b = c.getBounds(); + } + clip.setBounds(b); + setXClip(b.x, b.y, b.width, b.height); + } + else + { + clip.setBounds(0, 0, xdrawable.width, xdrawable.height); + setXClip(0, 0, xdrawable.width, xdrawable.height); + } + } + + public void copyArea(int x, int y, int width, int height, int dx, int dy) + { + // Clip and translate src rectangle. + int srcX = Math.min(Math.max(x, clip.x), clip.x + clip.width) + + translateX; + int srcY = Math.min(Math.max(y, clip.y), clip.y + clip.height) + + translateY; + int srcWidth = Math.min(Math.max(x + width, clip.x), + clip.x + clip.width) - x; + int srcHeight = Math.min(Math.max(y + height, clip.y), + clip.y + clip.height) - y; + xdrawable.copy_area(xdrawable, xgc, srcX, srcY, srcWidth, srcHeight, + srcX + dx, srcY + dy); + } + + /** + * Draws a line from point (x1, y1) to point (x2, y2). + */ + public void drawLine(int x1, int y1, int x2, int y2) + { + //System.err.println("drawLine: " + (x1 + translateX) + ", " + ( y1 + translateY) + ", " + (x2 + translateX) + ", " + (y2 + translateY) + " on: " + xdrawable); + xdrawable.line(xgc, x1 + translateX, y1 + translateY, + x2 + translateX, y2 + translateY); + } + + /** + * Fills the specified rectangle. + */ + public void fillRect(int x, int y, int width, int height) + { + xdrawable.rectangle(xgc, x + translateX, y + translateY, + width, height, true); + } + + public void clearRect(int x, int y, int width, int height) + { + xgc.set_foreground(Color.WHITE.getRGB()); + xdrawable.rectangle(xgc, x, y, width, height, true); + if (foreground != null) + xgc.set_foreground(foreground.getRGB()); + } + + public void drawRoundRect(int x, int y, int width, int height, int arcWidth, + int arcHeight) + { + // Draw 4 lines. + int arcRadiusX = arcWidth / 2; + int arcRadiusY = arcHeight / 2; + drawLine(x + arcRadiusX, y, x + width - arcRadiusX, y); + drawLine(x, y + arcRadiusY, x, y + height - arcRadiusY); + drawLine(x + arcRadiusX, y + height, x + width - arcRadiusX, y + height); + drawLine(x + width, y + arcRadiusY, x + width, y + height - arcRadiusY); + + // Draw the 4 arcs at the corners. + // Upper left. + drawArc(x, y, arcWidth, arcHeight, 90, 90); + // Lower left. + drawArc(x, y + height - arcHeight, arcWidth, arcHeight, 180, 90); + // Upper right. + drawArc(x + width - arcWidth, y, arcWidth, arcHeight, 0, 90); + // Lower right. + drawArc(x + width - arcWidth, y + height - arcHeight, arcWidth, arcHeight, + 270, 90); + } + + public void fillRoundRect(int x, int y, int width, int height, int arcWidth, + int arcHeight) + { + // Fill the 3 rectangles that make up the inner area. + int arcRadiusX = arcWidth / 2; + int arcRadiusY = arcHeight / 2; + // Left. + fillRect(x, y + arcRadiusY, arcRadiusX, height - arcHeight); + // Middle. + fillRect(x + arcRadiusX, y, width - arcWidth, height); + // Right. + fillRect(x + width - arcRadiusX, y + arcRadiusY, arcRadiusX, + height - arcHeight); + + // Fill the 4 arcs in the corners. + // Upper left. + fillArc(x, y, arcWidth, arcHeight, 90, 90); + // Lower left. + fillArc(x, y + height - arcHeight, arcWidth, arcHeight, 180, 90); + // Upper right. + fillArc(x + width - arcWidth, y, arcWidth, arcHeight, 0, 90); + // Lower right. + fillArc(x + width - arcWidth, y + height - arcHeight, arcWidth, arcHeight, + 270, 90); + } + + public void drawOval(int x, int y, int width, int height) + { + xdrawable.arc(xgc, x, y, width, height, 0, 360 * 64, false); + } + + public void fillOval(int x, int y, int width, int height) + { + xdrawable.arc(xgc, x, y, width, height, 0, 360 * 64, true); + } + + public void drawArc(int x, int y, int width, int height, int arcStart, + int arcAngle) + { + xdrawable.arc(xgc, x, y, width, height, arcStart * 64, arcAngle * 64, false); + } + + public void fillArc(int x, int y, int width, int height, int arcStart, + int arcAngle) + { + xdrawable.arc(xgc, x, y, width, height, arcStart * 64, arcAngle * 64, true); + } + + public void drawPolyline(int[] xPoints, int[] yPoints, int npoints) + { + int numPoints = Math.min(xPoints.length, yPoints.length); + Point[] points = new Point[numPoints]; + // FIXME: Improve Escher API to accept arrays to avoid creation + // of many Point objects. + for (int i = 0; i < numPoints; i++) + points[i] = new Point(xPoints[i], yPoints[i]); + xdrawable.poly_line(xgc, points, Drawable.ORIGIN); + } + + public void drawPolygon(int[] xPoints, int[] yPoints, int npoints) + { + int numPoints = Math.min(xPoints.length, yPoints.length); + Point[] points = new Point[numPoints]; + // FIXME: Improve Escher API to accept arrays to avoid creation + // of many Point objects. + for (int i = 0; i < numPoints; i++) + points[i] = new Point(xPoints[i], yPoints[i]); + xdrawable.poly_line(xgc, points, Drawable.ORIGIN); + } + + public void fillPolygon(int[] xPoints, int[] yPoints, int npoints) + { + int numPoints = Math.min(xPoints.length, yPoints.length); + Point[] points = new Point[numPoints]; + // FIXME: Improve Escher API to accept arrays to avoid creation + // of many Point objects. + for (int i = 0; i < numPoints; i++) + points[i] = new Point(xPoints[i], yPoints[i]); + xdrawable.fill_poly(xgc, points, Drawable.COMPLEX, Drawable.ORIGIN); + } + + /** + * Draws the specified string at (x, y). + */ + public void drawString(String string, int x, int y) + { + if (disposed) + throw new AWTError("XGraphics already disposed"); + + xdrawable.text(xgc, x + translateX, y + translateY, string); + } + + public void drawString(AttributedCharacterIterator ci, int x, int y) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + /** + * Draws the specified image on the drawable at position (x,y). + */ + public boolean drawImage(Image image, int x, int y, ImageObserver observer) + { + if (image instanceof XImage) + { + XImage xim = (XImage) image; + Pixmap pm = xim.pixmap; + xdrawable.copy_area(pm, xgc, 0, 0, pm.width, pm.height, + x + translateX, y + translateY); + } + else if (image instanceof BufferedImage + && ((BufferedImage) image).getTransparency() != Transparency.OPAQUE) + { + BufferedImage bi = (BufferedImage) image; + int width = bi.getWidth(); + int height = bi.getHeight(); + Data img = xdrawable.image(x + translateX, y + translateY, + width, height, 0xFFFFFFFF, 2); + + // Compute line byte count. + int lineBitCount = width * pixmapFormat.bits_per_pixel (); + int rem = lineBitCount % pixmapFormat.scanline_pad (); + int linePadCount = lineBitCount / pixmapFormat.scanline_pad () + + (rem == 0 ? 0 : 1); + int lineByteCount = linePadCount * pixmapFormat.scanline_pad () / 8; + + // Composite source and destination pixel data. + int[] trgb = new int[3]; // The device rgb pixels. + for (int yy = 0; yy < height; yy++) + { + for (int xx = 0; xx < width; xx++) + { + getRGB(xx, yy, img, trgb, lineByteCount); + int srgb = bi.getRGB(xx, yy); + float alpha = ((srgb >> 24) & 0xff) / 256F; + float tAlpha = 1.F - alpha; + int red = (srgb >> 16) & 0xFF; + int green = (srgb >> 8) & 0xFF; + int blue = (srgb) & 0xFF; + trgb[0] = (int) (trgb[0] * tAlpha + red * alpha); + trgb[1] = (int) (trgb[1] * tAlpha + green * alpha); + trgb[2] = (int) (trgb[2] * tAlpha + blue * alpha); + setRGB(xx, yy, img, trgb, lineByteCount); + } + } + + // Now we have the transparent image composited onto the target + // Image, now we only must copy it to the Drawable. + ZPixmap pm = new ZPixmap(xdrawable.display); + pm.width = width; + pm.height = height; + pm.init(); + System.arraycopy(img.data, 32, pm.data, 0, img.data.length - 32); + xdrawable.put_image(xgc, pm, x + translateX, y + translateY); + } + else + { + // Pre-render the image into an XImage. + ImageProducer source = image.getSource(); + ImageConverter conv = new ImageConverter(); + source.startProduction(conv); + XImage xim = conv.getXImage(); + Pixmap pm = xim.pixmap; + xdrawable.copy_area(pm, xgc, 0, 0, pm.width, pm.height, + x + translateX, y + translateY); + } + return true; + } + + /** + * Helper method to work around limitation in the current Escher impl. + * + * @param x the x position + * @param y the y position + * @param img the image data + * @param rgb an 3-size array that holds the rgb values on method exit + */ + private void getRGB(int x, int y, Data img, int[] rgb, int lineByteCount) + { + // TODO: Does this also work on non-RGB devices? + int i = y * lineByteCount + pixelByteCount * x; + if (imageByteOrder == gnu.x11.image.Image.LSB_FIRST) + {//if (i >= 5716-33) System.err.println("lbc: " + lineByteCount + ", " + pixelByteCount); + rgb[2] = img.data[32 + i]; + rgb[1] = img.data[32 + i + 1]; + rgb[0] = img.data[32 + i + 2]; + } + else + { // MSB_FIRST + rgb[0] = img.data[32 + i]; + rgb[1] = img.data[32 + i + 1]; + rgb[2] = img.data[32 + i + 2]; + } + + } + + /** + * Helper method to work around limitation in the current Escher impl. + * + * @param x the x position + * @param y the y position + * @param img the image data + * @param rgb an 3-size array that holds the rgb values on method exit + */ + private void setRGB(int x, int y, Data img, int[] rgb, int lineByteCount) + { + // TODO: Does this also work on non-RGB devices? + int i = y * lineByteCount + pixelByteCount * x; + if (imageByteOrder == gnu.x11.image.Image.LSB_FIRST) + { + img.data[32 + i] = (byte) rgb[2]; + img.data[32 + i + 1] = (byte) rgb[1]; + img.data[32 + i + 2] = (byte) rgb[0]; + } + else + { // MSB_FIRST + img.data[32 + i] = (byte) rgb[0]; + img.data[32 + i + 1] = (byte) rgb[1]; + img.data[32 + i + 2] = (byte) rgb[2]; + } + } + + public boolean drawImage(Image image, int x, int y, int width, int height, + ImageObserver observer) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public boolean drawImage(Image image, int x, int y, Color bgcolor, + ImageObserver observer) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public boolean drawImage(Image image, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + ImageObserver observer) + { + return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, + observer); + } + + public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, Color bgcolor, + ImageObserver observer) + { + + // FIXME: What to do with bgcolor? + + // Scale the image. + int sw = image.getWidth(observer); + int sh = image.getHeight(observer); + double scaleX = Math.abs(dx2 - dx1) / (double) Math.abs(sx2 - sx1); + double scaleY = Math.abs(dy2 - dy1) / (double) Math.abs(sy2 - sy1); + Image scaled = image.getScaledInstance((int) (scaleX * sw), + (int) (scaleY * sh), + Image.SCALE_FAST); + + // Scaled source coordinates. + int sx1s = (int) (scaleX * Math.min(sx1, sx2)); + int sx2s = (int) (scaleX * Math.max(sx1, sx2)); + + // Temporarily clip to the target rectangle. + Rectangle old = clip; + clipRect(dx1, dy1, dx2 - dx1, dy2 - dy1); + + // Draw scaled image. + boolean res = drawImage(scaled, dx1 - sx1s, dy1 - sx2s, observer); + + // Reset clip. + setClip(old); + + return res; + } + + /** + * Frees any resources associated with this object. + */ + public void dispose() + { + if (! disposed) + { + xgc.free(); + xdrawable.display.flush(); + disposed = true; + } + } + + // Additional helper methods. + + /** + * Creates and returns an exact copy of this XGraphics. + */ + protected Object clone() + { + try + { + XGraphics copy = (XGraphics) super.clone(); + copy.xgc = xgc.copy(); + if (clip != null) + { + copy.clip = new Rectangle(clip); + copy.setXClip(clip.x, clip.y, clip.width, clip.height); + } + return copy; + } + catch (CloneNotSupportedException ex) + { + assert false; + } + return null; + } + + /** + * Computes the intersection between two rectangles and stores the result + * int the second rectangle. + * + * This method has been copied from {@link javax.swing.SwingUtilities}. + * + * @param x the x coordinate of the rectangle #1 + * @param y the y coordinate of the rectangle #1 + * @param w the width of the rectangle #1 + * @param h the height of the rectangle #1 + * @param rect the rectangle #2 and output rectangle + */ + private static void computeIntersection(int x, int y, int w, int h, + Rectangle rect) + { + int x2 = (int) rect.x; + int y2 = (int) rect.y; + int w2 = (int) rect.width; + int h2 = (int) rect.height; + + int dx = (x > x2) ? x : x2; + int dy = (y > y2) ? y : y2; + int dw = (x + w < x2 + w2) ? (x + w - dx) : (x2 + w2 - dx); + int dh = (y + h < y2 + h2) ? (y + h - dy) : (y2 + h2 - dy); + + if (dw >= 0 && dh >= 0) + rect.setBounds(dx, dy, dw, dh); + else + rect.setBounds(0, 0, 0, 0); + } + + +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java new file mode 100644 index 0000000..5dc79ff --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java @@ -0,0 +1,295 @@ +/* XGraphics2D.java -- A Java based Graphics2D impl for X + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.x; + +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.Toolkit; +import java.awt.geom.AffineTransform; +import java.awt.image.ColorModel; +import java.awt.image.Raster; + +import gnu.java.awt.java2d.AbstractGraphics2D; +import gnu.x11.Drawable; +import gnu.x11.GC; +import gnu.x11.image.ZPixmap; + +public class XGraphics2D + extends AbstractGraphics2D +{ + + /** + * The X Drawable to draw on. + */ + private Drawable xdrawable; + + /** + * The X graphics context (GC). + */ + private GC xgc; + + /** + * Indicates if this graphics has already been disposed. + */ + private boolean disposed; + + XGraphics2D(Drawable d) + { + super(); + xdrawable = d; + xgc = new GC(d); + init(); + disposed = false; + //setClip(new Rectangle(0, 0, xdrawable.width, xdrawable.height)); + } + + /** + * Draws a pixel in the target coordinate space using the specified color. + * + * @param x the x coordinate + * @param y the y coordinate + */ + protected void rawSetPixel(int x, int y) + { + xdrawable.point(xgc, x, y); + } + +// protected void rawFillPolygon(double[] xpoints, double[] ypoints, int npoints) +// { +// Point[] points = new Point[npoints]; +// for (int n = 0; n < npoints; n++) +// { +// points[n] = new Point((int) xpoints[n], (int) ypoints[n]); +// } +// xdrawable.fill_poly(xgc, points, Drawable.COMPLEX, Drawable.ORIGIN); +// xdrawable.display.flush(); +// } + + protected void rawDrawLine(int x0, int y0, int x1, int y1) + { + xdrawable.line(xgc, x0, y0, x1, y1); + } + + protected void rawFillRect(int x, int y, int w, int h) + { + xdrawable.rectangle(xgc, x, y, w, h, true); + } + + protected void rawSetForeground(java.awt.Color c) + { + if (c != null) + xgc.set_foreground(c.getRGB()); + } + + protected void rawSetForeground(int r, int g, int b) + { + xgc.set_foreground( r << 16 | g << 8 | b ); + } + + /** + * Returns the color model of this Graphics object. + * + * @return the color model of this Graphics object + */ + protected ColorModel getColorModel() + { + return Toolkit.getDefaultToolkit().getColorModel(); + } + + /** + * Returns the color model of the target device. + * + * @return the color model of the target device + */ + protected ColorModel getDestinationColorModel() + { + return Toolkit.getDefaultToolkit().getColorModel(); + } + + /** + * Returns the bounds of the target. + * + * @return the bounds of the target + */ + protected Rectangle getDeviceBounds() + { + return new Rectangle(0, 0, xdrawable.width, xdrawable.height); + } + + public GraphicsConfiguration getDeviceConfiguration() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void dispose() + { + if (!disposed) + { + xgc.free(); + xdrawable.display.flush(); + disposed = true; + } + } + + public Graphics create() + { + // super.create() returns a copy created by clone(), so it should + // be a XGraphics2D. + XGraphics2D copy = (XGraphics2D) super.create(); + copy.xgc = xgc.copy(); + return copy; + } + +// /** +// * Draws the specified image on the drawable at position (x,y). +// */ +// +// public boolean drawImage(Image image, int x, int y, ImageObserver observer) +// { +// AffineTransform transform = getTransform(); +// int translateX = (int) transform.getTranslateX(); +// int translateY = (int) transform.getTranslateY(); +// if (image instanceof XImage) +// { +// XImage xim = (XImage) image; +// Pixmap pm = xim.pixmap; +// xdrawable.copy_area(pm, xgc, 0, 0, pm.width, pm.height, +// x + translateX, y + translateY); +// } +// else if (image instanceof BufferedImage) +// { +// BufferedImage bufferedImage = (BufferedImage) image; +// Raster raster = bufferedImage.getData(); +// int w = bufferedImage.getWidth(); +// int h = bufferedImage.getHeight(); +// // Push data to X server. +// ZPixmap zPixmap = new ZPixmap(xdrawable.display, w, h, +// xdrawable.display.default_pixmap_format); +// System.err.println("data buffer length: " + zPixmap.data.length); +// int[] pixel = new int[4]; +// for (int tx = 0; tx < w; tx++) +// { +// for (int ty = 0; ty < h; ty++) +// { +// pixel = raster.getPixel(tx, ty, pixel); +//// System.err.print("r: " + pixel[0]); +//// System.err.print(", g: " + pixel[1]); +//// System.err.println(", b: " + pixel[2]); +// zPixmap.set_red(tx, ty, pixel[0]); +// zPixmap.set_green(tx, ty, pixel[1]); +// zPixmap.set_blue(tx, ty, pixel[2]); +// } +// } +// xdrawable.put_image(xgc, zPixmap, x, y); +// } +// else +// { +// throw new UnsupportedOperationException("Not yet implemented."); +// } +// return true; +// } +// + public void setClip(Shape c) + { + super.setClip(c); + if (c instanceof Rectangle) + { + Rectangle r = (Rectangle) c; + AffineTransform t = getTransform(); + int translateX = (int) t.getTranslateX(); + //System.err.println("translateX: " + translateX); + int translateY = (int) t.getTranslateY(); + //System.err.println("translateY: " + translateY); + //System.err.println("clip: " + c); + gnu.x11.Rectangle clip = new gnu.x11.Rectangle(r.x, r.y, r.width, + r.height); + xgc.set_clip_rectangles(translateX, translateY, + new gnu.x11.Rectangle[]{clip}, GC.UN_SORTED); + } + } + + /** + * Notifies the backend that the raster has changed in the specified + * rectangular area. The raster that is provided in this method is always + * the same as the one returned in {@link #getDestinationRaster}. + * Backends that reflect changes to this raster directly don't need to do + * anything here. + * + * @param raster the updated raster, identical to the raster returned + * by {@link #getDestinationRaster()} + * @param x the upper left corner of the updated region, X coordinate + * @param y the upper lef corner of the updated region, Y coordinate + * @param w the width of the updated region + * @param h the height of the updated region + */ + protected void updateRaster(Raster raster, int x, int y, int w, int h) + { + if (w > 0 && h > 0) + { + ZPixmap zPixmap = new ZPixmap(xdrawable.display, w, h, + xdrawable.display.default_pixmap_format); + int[] pixel = null; + int x1 = x + w; + int y1 = y + h; + for (int tx = x; tx < x1; tx++) + { + for (int ty = y; ty < y1; ty++) + { + pixel = raster.getPixel(tx, ty, pixel); + //System.err.println("tx: " + tx + ", ty: " + ty + ", pixel: " + pixel[0] + ", " + pixel[1] + ", " + pixel[2]); +// System.err.print("r: " + pixel[0]); +// System.err.print(", g: " + pixel[1]); +// System.err.println(", b: " + pixel[2]); + zPixmap.set_red(tx - x, ty - y, pixel[0]); + zPixmap.set_green(tx - x, ty - y, pixel[1]); + zPixmap.set_blue(tx - x, ty - y, pixel[2]); + } + } + xdrawable.put_image(xgc, zPixmap, x, y); + } + } + + + protected void init() + { + super.init(); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java new file mode 100644 index 0000000..d6e66cb --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java @@ -0,0 +1,118 @@ +/* XGraphicsConfiguration.java -- GraphicsConfiguration for X + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.x; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.VolatileImage; + +public class XGraphicsConfiguration + extends GraphicsConfiguration +{ + + XGraphicsDevice device; + + XGraphicsConfiguration(XGraphicsDevice dev) + { + device = dev; + } + + public GraphicsDevice getDevice() + { + return device; + } + + public BufferedImage createCompatibleImage(int w, int h) + { + return new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + } + + public VolatileImage createCompatibleVolatileImage(int w, int h) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public VolatileImage createCompatibleVolatileImage(int width, int height, + int transparency) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public BufferedImage createCompatibleImage(int w, int h, int transparency) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public ColorModel getColorModel() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public ColorModel getColorModel(int transparency) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public AffineTransform getDefaultTransform() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public AffineTransform getNormalizingTransform() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public Rectangle getBounds() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphicsDevice.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsDevice.java new file mode 100644 index 0000000..6a020ec --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsDevice.java @@ -0,0 +1,166 @@ +/* XGraphicsDevice.java -- GraphicsDevice for X + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.awt.peer.x; + +import gnu.classpath.SystemProperties; +import gnu.java.net.local.LocalSocket; +import gnu.java.net.local.LocalSocketAddress; +import gnu.x11.Connection; +import gnu.x11.Display; + +import java.awt.AWTError; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.net.SocketException; + +/** + * This class represents an X Display. The actual connection is established + * lazily when it is first needed. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class XGraphicsDevice + extends GraphicsDevice +{ + + private XGraphicsConfiguration defaultConfiguration; + + /** + * The X display associated with the XGraphicsDevice. This is established + * when {@link #getDisplay} is first called. + */ + private Display display; + + /** + * The display name from which the display will be initialized. + */ + private Display.Name displayName; + + /** + * The event pump for this X Display. + */ + private XEventPump eventPump; + + /** + * Creates a new XGraphicsDevice. + */ + XGraphicsDevice(Display.Name dn) + { + displayName = dn; + } + + public int getType() + { + return TYPE_RASTER_SCREEN; + } + + public String getIDstring() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public GraphicsConfiguration[] getConfigurations() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public GraphicsConfiguration getDefaultConfiguration() + { + if (defaultConfiguration == null) + defaultConfiguration = new XGraphicsConfiguration(this); + return defaultConfiguration; + } + + /** + * Returns the X Display associated with this XGraphicsDevice. + * This establishes the connection to the X server on the first invocation. + * + * @return the X Display associated with this XGraphicsDevice + */ + Display getDisplay() + { + if (display == null) + { + if (displayName.hostname.equals("")) + displayName.hostname = "localhost"; + if (XToolkit.DEBUG) + System.err.println("connecting to : " + displayName); + // Try to connect via unix domain sockets when host == localhost. + if ((displayName.hostname.equals("localhost") + || displayName.hostname.equals("")) + && SystemProperties.getProperty("gnu.xawt.no_local_sockets") == null) + { + // TODO: Is this 100% ok? + String sockPath = "/tmp/.X11-unix/X" + displayName.display_no; + LocalSocketAddress addr = new LocalSocketAddress(sockPath); + try + { + if (XToolkit.DEBUG) + System.err.println("connecting to local socket: " + + sockPath); + LocalSocket socket = new LocalSocket(addr); + display = new Display(socket, "localhost", + displayName.display_no, + displayName.screen_no); + display.connection.send_mode = Connection.ASYNCHRONOUS; + if (XToolkit.DEBUG) + System.err.println("connected to local socket"); + } + catch (SocketException ex) + { + AWTError err = new AWTError("could not connect to X server"); + err.initCause(ex); + throw err; + } + } + else + { + display = new Display(displayName); + } + eventPump = new XEventPump(display); + } + return display; + } + + XEventPump getEventPump() + { + return eventPump; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsEnvironment.java new file mode 100644 index 0000000..65383a6 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsEnvironment.java @@ -0,0 +1,202 @@ +/* XGraphicsEnvironment.java -- Represents the X environment + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.x; + +import gnu.java.awt.java2d.RasterGraphics; +import gnu.x11.Display; + +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Locale; +import java.util.Properties; + +/** + * Represents the X environment for AWT. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class XGraphicsEnvironment + extends GraphicsEnvironment +{ + + /** + * The default graphics device. This is normally the local main X + * Display, but can be configured to be any X connection. + */ + private XGraphicsDevice defaultDevice; + + /** + * All configured devices. + */ + private XGraphicsDevice[] devices; + + /** + * Creates a new XGraphicsEnvironment. This loads the configuration if + * there is one present and initializes the XGraphicsDevices in the + * environment. If there is no configuration, then there is one + * default device initialized with the local main X device. + */ + public XGraphicsEnvironment() + { + // Initiliaze the devices. + Properties props = new Properties(); + File config = new File(System.getProperty("user.home"), + ".xawt.properties"); + + try + { + FileInputStream configIn = new FileInputStream(config); + props.load(configIn); + int dev = 1; + ArrayList deviceList = new ArrayList(); + while (true) + { + String propName = "display." + dev; + String propValue = props.getProperty(propName); + if (propValue != null) + { + Display.Name displayName = new Display.Name(propValue); + XGraphicsDevice device = new XGraphicsDevice(displayName); + if (dev == 1) + defaultDevice = device; + deviceList.add(device); + dev++; + } + else + { + if (dev == 1) + { + defaultDevice = initDefaultDevice(); + deviceList.add(defaultDevice); + } + break; + } + } + devices = (XGraphicsDevice[]) deviceList.toArray + (new XGraphicsDevice[deviceList.size()]); + } + catch (FileNotFoundException ex) + { + defaultDevice = initDefaultDevice(); + devices = new XGraphicsDevice[]{ defaultDevice }; + } + catch (IOException ex) + { + defaultDevice = initDefaultDevice(); + devices = new XGraphicsDevice[]{ defaultDevice }; + } + + } + + /** + * Helper method that initializes the default device in the case when there + * is no configuration for the default. + */ + private XGraphicsDevice initDefaultDevice() + { + String display = System.getenv("DISPLAY"); + if (display == null) + display = ":0.0"; + Display.Name displayName = new Display.Name(display); + return new XGraphicsDevice(displayName); + } + + /** + * Returns all configured screen devices. + * + * @return all configured screen devices + */ + public GraphicsDevice[] getScreenDevices() + { + // We return a copy so that nobody can fiddle with our devices. + XGraphicsDevice[] copy = new XGraphicsDevice[devices.length]; + System.arraycopy(devices, 0, copy, 0, devices.length); + return copy; + } + + /** + * Returns the default screen device. + * + * @return the default screen device + */ + public GraphicsDevice getDefaultScreenDevice() + { + return defaultDevice; + } + + /** + * Returns a Graphics instance suitable for drawing on top of the + * BufferedImage. + * + * @param image the buffered image to create a graphics for + * + * @return a Graphics2D instance for drawing on the BufferedImage + */ + public Graphics2D createGraphics(BufferedImage image) + { + return new RasterGraphics(image.getRaster(), image.getColorModel()); + } + + public Font[] getAllFonts() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public String[] getAvailableFontFamilyNames() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public String[] getAvailableFontFamilyNames(Locale l) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XImage.java b/libjava/classpath/gnu/java/awt/peer/x/XImage.java new file mode 100644 index 0000000..b9e9936 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XImage.java @@ -0,0 +1,111 @@ +/* XImage.java -- Image impl for X Pixmaps + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.x; + +import gnu.x11.Pixmap; + +import java.awt.Graphics; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.util.Hashtable; + +public class XImage + extends Image +{ + + Pixmap pixmap; + + private Hashtable properties; + + XImage(int w, int h) + { + GraphicsEnvironment env = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + XGraphicsDevice dev = (XGraphicsDevice) env.getDefaultScreenDevice(); + pixmap = new Pixmap(dev.getDisplay(), w, h); + } + + public int getWidth(ImageObserver observer) + { + return pixmap.width; + } + + public int getHeight(ImageObserver observer) + { + return pixmap.height; + } + + public ImageProducer getSource() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + /** + * Creates an XGraphics for drawing on this XImage. + * + * @return an XGraphics for drawing on this XImage + */ + public Graphics getGraphics() + { + XGraphics g = new XGraphics(pixmap); + return g; + } + + public Object getProperty(String name, ImageObserver observer) + { + Object val = null; + if (properties != null) + val = properties.get(val); + return val; + } + + public void flush() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected void finalize() + { + pixmap.free(); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XLightweightPeer.java b/libjava/classpath/gnu/java/awt/peer/x/XLightweightPeer.java new file mode 100644 index 0000000..2613d84 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XLightweightPeer.java @@ -0,0 +1,56 @@ +/* XLightweightPeer.java -- A lightweight peer for X + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.x; + +import java.awt.Component; +import java.awt.peer.LightweightPeer; + +import gnu.java.awt.peer.swing.SwingContainerPeer; + +public class XLightweightPeer + extends SwingContainerPeer + implements LightweightPeer +{ + + XLightweightPeer(Component c) + { + super(c); + init(c, null); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XToolkit.java b/libjava/classpath/gnu/java/awt/peer/x/XToolkit.java new file mode 100644 index 0000000..a286fd6 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XToolkit.java @@ -0,0 +1,608 @@ +/* XToolkit.java -- The central AWT Toolkit for the X peers + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.x; + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Checkbox; +import java.awt.CheckboxMenuItem; +import java.awt.Choice; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FileDialog; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Label; +import java.awt.List; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.awt.PrintJob; +import java.awt.ScrollPane; +import java.awt.Scrollbar; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.Transparency; +import java.awt.Window; +import java.awt.datatransfer.Clipboard; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.peer.DragSourceContextPeer; +import java.awt.im.InputMethodHighlight; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.peer.ButtonPeer; +import java.awt.peer.CanvasPeer; +import java.awt.peer.CheckboxMenuItemPeer; +import java.awt.peer.CheckboxPeer; +import java.awt.peer.ChoicePeer; +import java.awt.peer.DialogPeer; +import java.awt.peer.FileDialogPeer; +import java.awt.peer.FontPeer; +import java.awt.peer.FramePeer; +import java.awt.peer.LabelPeer; +import java.awt.peer.LightweightPeer; +import java.awt.peer.ListPeer; +import java.awt.peer.MenuBarPeer; +import java.awt.peer.MenuItemPeer; +import java.awt.peer.MenuPeer; +import java.awt.peer.PanelPeer; +import java.awt.peer.PopupMenuPeer; +import java.awt.peer.RobotPeer; +import java.awt.peer.ScrollPanePeer; +import java.awt.peer.ScrollbarPeer; +import java.awt.peer.TextAreaPeer; +import java.awt.peer.TextFieldPeer; +import java.awt.peer.WindowPeer; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.WeakHashMap; + +import javax.imageio.ImageIO; + +import gnu.classpath.SystemProperties; +import gnu.java.awt.ClasspathToolkit; +import gnu.java.awt.EmbeddedWindow; +import gnu.java.awt.peer.ClasspathFontPeer; +import gnu.java.awt.peer.EmbeddedWindowPeer; +import gnu.java.awt.peer.swing.SwingCanvasPeer; +import gnu.java.awt.peer.swing.SwingLabelPeer; +import gnu.java.awt.peer.swing.SwingPanelPeer; + +public class XToolkit + extends ClasspathToolkit +{ + + /** + * Set to true to enable debug output. + */ + static boolean DEBUG = false; + + /** + * Maps AWT colors to X colors. + */ + HashMap colorMap = new HashMap(); + + /** + * The system event queue. + */ + private EventQueue eventQueue; + + /** + * The default color model of this toolkit. + */ + private ColorModel colorModel; + + /** + * Maps image URLs to Image instances. + */ + private HashMap imageCache = new HashMap(); + + /** + * The cached fonts. + */ + private WeakHashMap fontCache = new WeakHashMap(); + + public XToolkit() + { + SystemProperties.setProperty("gnu.javax.swing.noGraphics2D", "true"); + SystemProperties.setProperty("java.awt.graphicsenv", + "gnu.java.awt.peer.x.XGraphicsEnvironment"); + } + + public GraphicsEnvironment getLocalGraphicsEnvironment() + { + return new XGraphicsEnvironment(); + } + + /** + * Returns the font peer for a font with the specified name and attributes. + * + * @param name the font name + * @param attrs the font attributes + * + * @return the font peer for a font with the specified name and attributes + */ + public ClasspathFontPeer getClasspathFontPeer(String name, Map attrs) + { + String canonical = XFontPeer.encodeFont(name, attrs); + ClasspathFontPeer font; + if (!fontCache.containsKey(canonical)) + { + String graphics2d = + SystemProperties.getProperty("gnu.xawt.graphics2d"); + if (graphics2d != null && graphics2d.equals("gl")) + font = new XFontPeer2(name, attrs); + else + font = new XFontPeer(name, attrs); + fontCache.put(canonical, font); + } + else + { + font = (ClasspathFontPeer) fontCache.get(canonical); + } + return font; + } + + public Font createFont(int format, InputStream stream) + { + return null; + } + + public RobotPeer createRobot(GraphicsDevice screen) throws AWTException + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public EmbeddedWindowPeer createEmbeddedWindow(EmbeddedWindow w) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected ButtonPeer createButton(Button target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected TextFieldPeer createTextField(TextField target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected LabelPeer createLabel(Label target) + { + return new SwingLabelPeer(target); + } + + protected ListPeer createList(List target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected CheckboxPeer createCheckbox(Checkbox target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected ScrollbarPeer createScrollbar(Scrollbar target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected ScrollPanePeer createScrollPane(ScrollPane target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected TextAreaPeer createTextArea(TextArea target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected ChoicePeer createChoice(Choice target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected FramePeer createFrame(Frame target) + { + XFramePeer frame = new XFramePeer(target); + return frame; + } + + protected CanvasPeer createCanvas(Canvas target) + { + return new SwingCanvasPeer(target); + } + + protected PanelPeer createPanel(Panel target) + { + return new SwingPanelPeer(target); + } + + protected WindowPeer createWindow(Window target) + { + return new XWindowPeer(target); + } + + protected DialogPeer createDialog(Dialog target) + { + return new XDialogPeer(target); + } + + protected MenuBarPeer createMenuBar(MenuBar target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected MenuPeer createMenu(Menu target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected PopupMenuPeer createPopupMenu(PopupMenu target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected MenuItemPeer createMenuItem(MenuItem target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected FileDialogPeer createFileDialog(FileDialog target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected FontPeer getFontPeer(String name, int style) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public Dimension getScreenSize() + { + // FIXME: This is only a hack to get some apps working. + return new Dimension(1024, 768); + } + + public int getScreenResolution() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + /** + * Returns the color model used by this toolkit. + * + * @return the color model used by this toolkit + */ + public ColorModel getColorModel() + { + // TODO: I assume 24 bit depth here, we can do this better. + if (colorModel == null) + colorModel = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF); + return colorModel; + } + + public String[] getFontList() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public FontMetrics getFontMetrics(Font name) + { + ClasspathFontPeer peer = (ClasspathFontPeer) name.getPeer(); + return peer.getFontMetrics(name); + } + + public void sync() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + /** + * Returns an image that has its pixel data loaded from a file with the + * specified name. If that file doesn't exist, an empty or error image + * is returned instead. + * + * @param name the filename of the file that contains the pixel data + * + * @return the image + */ + public Image getImage(String name) + { + Image image; + try + { + File file = new File(name); + image = getImage(file.toURL()); + } + catch (MalformedURLException ex) + { + // TODO: Replace by a more meaningful error image instead. + image = null; + } + return image; + } + + /** + * Returns an image that has its pixel data loaded from the specified URL. + * If the image cannot be loaded for some reason, an empty or error image + * is returned instead. + * + * @param url the URL to the image data + * + * @return the image + */ + public Image getImage(URL url) + { + Image image; + if (imageCache.containsKey(url)) + { + image = (Image) imageCache.get(url); + } + else + { + image = createImage(url); + imageCache.put(url, image); + } + return image; + } + + /** + * Returns an image that has its pixel data loaded from a file with the + * specified name. If that file doesn't exist, an empty or error image + * is returned instead. + * + * @param filename the filename of the file that contains the pixel data + * + * @return the image + */ + public Image createImage(String filename) + { + Image im; + try + { + File file = new File(filename); + URL url = file.toURL(); + im = createImage(url); + } + catch (MalformedURLException ex) + { + im = createErrorImage(); + } + return im; + } + + /** + * Returns an image that has its pixel data loaded from the specified URL. + * If the image cannot be loaded for some reason, an empty or error image + * is returned instead. + * + * @param url the URL to the image data + * + * @return the image + */ + public Image createImage(URL url) + { + Image image; + try + { + image = createImage(url.openStream()); + } + catch (IOException ex) + { + image = createErrorImage(); + } + return image; + } + + /** + * Creates an image that is returned when calls to createImage() yields an + * error. + * + * @return an image that is returned when calls to createImage() yields an + * error + */ + private Image createErrorImage() + { + // TODO: Create better error image. + return new XImage(1, 1); + } + + public boolean prepareImage(Image image, int width, int height, ImageObserver observer) + { + // Images are loaded synchronously, so we don't bother and return true. + return true; + } + + public int checkImage(Image image, int width, int height, ImageObserver observer) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public Image createImage(ImageProducer producer) + { + ImageConverter conv = new ImageConverter(); + producer.startProduction(conv); + Image image = conv.getXImage(); + return image; + } + + public Image createImage(byte[] data, int offset, int len) + { + Image image; + try + { + ByteArrayInputStream i = new ByteArrayInputStream(data, offset, len); + image = createImage(i); + } + catch (IOException ex) + { + image = createErrorImage(); + } + return image; + } + + private Image createImage(InputStream i) + throws IOException + { + Image image; + BufferedImage buffered = ImageIO.read(i); + // If the bufferedimage is opaque, then we can copy it over to an + // X Pixmap for faster drawing. + if (buffered != null && buffered.getTransparency() == Transparency.OPAQUE) + { + ImageProducer source = buffered.getSource(); + image = createImage(source); + } + else if (buffered != null) + { + image = buffered; + } + else + { + image = createErrorImage(); + } + return image; + } + + public PrintJob getPrintJob(Frame frame, String title, Properties props) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void beep() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public Clipboard getSystemClipboard() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + /** + * Returns the eventqueue used by the XLib peers. + * + * @return the eventqueue used by the XLib peers + */ + protected EventQueue getSystemEventQueueImpl() + { + if (eventQueue == null) + eventQueue = new EventQueue(); + return eventQueue; + } + + public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public Map mapInputMethodHighlight(InputMethodHighlight highlight) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + /** + * Helper method to quickly fetch the default device (X Display). + * + * @return the default XGraphicsDevice + */ + static XGraphicsDevice getDefaultDevice() + { + XGraphicsEnvironment env = (XGraphicsEnvironment) + XGraphicsEnvironment.getLocalGraphicsEnvironment(); + return (XGraphicsDevice) env.getDefaultScreenDevice(); + } + + protected LightweightPeer createComponent(Component c) + { + return new XLightweightPeer(c); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java new file mode 100644 index 0000000..28cc5a5 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java @@ -0,0 +1,255 @@ +/* XWindowPeer.java -- Window peer for X + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.x; + +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.PaintEvent; +import java.awt.event.WindowEvent; + +import gnu.x11.Window; +import gnu.x11.event.Event; + +import gnu.java.awt.peer.swing.SwingWindowPeer; + +public class XWindowPeer + extends SwingWindowPeer +{ + + private static int standardSelect = Event.BUTTON_PRESS_MASK + | Event.BUTTON_RELEASE_MASK + | Event.POINTER_MOTION_MASK + //| Event.RESIZE_REDIRECT_MASK + | Event.EXPOSURE_MASK + //| Event.PROPERTY_CHANGE_MASK + | Event.STRUCTURE_NOTIFY_MASK + | Event.KEY_PRESS_MASK + | Event.KEY_RELEASE_MASK + ; + + /** + * Indicates if we are in callback mode, that is when a property (like size) + * is changed in reponse to a request from the X server and doesn't need + * to be propagated back to the X server. + */ + boolean callback = false; + + /** + * The X window. + */ + private Window xwindow; + + XWindowPeer(java.awt.Window window) + { + super(window); + XGraphicsDevice dev = XToolkit.getDefaultDevice(); + + // TODO: Maybe initialize lazily in show(). + // FIXME: Howto generate a Window without decorations? + int x = Math.max(window.getX(), 0); + int y = Math.max(window.getY(), 0); + int w = Math.max(window.getWidth(), 1); + int h = Math.max(window.getHeight(), 1); + xwindow = new Window(dev.getDisplay().default_root, x, y, w, h); + xwindow.create(); + xwindow.select_input(standardSelect); + dev.getEventPump().registerWindow(xwindow, window); + } + + public void toBack() + { + // TODO Auto-generated method stub + + } + + public void toFront() + { + // TODO Auto-generated method stub + + } + + public void updateAlwaysOnTop() + { + // TODO Auto-generated method stub + + } + + public boolean requestWindowFocus() + { + // TODO Auto-generated method stub + return false; + } + + public Point getLocationOnScreen() + { + return new Point(xwindow.x, xwindow.y); + } + + /** + * Returns a XGraphics suitable for drawing on this frame. + * + * @return a XGraphics suitable for drawing on this frame + */ + public Graphics getGraphics() + { + return new XGraphics(xwindow); + } + + public Image createImage(int w, int h) + { + return new XImage(w, h); + } + + /** + * Makes the component visible. This is called by {@link Component#show()}. + * + * This is implemented to call setVisible(true) on the Swing component. + */ + public void show() + { +// // Prevent ResizeRedirect events. +// //xwindow.select_input(noResizeRedirectSelect); +// Window.Attributes atts = new Window.Attributes(); +// atts.set_override_redirect(true); +// xwindow.change_attributes(atts); + + // Prevent ResizeRedirect events. + //xwindow.select_input(Event.NO_EVENT_MASK); + //xwindow.select_input(noResizeRedirectSelect); + + xwindow.map(); + EventQueue eq = XToolkit.getDefaultToolkit().getSystemEventQueue(); + java.awt.Window w = (java.awt.Window) super.awtComponent; + eq.postEvent(new WindowEvent(w, WindowEvent.WINDOW_OPENED)); + eq.postEvent(new PaintEvent(w, PaintEvent.PAINT, + new Rectangle(0, 0, w.getWidth(), + w.getHeight()))); + +// // Reset input selection. +// atts.set_override_redirect(false); +// xwindow.change_attributes(atts); + } + + /** + * Makes the component invisible. This is called from + * {@link Component#hide()}. + * + * This is implemented to call setVisible(false) on the Swing component. + */ + public void hide() + { + xwindow.unmap(); + } + + /** + * Notifies the peer that the bounds of this component have changed. This + * is called by {@link Component#reshape(int, int, int, int)}. + * + * This is implemented to call setBounds() on the Swing component. + * + * @param x the X coordinate of the upper left corner of the component + * @param y the Y coordinate of the upper left corner of the component + * @param width the width of the component + * @param height the height of the component + */ + public void reshape(int x, int y, int width, int height) + { + // Prevent ResizeRedirect events. +// //xwindow.select_input(noResizeRedirectSelect); +// Window.Attributes atts = new Window.Attributes(); +// atts.set_override_redirect(true); +// xwindow.change_attributes(atts); + + // Need to substract insets because AWT size is including insets, + // and X size is excuding insets. + Insets i = insets(); + xwindow.move_resize(x - i.left, y - i.right, width - i.left - i.right, + height - i.top - i.bottom); + + // Reset input selection. +// atts = new Window.Attributes(); +// atts.set_override_redirect(false); +// xwindow.change_attributes(atts); + } + + public Insets insets() + { + Insets i = new Insets(0, 0, 0, 0); +// Window.GeometryReply g = xwindow.geometry(); +// int b = g.border_width(); +// Insets i = new Insets(b, b, b, b); +// Window.WMSizeHints wmSize = xwindow.wm_normal_hints(); +// if (wmSize != null) +// { +// i.left = wmSize.x() - g.x(); +// i.right = wmSize.width() - g.width() - i.left ; +// i.top = wmSize.y() - g.y(); +// i.bottom = wmSize.height() - g.height() - i.top; +// } +// System.err.println("insets: " + i); + return i; + } + + /** + * Returns the font metrics for the specified font. + * + * @return the font metrics for the specified font + */ + public FontMetrics getFontMetrics(Font font) + { + XFontPeer fontPeer = (XFontPeer) font.getPeer(); + return fontPeer.getFontMetrics(font); + } + + /** + * Unregisters the window in the event pump when it is closed. + */ + protected void finalize() + { + XGraphicsDevice dev = XToolkit.getDefaultDevice(); + dev.getEventPump().unregisterWindow(xwindow); + } +} diff --git a/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java b/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java index 2303f44..e4cc819 100644 --- a/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java @@ -668,7 +668,7 @@ class PostScriptGraphics2D extends Graphics2D saveAndInvertAxis(); // draw the shape s with an inverted Y axis. - PathIterator pi = s.getPathIterator(new AffineTransform()); + PathIterator pi = s.getPathIterator(null); float[] coords = new float[6]; while (! pi.isDone()) @@ -872,7 +872,7 @@ class PostScriptGraphics2D extends Graphics2D /** write a shape to the file */ private void writeShape(Shape s) { - PathIterator pi = s.getPathIterator(new AffineTransform()); + PathIterator pi = s.getPathIterator(null); float[] coords = new float[6]; while (! pi.isDone()) -- cgit v1.1