This adds a bunch of 1.6 methods and constants to our AWT, and fixes some issues in the peers. Together with these patches and a bunch of modifications on OpenJDK, I was able to use the GTK peers in OpenJDK to get Swing running:
http://kennke.org/blog/2007/06/25/openjdk-swing-on-gtk-peers/ 2007-06-25 Roman Kennke <[EMAIL PROTECTED]> * gnu/java/awt/peer/ClasspathFontPeer.java (canDisplay): Take character as integer codepoint. * gnu/java/awt/peer/gtk/GdkFontPeer.java (canDisplay): Take character as integer codepoint. * gnu/java/awt/peer/gtk/GtkComponentPeer.java (postMouseEvent): Use MouseEvent constructor with absolute coordinates to avoid deadlock (over getLocationOnScreen()). * gnu/java/awt/peer/gtk/VolatileImageGraphics.java (getDeviceConfiguration): Fall back to the default configuration if the component is not set. * gnu/java/awt/peer/qt/QtFontMetrics.java (canDisplay): Take character as integer codepoint. * gnu/java/awt/peer/qt/QtFontPeer.java (canDisplay): Take character as integer codepoint. * gnu/java/awt/peer/x/XFontPeer2.java (canDisplay): Take character as integer codepoint. * include/gnu_java_awt_peer_qt_QtFontMetrics.h (canDisplay): Take character as integer codepoint. * java/awt/Font.java (DIALOG): New constant. (DIALOG_INPUT): New constant. (MONOSPACED): New constant. (SANS_SERIF): New constant. (SERIF): New constant. (Font(Font)): New constructor. (canDisplay(char)): Use new canDisplay(int) method. (canDisplay(int)): New method. (hasLayoutAttributes): New method. * java/awt/event/MouseEvent.java (absX,absY): New fields. (MouseEvent): New constructor with absolute coordinates. (getLocationOnScreen): New method. (getXOnScreen): New method. (getYOnScreen): New method. * native/jni/qt-peer/qtfontmetrics.cpp (canDisplay): Take character as integer codepoint. /Roman -- Dipl.-Inform. (FH) Roman Kennke, Software Engineer, http://kennke.org aicas Allerton Interworks Computer Automated Systems GmbH Haid-und-Neu-Straße 18 * D-76131 Karlsruhe * Germany http://www.aicas.com * Tel: +49-721-663 968-0 USt-Id: DE216375633, Handelsregister HRB 109481, AG Karlsruhe Geschäftsführer: Dr. James J. Hunt
Index: include/gnu_java_awt_peer_qt_QtFontMetrics.h =================================================================== RCS file: /cvsroot/classpath/classpath/include/gnu_java_awt_peer_qt_QtFontMetrics.h,v retrieving revision 1.9 diff -u -1 -0 -r1.9 gnu_java_awt_peer_qt_QtFontMetrics.h --- include/gnu_java_awt_peer_qt_QtFontMetrics.h 30 Apr 2006 10:37:36 -0000 1.9 +++ include/gnu_java_awt_peer_qt_QtFontMetrics.h 25 Jun 2007 11:25:17 -0000 @@ -7,21 +7,21 @@ #ifdef __cplusplus extern "C" { #endif JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_init (JNIEnv *env, jobject, jobject); JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_initGraphics (JNIEnv *env, jobject, jobject, jobject); JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_dispose (JNIEnv *env, jobject); JNIEXPORT jobject JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_getStringBounds (JNIEnv *env, jobject, jstring); -JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_canDisplay (JNIEnv *env, jobject, jchar); +JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_canDisplay (JNIEnv *env, jobject, jint); JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_getAscent (JNIEnv *env, jobject); JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_getDescent (JNIEnv *env, jobject); JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_getHeight (JNIEnv *env, jobject); JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_getLeading (JNIEnv *env, jobject); JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_getMaxAdvance (JNIEnv *env, jobject); JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_charWidth (JNIEnv *env, jobject, jchar); JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_stringWidth (JNIEnv *env, jobject, jstring); #ifdef __cplusplus } Index: gnu/java/awt/peer/ClasspathFontPeer.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/ClasspathFontPeer.java,v retrieving revision 1.11 diff -u -1 -0 -r1.11 ClasspathFontPeer.java --- gnu/java/awt/peer/ClasspathFontPeer.java 12 Apr 2007 14:02:16 -0000 1.11 +++ gnu/java/awt/peer/ClasspathFontPeer.java 25 Jun 2007 11:25:18 -0000 @@ -637,21 +637,21 @@ /* Remaining methods are abstract */ /** * Implementation of [EMAIL PROTECTED] Font#canDisplay(char)} * * @param font the font this peer is being called from. This may be * useful if you are sharing peers between Font objects. Otherwise it may * be ignored. */ - public abstract boolean canDisplay (Font font, char c); + public abstract boolean canDisplay (Font font, int c); /** * Implementation of [EMAIL PROTECTED] Font#canDisplay(String)}, * [EMAIL PROTECTED] Font#canDisplay(char [], int, int)}, and * [EMAIL PROTECTED] Font#canDisplay(CharacterIterator, int, int)}. * * @param font the font this peer is being called from. This may be * useful if you are sharing peers between Font objects. Otherwise it may * be ignored. */ Index: gnu/java/awt/peer/gtk/GdkFontPeer.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java,v retrieving revision 1.24 diff -u -1 -0 -r1.24 GdkFontPeer.java --- gnu/java/awt/peer/gtk/GdkFontPeer.java 25 Apr 2007 14:53:03 -0000 1.24 +++ gnu/java/awt/peer/gtk/GdkFontPeer.java 25 Jun 2007 11:25:18 -0000 @@ -354,21 +354,21 @@ (byte) 'm', (byte) 'e'); if( data == null ) return null; nameTable = ByteBuffer.wrap( data ); } return NameDecoder.getName(nameTable, name, locale); } - public boolean canDisplay (Font font, char c) + public boolean canDisplay (Font font, int c) { // FIXME: inquire with pango return true; } public int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit) { // FIXME: inquire with pango return -1; } Index: gnu/java/awt/peer/gtk/GtkComponentPeer.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java,v retrieving revision 1.127 diff -u -1 -0 -r1.127 GtkComponentPeer.java --- gnu/java/awt/peer/gtk/GtkComponentPeer.java 22 Jun 2007 14:27:57 -0000 1.127 +++ gnu/java/awt/peer/gtk/GtkComponentPeer.java 25 Jun 2007 11:25:18 -0000 @@ -609,25 +609,32 @@ public void hide () { setVisible (false); } public void show () { setVisible (true); } - protected void postMouseEvent(int id, long when, int mods, int x, int y, + protected void postMouseEvent(int id, long when, int mods, int x, int y, int clickCount, boolean popupTrigger) { - q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y, - clickCount, popupTrigger)); + // It is important to do the getLocationOnScreen() here, instead + // of using the old MouseEvent constructors, because + // Component.getLocationOnScreen() locks on the AWT lock, which can + // trigger a deadlock. You don't want this. + Point locOnScreen = getLocationOnScreen(); + q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y, + locOnScreen.x + x, locOnScreen.y + y, + clickCount, popupTrigger, + MouseEvent.NOBUTTON)); } /** * Callback for component_scroll_cb. */ protected void postMouseWheelEvent(int id, long when, int mods, int x, int y, int clickCount, boolean popupTrigger, int type, int amount, int rotation) { Index: gnu/java/awt/peer/gtk/VolatileImageGraphics.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java,v retrieving revision 1.12 diff -u -1 -0 -r1.12 VolatileImageGraphics.java --- gnu/java/awt/peer/gtk/VolatileImageGraphics.java 12 Feb 2007 21:39:20 -0000 1.12 +++ gnu/java/awt/peer/gtk/VolatileImageGraphics.java 25 Jun 2007 11:25:18 -0000 @@ -79,21 +79,31 @@ copy( copy, cairo_t ); } public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy) { owner.copyArea(x, y, width, height, dx, dy); } public GraphicsConfiguration getDeviceConfiguration() { - return owner.component.getGraphicsConfiguration(); + GraphicsConfiguration conf; + if (owner.component != null) + { + conf = owner.component.getGraphicsConfiguration(); + } + else + { + return java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getDefaultConfiguration(); + } + return conf; } public Graphics create() { return new VolatileImageGraphics( this ); } public void draw(Shape s) { if (comp == null || comp instanceof AlphaComposite) Index: gnu/java/awt/peer/qt/QtFontMetrics.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/qt/QtFontMetrics.java,v retrieving revision 1.2 diff -u -1 -0 -r1.2 QtFontMetrics.java --- gnu/java/awt/peer/qt/QtFontMetrics.java 26 Jul 2006 20:08:07 -0000 1.2 +++ gnu/java/awt/peer/qt/QtFontMetrics.java 25 Jun 2007 11:25:18 -0000 @@ -87,21 +87,21 @@ private native void init(QtFontPeer fp); private native void initGraphics(QtFontPeer fp, QtGraphics g); private native void dispose(); native Rectangle2D getStringBounds(String s); // ****************** Package private *************************** - native boolean canDisplay( char c ); + native boolean canDisplay( int c ); // ****************** Public methods **************************** public native int getAscent(); public native int getDescent(); public native int getHeight(); public native int getLeading(); Index: gnu/java/awt/peer/qt/QtFontPeer.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/qt/QtFontPeer.java,v retrieving revision 1.5 diff -u -1 -0 -r1.5 QtFontPeer.java --- gnu/java/awt/peer/qt/QtFontPeer.java 2 Nov 2006 11:02:29 -0000 1.5 +++ gnu/java/awt/peer/qt/QtFontPeer.java 25 Jun 2007 11:25:18 -0000 @@ -91,21 +91,21 @@ private native void create(String name, int style, int size); /** * Destroys the QFont. */ public native void dispose(); // ****************** ClasspathFontPeer Methods. - public boolean canDisplay (Font font, char c) + public boolean canDisplay (Font font, int c) { return metrics.canDisplay( c ); } public int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit) { int index = start; char c = i.setIndex( index ); while( index <= limit ) Index: gnu/java/awt/peer/x/XFontPeer2.java =================================================================== RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/x/XFontPeer2.java,v retrieving revision 1.5 diff -u -1 -0 -r1.5 XFontPeer2.java --- gnu/java/awt/peer/x/XFontPeer2.java 22 May 2007 13:12:56 -0000 1.5 +++ gnu/java/awt/peer/x/XFontPeer2.java 25 Jun 2007 11:25:18 -0000 @@ -263,21 +263,21 @@ 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) + public boolean canDisplay(Font font, int 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"); } Index: java/awt/Font.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/awt/Font.java,v retrieving revision 1.39 diff -u -1 -0 -r1.39 Font.java --- java/awt/Font.java 10 Dec 2006 20:25:43 -0000 1.39 +++ java/awt/Font.java 25 Jun 2007 11:25:18 -0000 @@ -163,20 +163,45 @@ * <code>limit</code> position. If this flag is set, * <code>layoutGlyphVector</code> does not examine the text after * <code>limit</code>, even if this would be necessary to select the * correct glyphs (e.g., for Arabic text). * * @since 1.4 */ public static final int LAYOUT_NO_LIMIT_CONTEXT = 4; /** + * @since 1.6 + */ + public static final String DIALOG = "Dialog"; + + /** + * @since 1.6 + */ + public static final String DIALOG_INPUT = "DialogInput"; + + /** + * @since 1.6 + */ + public static final String MONOSPACED = "Monospaced"; + + /** + * @since 1.6 + */ + public static final String SANS_SERIF = "SansSerif"; + + /** + * @since 1.6 + */ + public static final String SERIF = "Serif"; + + /** * The logical name of this font. * * @since 1.0 */ protected String name; /** * The size of this font in points, rounded. * * @since 1.0 @@ -323,20 +348,25 @@ * @param propname The name of the system property. * * @return The requested font, or <code>null</code> if the property * not exist or is malformed. */ public static Font getFont(String propname) { return getFont(propname, (Font) null); } + protected Font(Font font) + { + this(font.getName(), font.getAttributes()); + } + /** * Initializes a new instance of <code>Font</code> with the specified * attributes. * * @param name The name of the font. * @param style The font style. * @param size The font point size. */ public Font(String name, int style, int size) { @@ -484,21 +514,26 @@ * Checks if specified character maps to a glyph in this font. * * @param c The character to check. * * @return Whether the character has a corresponding glyph in this font. * * @since 1.2 */ public boolean canDisplay(char c) { - return peer.canDisplay(this, c); + return canDisplay((int) c); + } + + public boolean canDisplay(int codePoint) + { + return peer.canDisplay(this, codePoint); } /** * Checks how much of a given string can be mapped to glyphs in * this font. * * @param s The string to check. * * @return The index of the first character in <code>s</code> which cannot * be converted to a glyph by this font, or <code>-1</code> if all @@ -1366,20 +1401,26 @@ * be used for drawing, and any rendering hints should be set * to the desired values before obtaining <code>frc</code>. * * @see java.awt.Graphics2D#getFontRenderContext() */ public LineMetrics getLineMetrics(String str, FontRenderContext frc) { return getLineMetrics(str, 0, str.length() - 1, frc); } + public boolean hasLayoutAttributes() + { + // TODO: Implement properly. + return false; + } + /** * Reads the normal fields from the stream and then constructs the * peer from the style and size through getPeerFromToolkit(). */ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); HashMap attrs = new HashMap(); Index: java/awt/event/MouseEvent.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/awt/event/MouseEvent.java,v retrieving revision 1.13 diff -u -1 -0 -r1.13 MouseEvent.java --- java/awt/event/MouseEvent.java 13 Apr 2006 12:38:26 -0000 1.13 +++ java/awt/event/MouseEvent.java 25 Jun 2007 11:25:18 -0000 @@ -157,20 +157,30 @@ /** * The Y coordinate of the mouse cursor at the time of the event. * * @see #getY() * @serial the y coordinate */ private int y; /** + * The screen position of that mouse event, X coordinate. + */ + private int absX; + + /** + * The screen position of that mouse event, Y coordinate. + */ + private int absY; + + /** * The number of clicks that took place. For MOUSE_CLICKED, MOUSE_PRESSED, * and MOUSE_RELEASED, this will be at least 1; otherwise it is 0. * * see #getClickCount() * @serial the number of clicks */ private final int clickCount; /** * Indicates which mouse button changed state. Can only be one of @@ -205,20 +215,21 @@ * @param popupTrigger true if this event triggers a popup menu * @param button the most recent mouse button to change state * @throws IllegalArgumentException if source is null or button is invalid * @since 1.4 */ public MouseEvent(Component source, int id, long when, int modifiers, int x, int y, int clickCount, boolean popupTrigger, int button) { super(source, id, when, modifiers); + this.x = x; this.y = y; this.clickCount = clickCount; this.popupTrigger = popupTrigger; this.button = button; if (button < NOBUTTON || button > BUTTON3) throw new IllegalArgumentException(); if ((modifiers & EventModifier.OLD_MASK) != 0) { if ((modifiers & BUTTON1_MASK) != 0) @@ -227,20 +238,27 @@ this.button = BUTTON2; else if ((modifiers & BUTTON3_MASK) != 0) this.button = BUTTON3; } // clear the mouse button modifier masks if this is a button // release event. if (id == MOUSE_RELEASED) this.modifiersEx &= ~(BUTTON1_DOWN_MASK | BUTTON2_DOWN_MASK | BUTTON3_DOWN_MASK); + + if (source != null) + { + Point screenLoc = source.getLocationOnScreen(); + absX = screenLoc.x + x; + absY = screenLoc.y + y; + } } /** * Initializes a new instance of <code>MouseEvent</code> with the specified * information. Note that an invalid id leads to unspecified results. * * @param source the source of the event * @param id the event id * @param when the timestamp of when the event occurred * @param modifiers the modifier keys during the event, in old or new style @@ -251,20 +269,73 @@ * @throws IllegalArgumentException if source is null */ public MouseEvent(Component source, int id, long when, int modifiers, int x, int y, int clickCount, boolean popupTrigger) { this(source, id, when, modifiers, x, y, clickCount, popupTrigger, NOBUTTON); } /** + * Creates a new MouseEvent. This is like the other constructors and adds + * specific absolute coordinates. + * + * @param source the source of the event + * @param id the event id + * @param when the timestamp of when the event occurred + * @param modifiers the modifier keys during the event, in old or new style + * @param x the X coordinate of the mouse point + * @param y the Y coordinate of the mouse point + * @param absX the absolute X screen coordinate of this event + * @param absY the absolute Y screen coordinate of this event + * @param clickCount the number of mouse clicks for this event + * @param popupTrigger true if this event triggers a popup menu + * @param button the most recent mouse button to change state + * + * @throws IllegalArgumentException if source is null or button is invalid + * + * @since 1.6 + */ + public MouseEvent(Component source, int id, long when, int modifiers, + int x, int y, int absX, int absY, int clickCount, + boolean popupTrigger, int button) + { + super(source, id, when, modifiers); + + this.x = x; + this.y = y; + this.clickCount = clickCount; + this.popupTrigger = popupTrigger; + this.button = button; + if (button < NOBUTTON || button > BUTTON3) + throw new IllegalArgumentException(); + if ((modifiers & EventModifier.OLD_MASK) != 0) + { + if ((modifiers & BUTTON1_MASK) != 0) + this.button = BUTTON1; + else if ((modifiers & BUTTON2_MASK) != 0) + this.button = BUTTON2; + else if ((modifiers & BUTTON3_MASK) != 0) + this.button = BUTTON3; + } + // clear the mouse button modifier masks if this is a button + // release event. + if (id == MOUSE_RELEASED) + this.modifiersEx &= ~(BUTTON1_DOWN_MASK + | BUTTON2_DOWN_MASK + | BUTTON3_DOWN_MASK); + + this.absX = absX; + this.absY = absY; + } + + /** * This method returns the X coordinate of the mouse position. This is * relative to the source component. * * @return the x coordinate */ public int getX() { return x; } @@ -273,20 +344,44 @@ * relative to the source component. * * @return the y coordinate */ public int getY() { return y; } /** + * @since 1.6 + */ + public Point getLocationOnScreen() + { + return new Point(absX, absY); + } + + /** + * @since 1.6 + */ + public int getXOnScreen() + { + return absX; + } + + /** + * @since 1.6 + */ + public int getYOnScreen() + { + return absY; + } + + /** * This method returns a <code>Point</code> for the x,y position of * the mouse pointer. This is relative to the source component. * * @return a <code>Point</code> for the event position */ public Point getPoint() { return new Point(x, y); } Index: native/jni/qt-peer/qtfontmetrics.cpp =================================================================== RCS file: /cvsroot/classpath/classpath/native/jni/qt-peer/qtfontmetrics.cpp,v retrieving revision 1.2 diff -u -1 -0 -r1.2 qtfontmetrics.cpp --- native/jni/qt-peer/qtfontmetrics.cpp 15 Aug 2005 21:53:12 -0000 1.2 +++ native/jni/qt-peer/qtfontmetrics.cpp 25 Jun 2007 11:25:18 -0000 @@ -120,25 +120,25 @@ QFontMetrics *fm = getFontMetrics( env, obj ); if ( fm ) delete fm; setNativePtr( env, obj, NULL ); } /* * Returns JNI_TRUE if a character is displayable. */ JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_canDisplay -(JNIEnv *env, jobject obj, jchar c) +(JNIEnv *env, jobject obj, jint c) { QFontMetrics *fm = getFontMetrics( env, obj ); assert( fm ); - bool result = fm->inFont( QChar( (unsigned short)c ) ); + bool result = fm->inFont( QChar( (unsigned int) c ) ); return (result ? JNI_TRUE : JNI_FALSE); } /* * Returns the ascent. */ JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_qt_QtFontMetrics_getAscent (JNIEnv *env, jobject obj) { QFontMetrics *fm = getFontMetrics( env, obj );