diff options
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | configure.ac | 30 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/GLGraphics.java | 123 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/ImageConverter.java | 113 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/KeyboardMapping.java | 415 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XEventPump.java | 287 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XFontPeer.java | 740 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XFontPeer2.java | 335 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XFramePeer.java | 321 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XGraphics.java | 855 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XGraphics2D.java | 295 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XGraphicsConfiguration.java | 118 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XGraphicsDevice.java | 166 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XGraphicsEnvironment.java | 202 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XImage.java | 107 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XLightweightPeer.java | 56 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XToolkit.java | 582 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/XWindowPeer.java | 256 | ||||
-rw-r--r-- | gnu/java/awt/peer/x/fonts.properties | 25 | ||||
-rw-r--r-- | lib/standard.omit.in (renamed from lib/standard.omit) | 0 |
20 files changed, 5051 insertions, 0 deletions
@@ -1,3 +1,28 @@ +2006-06-29 Roman Kennke <kennke@aicas.com> + + * gnu/java/awt/peer/x/GLGraphics.java, + * gnu/java/awt/peer/x/ImageConverter.java, + * gnu/java/awt/peer/x/KeyboardMapping.java, + * gnu/java/awt/peer/x/XEventPump.java, + * gnu/java/awt/peer/x/XFontPeer.java, + * gnu/java/awt/peer/x/XFontPeer2.java, + * gnu/java/awt/peer/x/XFramePeer.java, + * gnu/java/awt/peer/x/XGraphics.java, + * gnu/java/awt/peer/x/XGraphics2D.java, + * gnu/java/awt/peer/x/XGraphicsConfiguration.java, + * gnu/java/awt/peer/x/XGraphicsDevice.java, + * gnu/java/awt/peer/x/XGraphicsEnvironment.java, + * gnu/java/awt/peer/x/XImage.java, + * gnu/java/awt/peer/x/XLightweightPeer.java, + * gnu/java/awt/peer/x/XToolkit.java, + * gnu/java/awt/peer/x/XWindowPeer.java, + * gnu/java/awt/peer/x/fonts.properties: New files. + * lib/standard.omit: Removed. + * lib/standard.omit.in: Added. + * configure.ac: Added configure option --with-escher. Added some + configury for omitting gnu.java.awt.peer.x package when + this option is not specified. + 2006-06-29 David Gilbert <david.gilbert@object-refinery.com> * javax/swing/JComponent.java diff --git a/configure.ac b/configure.ac index 92375b607..e3569dcc0 100644 --- a/configure.ac +++ b/configure.ac @@ -697,6 +697,30 @@ esac; AM_CONDITIONAL(USE_PREBUILT_GLIBJ_ZIP, test x$use_glibj_zip = xtrue) AC_SUBST(PATH_TO_GLIBJ_ZIP) +dnl ----------------------------------------------------------- +dnl Build with Escher based X peers. +dnl ----------------------------------------------------------- +AC_ARG_WITH([escher], + AS_HELP_STRING([--with-escher=ABS.PATH], + [specify path to escher dir or JAR for X peers])) +case "$with_escher" in +"") + use_escher=false + ;; +"no") + use_escher=false + ;; +"yes") + AC_MSG_ERROR([Please suply an absolute path to Escher library]) + ;; +*) + use_escher=true + PATH_TO_ESCHER=$with_escher + ;; +esac; + +AM_CONDITIONAL(USE_ESCHER, test x$use_escher = xtrue) +AC_SUBST(PATH_TO_ESCHER) dnl ----------------------------------------------------------- dnl Check if local socket support should be included. @@ -784,3 +808,9 @@ fi AC_CONFIG_COMMANDS([gen-classlist],[chmod 755 lib/gen-classlist.sh]) AC_CONFIG_COMMANDS([copy-vmresources],[chmod 755 lib/copy-vmresources.sh]) AC_OUTPUT + +# Create standard.omit based on decisions we just made. +cp lib/standard.omit.in lib/standard.omit +if test x$use_escher != xtrue; then + echo gnu/java/awt/peer/x >> lib/standard.omit +fi diff --git a/gnu/java/awt/peer/x/GLGraphics.java b/gnu/java/awt/peer/x/GLGraphics.java new file mode 100644 index 000000000..c80c85c28 --- /dev/null +++ b/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/gnu/java/awt/peer/x/ImageConverter.java b/gnu/java/awt/peer/x/ImageConverter.java new file mode 100644 index 000000000..6d32448ee --- /dev/null +++ b/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/gnu/java/awt/peer/x/KeyboardMapping.java b/gnu/java/awt/peer/x/KeyboardMapping.java new file mode 100644 index 000000000..8e0a31f5d --- /dev/null +++ b/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/gnu/java/awt/peer/x/XEventPump.java b/gnu/java/awt/peer/x/XEventPump.java new file mode 100644 index 000000000..bd1ef08ce --- /dev/null +++ b/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()); + ((XFramePeer) awtWindow.getPeer()).callback = true; + awtWindow.setSize(c.width(), c.height()); + ((XFramePeer) 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/gnu/java/awt/peer/x/XFontPeer.java b/gnu/java/awt/peer/x/XFontPeer.java new file mode 100644 index 000000000..8a499db1a --- /dev/null +++ b/gnu/java/awt/peer/x/XFontPeer.java @@ -0,0 +1,740 @@ +/* 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 <code>c</code>. + * + * @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()); + return protoType.replaceFirst("%d", String.valueOf(size)); + } + + /** + * 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; + } + + /** + * 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/gnu/java/awt/peer/x/XFontPeer2.java b/gnu/java/awt/peer/x/XFontPeer2.java new file mode 100644 index 000000000..25371de1a --- /dev/null +++ b/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/gnu/java/awt/peer/x/XFramePeer.java b/gnu/java/awt/peer/x/XFramePeer.java new file mode 100644 index 000000000..1d34b1a81 --- /dev/null +++ b/gnu/java/awt/peer/x/XFramePeer.java @@ -0,0 +1,321 @@ +/* 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.Point; +import java.awt.Rectangle; +import java.awt.event.PaintEvent; +import java.awt.event.WindowEvent; + +import gnu.java.awt.peer.swing.SwingFramePeer; +import gnu.x11.Window; +import gnu.x11.event.Event; + +public class XFramePeer + extends SwingFramePeer +{ + + 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 + ; + + /** + * The X window. + */ + private Window xwindow; + + /** + * 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; + + public XFramePeer(Frame frame) + { + super(frame); + XGraphicsDevice dev = XToolkit.getDefaultDevice(); + + // TODO: Maybe initialize lazily in show(). + int x = Math.max(frame.getX(), 0); + int y = Math.max(frame.getY(), 0); + int w = Math.max(frame.getWidth(), 1); + int h = Math.max(frame.getHeight(), 1); + xwindow = new Window(dev.getDisplay().default_root, x, y, w, h); + xwindow.create(); + xwindow.select_input(standardSelect); + dev.getEventPump().registerWindow(xwindow, frame); + } + + public void setIconImage(Image image) + { + // 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) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void setMaximizedBounds(Rectangle r) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void setBoundsPrivate(int x, int y, int width, int height) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void toBack() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void toFront() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void updateAlwaysOnTop() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public boolean requestWindowFocus() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + 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); + } + + /** + * Sets the visibility state of the component. This is called by + * {@link Component#setVisible(boolean)}. + * + * This is implemented to call setVisible() on the Swing component. + * + * @param visible <code>true</code> to make the component visible, + * <code>false</code> to make it invisible + */ + public void setVisible(boolean visible) + { + if (visible) + show(); + else + hide(); + } + + /** + * 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) + { +// if (callback) +// return; + + // 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); + } + + public Rectangle getBounds() + { + return new Rectangle(xwindow.x, xwindow.y, xwindow.width, xwindow.height); + } +} diff --git a/gnu/java/awt/peer/x/XGraphics.java b/gnu/java/awt/peer/x/XGraphics.java new file mode 100644 index 000000000..81168797c --- /dev/null +++ b/gnu/java/awt/peer/x/XGraphics.java @@ -0,0 +1,855 @@ +/* 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.Drawable; +import gnu.x11.GC; +import gnu.x11.Pixmap; +import gnu.x11.Point; + +import java.awt.AWTError; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.RenderingHints.Key; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.image.RenderedImage; +import java.awt.image.renderable.RenderableImage; +import java.text.AttributedCharacterIterator; +import java.util.Map; + +public class XGraphics + extends Graphics2D + 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; + + /** + * 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); + } + + /** + * 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; + setClip(clip); + } + } + + /** + * Returns the current foreground color, possibly <code>null</code>. + * + * @return the current foreground color, possibly <code>null</code> + */ + public Color getColor() + { + return foreground; + } + + /** + * Sets the current foreground color. A <code>null</code> value doesn't + * change the current setting. + * + * @param c the foreground color to set + */ + public void setColor(Color c) + { + if (c != null) + { + xgc.set_foreground(c.getRGB()); + 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 <code>null</code>. + * + * @return the current font, possibly <code>null</code> + */ + public Font getFont() + { + return font; + } + + /** + * Sets the font on the graphics context. A <code>null</code> 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. + setClip(clip.x, clip.y, clip.width, clip.height); + } + + /** + * Returns <code>true</code> when the specified rectangle intersects with + * the current clip, <code>false</code> 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 <code>true</code> when the specified rectangle intersects with + * the current clip, <code>false</code> otherwise + */ + public boolean hitClip(int x, int y, int w, int h) + { + boolean hit; + if (clip == null) + { + hit = true; + } + else + { + hit = clip.intersects(x, y, w, h); + } + //System.err.println("hitClip: " + hit); + 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); + + gnu.x11.Rectangle[] clipRects = new gnu.x11.Rectangle[] { + new gnu.x11.Rectangle(x, y, width, height) }; + xgc.set_clip_rectangles(translateX, translateY, clipRects, GC.UN_SORTED); + } + + public Shape getClip() + { + // Return a copy here, so nobody can trash our clip. + return clip == null ? null : clip.getBounds(); + } + + /** + * Sets the current clip. + * + * @param clip the clip to set + */ + public void setClip(Shape clip) + { + if (clip != null) + { + Rectangle b; + if (clip instanceof Rectangle) + { + b = (Rectangle) clip; + } + else + { + b = clip.getBounds(); + } + setClip(b.x, b.y, b.width, b.height); + } + else + { + setClip(0, 0, xdrawable.width, xdrawable.height); + } + } + + public void copyArea(int x, int y, int width, int height, int dx, int dy) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + /** + * 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 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 + { + // 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; + } + + 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) + { + // 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, Color bgcolor, + ImageObserver observer) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + /** + * Frees any resources associated with this object. + */ + public void dispose() + { + xdrawable.display.flush(); + if (! disposed) + { + xgc.free(); + disposed = true; + } + } + + // Additional Graphics2D methods. + + public void draw(Shape shape) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public boolean drawImage(Image image, AffineTransform xform, ImageObserver obs) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void drawImage(BufferedImage image, BufferedImageOp op, int x, int y) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void drawRenderedImage(RenderedImage image, AffineTransform xform) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void drawRenderableImage(RenderableImage image, AffineTransform xform) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void drawString(String text, float x, float y) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void drawString(AttributedCharacterIterator iterator, float x, float y) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void fill(Shape shape) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public boolean hit(Rectangle rect, Shape text, boolean onStroke) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public GraphicsConfiguration getDeviceConfiguration() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void setComposite(Composite comp) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void setPaint(Paint paint) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void setStroke(Stroke stroke) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void setRenderingHint(Key hintKey, Object hintValue) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public Object getRenderingHint(Key hintKey) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void setRenderingHints(Map hints) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void addRenderingHints(Map hints) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public RenderingHints getRenderingHints() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void translate(double tx, double ty) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void rotate(double theta) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void rotate(double theta, double x, double y) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void scale(double scaleX, double scaleY) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void shear(double shearX, double shearY) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void transform(AffineTransform Tx) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void setTransform(AffineTransform Tx) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public AffineTransform getTransform() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public Paint getPaint() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public Composite getComposite() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void setBackground(Color color) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public Color getBackground() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public Stroke getStroke() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void clip(Shape s) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public FontRenderContext getFontRenderContext() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public void drawGlyphVector(GlyphVector g, float x, float y) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + + // 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(); + + // Save the original clip. + if (clip != null) + copy.clip = new Rectangle(clip); + return copy; + } + catch (CloneNotSupportedException ex) + { + AWTError err = new AWTError("Error while cloning XGraphics"); + err.initCause(ex); + throw err; + } + } + + /** + * 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/gnu/java/awt/peer/x/XGraphics2D.java b/gnu/java/awt/peer/x/XGraphics2D.java new file mode 100644 index 000000000..5dc79ff5c --- /dev/null +++ b/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/gnu/java/awt/peer/x/XGraphicsConfiguration.java b/gnu/java/awt/peer/x/XGraphicsConfiguration.java new file mode 100644 index 000000000..d6e66cbd2 --- /dev/null +++ b/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/gnu/java/awt/peer/x/XGraphicsDevice.java b/gnu/java/awt/peer/x/XGraphicsDevice.java new file mode 100644 index 000000000..6a020ec4e --- /dev/null +++ b/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/gnu/java/awt/peer/x/XGraphicsEnvironment.java b/gnu/java/awt/peer/x/XGraphicsEnvironment.java new file mode 100644 index 000000000..707b44c38 --- /dev/null +++ b/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. + */ + 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/gnu/java/awt/peer/x/XImage.java b/gnu/java/awt/peer/x/XImage.java new file mode 100644 index 000000000..28bc6b90a --- /dev/null +++ b/gnu/java/awt/peer/x/XImage.java @@ -0,0 +1,107 @@ +/* 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.Toolkit; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; + +public class XImage + extends Image +{ + + Pixmap pixmap; + + XImage(int w, int h) + { + XToolkit tk = (XToolkit) Toolkit.getDefaultToolkit(); + GraphicsEnvironment env = tk.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) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public void flush() + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + protected void finalize() + { + pixmap.free(); + } +} diff --git a/gnu/java/awt/peer/x/XLightweightPeer.java b/gnu/java/awt/peer/x/XLightweightPeer.java new file mode 100644 index 000000000..2613d84d8 --- /dev/null +++ b/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/gnu/java/awt/peer/x/XToolkit.java b/gnu/java/awt/peer/x/XToolkit.java new file mode 100644 index 000000000..5fc6c188e --- /dev/null +++ b/gnu/java/awt/peer/x/XToolkit.java @@ -0,0 +1,582 @@ +/* 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.Window; +import java.awt.datatransfer.Clipboard; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.peer.DragSourceContextPeer; +import java.awt.font.FontRenderContext; +import java.awt.im.InputMethodHighlight; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.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.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.text.AttributedString; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.WeakHashMap; + +import javax.imageio.ImageIO; + +import gnu.java.awt.ClasspathToolkit; +import gnu.java.awt.EmbeddedWindow; +import gnu.java.awt.peer.ClasspathFontPeer; +import gnu.java.awt.peer.ClasspathTextLayoutPeer; +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; + + private XGraphicsEnvironment env; + + /** + * 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() + { + System.setProperty("gnu.javax.swing.noGraphics2D", "true"); + } + + public GraphicsEnvironment getLocalGraphicsEnvironment() + { + if (env == null) + env = new XGraphicsEnvironment(); + return env; + } + + /** + * 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); + XFontPeer font; + if (!fontCache.containsKey(canonical)) + { + font = new XFontPeer(name, attrs); + fontCache.put(canonical, font); + } + else + { + font = (XFontPeer) fontCache.get(canonical); + } + return font; + } + + public ClasspathTextLayoutPeer getClasspathTextLayoutPeer(AttributedString str, FontRenderContext frc) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + 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) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + 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) + { + XFontPeer peer = (XFontPeer) 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 + { + BufferedImage buffered = ImageIO.read(url); + if (buffered != null) + { + ImageConverter conv = new ImageConverter(); + ImageProducer source = buffered.getSource(); + source.startProduction(conv); + return conv.getXImage(); + } + else return createErrorImage(); + + } + 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) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + public Image createImage(byte[] data, int offset, int len) + { + // TODO: Implement this. + throw new UnsupportedOperationException("Not yet implemented."); + } + + 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/gnu/java/awt/peer/x/XWindowPeer.java b/gnu/java/awt/peer/x/XWindowPeer.java new file mode 100644 index 000000000..f4815ce7f --- /dev/null +++ b/gnu/java/awt/peer/x/XWindowPeer.java @@ -0,0 +1,256 @@ +/* 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); + System.err.println("new XWindowPeer"); + 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/gnu/java/awt/peer/x/fonts.properties b/gnu/java/awt/peer/x/fonts.properties new file mode 100644 index 000000000..2c8755ceb --- /dev/null +++ b/gnu/java/awt/peer/x/fonts.properties @@ -0,0 +1,25 @@ + +serif.plain=-adobe-times-medium-r-normal--%d-*-*-*-p-*-iso8859-1 +serif.bold=-adobe-times-bold-r-normal--%d-*-*-*-p-*-iso8859-1 +serif.italic=-adobe-times-medium-o-normal--%d-*-*-*-p-*-iso8859-1 +serif.bolditalic=-adobe-times-bold-o-normal--%d-*-*-*-p-*-iso8859-1 + +sansserif.plain=-adobe-helvetica-medium-r-normal--%d-*-*-*-p-*-iso8859-1 +sansserif.bold=-adobe-helvetica-bold-r-normal--%d-*-*-*-p-*-iso8859-1 +sansserif.italic=-adobe-helvetica-medium-o-normal--%d-*-*-*-p-*-iso8859-1 +sansserif.bolditalic=-adobe-helvetica-bold-o-normal--%d-*-*-*-p-*-iso8859-1 + +monospaced.plain=-adobe-courier-medium-r-normal--%d-*-*-*-p-*-iso8859-1 +monospaced.bold=-adobe-courier-bold-r-normal--%d-*-*-*-p-*-iso8859-1 +monospaced.italic=-adobe-courier-medium-o-normal--%d-*-*-*-p-*-iso8859-1 +monospaced.bolditalic=-adobe-courier-bold-o-normal--%d-*-*-*-p-*-iso8859-1 + +dialog.plain=-adobe-helvetica-medium-r-normal--%d-*-*-*-p-*-iso8859-1 +dialog.bold=-adobe-helvetica-bold-r-normal--%d-*-*-*-p-*-iso8859-1 +dialog.italic=-adobe-helvetica-medium-o-normal--%d-*-*-*-p-*-iso8859-1 +dialog.bolditalic=-adobe-helvetica-bold-o-normal--%d-*-*-*-p-*-iso8859-1 + +dialoginput.plain=-adobe-helvetica-medium-r-normal--%d-*-*-*-p-*-iso8859-1 +dialoginput.bold=-adobe-helvetica-bold-r-normal--%d-*-*-*-p-*-iso8859-1 +dialoginput.italic=-adobe-helvetica-medium-o-normal--%d-*-*-*-p-*-iso8859-1 +dialoginput.bolditalic=-adobe-helvetica-bold-o-normal--%d-*-*-*-p-*-iso8859-1 diff --git a/lib/standard.omit b/lib/standard.omit.in index a518f7df8..a518f7df8 100644 --- a/lib/standard.omit +++ b/lib/standard.omit.in |