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 );