diff options
Diffstat (limited to 'libjava/classpath/gnu/java/awt/peer')
24 files changed, 662 insertions, 653 deletions
diff --git a/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java b/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java index daaa143d03b..88733b92f8c 100644 --- a/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/GLightweightPeer.java @@ -1,5 +1,5 @@ /* GLightweightPeer.java -- - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -54,11 +54,14 @@ import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.awt.event.PaintEvent; import java.awt.image.ColorModel; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.awt.image.VolatileImage; +import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; import java.awt.peer.LightweightPeer; @@ -79,7 +82,7 @@ import java.awt.peer.LightweightPeer; * Lightweight components are painted directly onto their parent * containers through an Image object provided by the toolkit. */ -public class GLightweightPeer +public class GLightweightPeer implements LightweightPeer, ContainerPeer { private Component comp; @@ -247,7 +250,25 @@ public class GLightweightPeer public void setBounds(int x, int y, int width, int height) {} - public void setCursor(Cursor cursor) {} + /** + * Sets the cursor on the heavy-weight parent peer. + * Called by the MouseListener on mouse enter. + */ + public void setCursor(Cursor cursor) + { + Component p = comp.getParent(); + while (p != null && p.isLightweight()) + p = p.getParent(); + + if (p != null) + { + // Don't actually change the cursor of the component + // otherwise other childs inherit this cursor. + ComponentPeer peer = p.getPeer(); + if (peer != null) + peer.setCursor(cursor); + } + } public void setEnabled(boolean enabled) {} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java index c79f403edfd..b2ffed10ea6 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java @@ -110,14 +110,10 @@ public class GdkFontMetrics extends FontMetrics return stringWidth (new String (data, off, len)); } - /* - Sun's Motif implementation always returns 0 or 1 here (???), but - going by the X11 man pages, it seems as though we should return - font.ascent + font.descent. - */ public int getLeading () { - return 1; + // Sun always returns 0. + return 0; } public int getAscent () diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java index c6d42b37276..82744480dcf 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java @@ -1,5 +1,5 @@ /* GdkFontPeer.java -- Implements FontPeer with GTK+ - Copyright (C) 1999, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1999, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,6 +43,7 @@ import gnu.java.awt.peer.ClasspathFontPeer; import java.awt.Font; import java.awt.FontMetrics; +import java.awt.Toolkit; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.font.LineMetrics; @@ -157,7 +158,7 @@ public class GdkFontPeer extends ClasspathFontPeer public String getPostScriptName(Font font) { - return null; + return this.familyName; } public boolean canDisplay (Font font, char c) @@ -301,7 +302,9 @@ public class GdkFontPeer extends ClasspathFontPeer public FontMetrics getFontMetrics (Font font) { - return new GdkFontMetrics (font); + // Get the font metrics through GtkToolkit to take advantage of + // the metrics cache. + return Toolkit.getDefaultToolkit().getFontMetrics (font); } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java index d7217aa7a3f..3c3cbdf32d2 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java @@ -48,6 +48,7 @@ import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; import java.awt.Shape; +import java.awt.Toolkit; import java.awt.image.ImageObserver; import java.text.AttributedCharacterIterator; @@ -218,8 +219,10 @@ public class GdkGraphics extends Graphics public boolean drawImage (Image img, int x, int y, Color bgcolor, ImageObserver observer) { - return drawImage(img, x, y, img.getWidth(null), img.getHeight(null), - bgcolor, observer); + if (img != null) + return drawImage(img, x, y, img.getWidth(null), img.getHeight(null), + bgcolor, observer); + return false; } public boolean drawImage (Image img, int x, int y, ImageObserver observer) @@ -227,16 +230,19 @@ public class GdkGraphics extends Graphics return drawImage (img, x, y, null, observer); } - public boolean drawImage (Image img, int x, int y, int width, int height, - Color bgcolor, ImageObserver observer) + public boolean drawImage(Image img, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) { - if (img instanceof GtkImage) - return ((GtkImage)img).drawImage (this, x, y, width, height, - bgcolor, observer); - else - return (new GtkImage(img.getSource())).drawImage (this, x, y, - width, height, - bgcolor, observer); + if (img != null) + { + if (img instanceof GtkImage) + return ((GtkImage) img).drawImage(this, x, y, width, height, bgcolor, + observer); + return (new GtkImage(img.getSource())).drawImage(this, x, y, width, + height, bgcolor, + observer); + } + return false; } public boolean drawImage (Image img, int x, int y, int width, int height, @@ -249,14 +255,16 @@ public class GdkGraphics extends Graphics int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) { - if (img instanceof GtkImage) - return ((GtkImage)img).drawImage(this, dx1, dy1, dx2, dy2, - sx1, sy1, sx2, sy2, bgcolor, observer); - else - return (new GtkImage(img.getSource())).drawImage(this, dx1, dy1, - dx2, dy2, - sx1, sy1, sx2, sy2, - bgcolor, observer); + if (img != null) + { + if (img instanceof GtkImage) + return ((GtkImage) img).drawImage(this, dx1, dy1, dx2, dy2, sx1, sy1, + sx2, sy2, bgcolor, observer); + return (new GtkImage(img.getSource())).drawImage(this, dx1, dy1, dx2, + dy2, sx1, sy1, sx2, + sy2, bgcolor, observer); + } + return false; } public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, @@ -373,7 +381,9 @@ public class GdkGraphics extends Graphics public FontMetrics getFontMetrics (Font font) { - return new GdkFontMetrics (font); + // Get the font metrics through GtkToolkit to take advantage of + // the metrics cache. + return Toolkit.getDefaultToolkit().getFontMetrics (font); } native void setClipRectangle (int x, int y, int width, int height); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java index 195304dcee2..323d5614aa4 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java @@ -1229,7 +1229,10 @@ public class GdkGraphics2D extends Graphics2D drawPixels(pixels, r.getWidth(), r.getHeight(), r.getWidth(), i2u); updateBufferedImage(); - + + // Cairo seems loosing the current color. + setColor(fg); + return true; } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java index 054ebaaaef3..72908ff5c7f 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java @@ -1,5 +1,5 @@ /* GdkPixbufDecoder.java -- Image data decoding object - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -82,6 +82,14 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder initStaticState (); } + /** + * Lock that should be held for all gdkpixbuf operations. We don't use + * the global gdk_threads_enter/leave functions since gdkpixbuf + * operations can be done in parallel to drawing and manipulating gtk + * widgets. + */ + static Object pixbufLock = new Object(); + static native void initStaticState(); private final int native_state = GtkGenericPeer.getUniqueInteger (); @@ -92,6 +100,7 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder Vector curr; // interface to GdkPixbuf + // These native functions should be called with the pixbufLock held. native void initState (); native void pumpBytes (byte[] bytes, int len) throws IOException; native void pumpDone () throws IOException; @@ -171,11 +180,26 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder byte bytes[] = new byte[4096]; int len = 0; - initState(); + synchronized(pixbufLock) + { + initState(); + } needsClose = true; + + // Note: We don't want the pixbufLock while reading from the InputStream. while ((len = is.read (bytes)) != -1) - pumpBytes (bytes, len); - pumpDone(); + { + synchronized(pixbufLock) + { + pumpBytes (bytes, len); + } + } + + synchronized(pixbufLock) + { + pumpDone(); + } + needsClose = false; for (int i = 0; i < curr.size (); i++) @@ -189,7 +213,10 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder public void finalize() { - finish(needsClose); + synchronized(pixbufLock) + { + finish(needsClose); + } } @@ -495,8 +522,11 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder } processImageStarted(1); - streamImage(pixels, this.ext, width, height, model.hasAlpha(), - (DataOutput) this.getOutput()); + synchronized(pixbufLock) + { + streamImage(pixels, this.ext, width, height, model.hasAlpha(), + (DataOutput) this.getOutput()); + } processImageComplete(); } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java index dc21761209e..797d653d226 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java @@ -38,61 +38,22 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.AWTEvent; import java.awt.Canvas; import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.event.PaintEvent; import java.awt.peer.CanvasPeer; public class GtkCanvasPeer extends GtkComponentPeer implements CanvasPeer { native void create (); + native void realize (); public GtkCanvasPeer (Canvas c) { super (c); } - public Graphics getGraphics () - { - if (GtkToolkit.useGraphics2D ()) - return new GdkGraphics2D (this); - else - return new GdkGraphics (this); - } - - public void handleEvent (AWTEvent event) - { - int id = event.getID(); - - switch (id) - { - case PaintEvent.PAINT: - case PaintEvent.UPDATE: - { - try - { - Graphics g = getGraphics (); - g.setClip (((PaintEvent)event).getUpdateRect()); - - if (id == PaintEvent.PAINT) - awtComponent.paint (g); - else - awtComponent.update (g); - - g.dispose (); - } - catch (InternalError e) - { - System.err.println (e); - } - } - break; - } - } - - /* Preferred size for a drawing widget is always what the user requested */ + // Preferred size for a drawing widget is always what the user + // requested. public Dimension getPreferredSize () { return awtComponent.getSize (); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java index a502e1fd6ef..f520fe224b1 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboard.java @@ -1,5 +1,5 @@ /* GtkClipboard.java - Copyright (C) 1999, 2005 Free Software Foundation, Inc. + Copyright (C) 1999, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -48,59 +48,85 @@ import java.util.Iterator; public class GtkClipboard extends Clipboard { + /** + * The one and only gtk+ clipboard instance for the CLIPBOARD selection. + */ + final static GtkClipboard clipboard = new GtkClipboard("System Clipboard"); + + /** + * The one and only gtk+ clipboard instance for the PRIMARY selection. + */ + final static GtkClipboard selection = new GtkClipboard("System Selection"); // Given to the native side so it can signal special targets that // can be converted to one of the special predefined DataFlavors. - static final String stringMimeType; - static final String imageMimeType; - static final String filesMimeType; + static final String stringMimeType + = DataFlavor.stringFlavor.getMimeType(); + static final String imageMimeType + = DataFlavor.imageFlavor.getMimeType(); + static final String filesMimeType + = DataFlavor.javaFileListFlavor.getMimeType(); // Indicates whether the results of the clipboard selection can be // cached by GtkSelection. True if // gdk_display_supports_selection_notification. - static final boolean canCache; - - static - { - stringMimeType = DataFlavor.stringFlavor.getMimeType(); - imageMimeType = DataFlavor.imageFlavor.getMimeType(); - filesMimeType = DataFlavor.javaFileListFlavor.getMimeType(); - - canCache = initNativeState(stringMimeType, imageMimeType, filesMimeType); - } - - /** - * The one and only gtk+ clipboard instance. - */ - private static GtkClipboard instance = new GtkClipboard(); + static final boolean canCache = initNativeState(clipboard, selection, + stringMimeType, + imageMimeType, + filesMimeType); /** * Creates the clipboard and sets the initial contents to the * current gtk+ selection. */ - private GtkClipboard() + private GtkClipboard(String name) { - super("System Clipboard"); - setContents(new GtkSelection(), null); + super(name); + setContents(new GtkSelection(this), null); } /** - * Returns the one and only GtkClipboard instance. + * Returns the one and only GtkClipboard instance for the CLIPBOARD + * selection. */ + static GtkClipboard getClipboardInstance() + { + return clipboard; + } - static GtkClipboard getInstance() + /** + * Returns the one and only GtkClipboard instance for the PRIMARY + * selection. + */ + static GtkClipboard getSelectionInstance() { - return instance; + return selection; } /** * Sets the GtkSelection facade as new contents of the clipboard. * Called from gtk+ when another application grabs the clipboard and * we loose ownership. + * + * @param cleared If true this is a clear event (someone takes the + * clipboard from us) otherwise it is an owner changed event. */ - private static void setSystemContents() + private synchronized void setSystemContents(boolean cleared) { - GtkClipboardNotifier.announce(); + // We need to notify clipboard owner listeners when we were the + // owner (the selection was explictly set) and someone takes the + // clipboard away from us and asks us the clear any held storage, + // or if we weren't the owner of the clipboard to begin with, but + // the clipboard contents changed. We could refine this and check + // whether the actual available formats did in fact change, but we + // assume listeners will check for that anyway (and if possible we + // ask to cache the available formats so even if multiple + // listeners check after a notification the overhead should be + // minimal). + boolean owner = ! (contents instanceof GtkSelection); + boolean needNotification = (cleared && owner) || (! cleared && ! owner); + if (needNotification) + GtkClipboardNotifier.announce(this); } /** @@ -146,15 +172,12 @@ public class GtkClipboard extends Clipboard || flavor.isRepresentationClassReader()) text = true; - // XXX - We only support automatic image conversion for - // GtkImages at the moment. So explicitly check that we have - // one. if (! images && flavors[i].equals(DataFlavor.imageFlavor)) { try { Object o = contents.getTransferData(DataFlavor.imageFlavor); - if (o instanceof GtkImage) + if (o instanceof Image) images = true; } catch (UnsupportedFlavorException ufe) @@ -265,7 +288,11 @@ public class GtkClipboard extends Clipboard try { - return (GtkImage) contents.getTransferData(DataFlavor.imageFlavor); + Object o = contents.getTransferData(DataFlavor.imageFlavor); + if( o instanceof GtkImage ) + return (GtkImage) o; + else + return new GtkImage(((Image)o).getSource()); } catch (UnsupportedFlavorException ufe) { @@ -384,11 +411,13 @@ public class GtkClipboard extends Clipboard } /** - * Initializes the gtk+ clipboard and caches any native side + * Initializes the gtk+ clipboards and caches any native side * structures needed. Returns whether or not the contents of the * Clipboard can be cached (gdk_display_supports_selection_notification). */ - private static native boolean initNativeState(String stringTarget, + private static native boolean initNativeState(GtkClipboard clipboard, + GtkClipboard selection, + String stringTarget, String imageTarget, String filesTarget); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java index a470fe171b8..fdc7d50c5b5 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkClipboardNotifier.java @@ -39,11 +39,15 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.datatransfer.*; +import java.util.*; class GtkClipboardNotifier extends Thread { - /** Whether or not to announce a GtkSelection change. */ - private static boolean announceChange; + /** Whether to announce a new GtkSelection has been set for CLIPBOARD. */ + static private boolean announceClipboardChange; + + /** Whether to announce a new GtkSelection has been set for PRIMARY. */ + static private boolean announcePrimaryChange; /** * The one and only instance. All operations are synchronized on @@ -64,24 +68,30 @@ class GtkClipboardNotifier extends Thread /** * Notifies that a new GtkSelection has to be announced. + * + * @param clipboard either the GtkClipboard.clipboard or the + * GtkClipboard.selection. */ - static void announce() + static void announce(GtkClipboard clipboard) { synchronized (notifier) { - announceChange = true; + if (clipboard == GtkClipboard.clipboard) + announceClipboardChange = true; + else + announcePrimaryChange = true; notifier.notifyAll(); } } public void run() { - final GtkClipboard clipboard = GtkClipboard.getInstance(); + GtkClipboard clipboard; while (true) { synchronized (this) { - while (!announceChange) + while (! announceClipboardChange && ! announcePrimaryChange) { try { @@ -92,14 +102,24 @@ class GtkClipboardNotifier extends Thread // ignore } } - announceChange = false; + + if (announceClipboardChange) + { + clipboard = GtkClipboard.clipboard; + announceClipboardChange = false; + } + else + { + clipboard = GtkClipboard.selection; + announcePrimaryChange = false; + } } // Do the actual announcement without the lock held. We will // notice a new change after this notification has finished. try { - clipboard.setContents(new GtkSelection(), null); + clipboard.setContents(new GtkSelection(clipboard), null); } catch (Throwable t) { diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java index 821183927b0..1a85de5fe49 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -63,6 +63,7 @@ import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; import java.awt.event.PaintEvent; import java.awt.event.TextEvent; import java.awt.image.BufferedImage; @@ -86,8 +87,6 @@ public class GtkComponentPeer extends GtkGenericPeer Insets insets; - boolean isInRepaint; - /* this isEnabled differs from Component.isEnabled, in that it knows if a parent is disabled. In that case Component.isEnabled may return true, but our isEnabled will always return false */ @@ -100,8 +99,9 @@ public class GtkComponentPeer extends GtkGenericPeer native void gtkWidgetGetPreferredDimensions (int[] dim); native void gtkWindowGetLocationOnScreen (int[] point); native void gtkWidgetGetLocationOnScreen (int[] point); - native void gtkWidgetSetCursor (int type); - native void gtkWidgetSetCursorUnlocked (int type); + native void gtkWidgetSetCursor (int type, GtkImage image, int x, int y); + native void gtkWidgetSetCursorUnlocked (int type, GtkImage image, + int x, int y); native void gtkWidgetSetBackground (int red, int green, int blue); native void gtkWidgetSetForeground (int red, int green, int blue); native void gtkWidgetSetSensitive (boolean sensitive); @@ -150,6 +150,9 @@ public class GtkComponentPeer extends GtkGenericPeer setNativeEventMask (); realize (); + + if (awtComponent.isCursorSet()) + setCursor (); } void setParentAndBounds () @@ -176,16 +179,6 @@ public class GtkComponentPeer extends GtkGenericPeer gtkWidgetSetParent (p); } - void beginNativeRepaint () - { - isInRepaint = true; - } - - void endNativeRepaint () - { - isInRepaint = false; - } - /* * Set the bounds of this peer's AWT Component based on dimensions * returned by the native windowing system. Most Components impose @@ -250,6 +243,8 @@ public class GtkComponentPeer extends GtkGenericPeer return getToolkit().getFontMetrics(font); } + // getGraphics may be overridden by derived classes but it should + // never return null. public Graphics getGraphics () { if (GtkToolkit.useGraphics2D ()) @@ -291,30 +286,10 @@ public class GtkComponentPeer extends GtkGenericPeer switch (id) { case PaintEvent.PAINT: + paintComponent((PaintEvent) event); + break; case PaintEvent.UPDATE: - { - try - { - Graphics g = getGraphics(); - - if (!awtComponent.isShowing() || awtComponent.getWidth() < 1 - || awtComponent.getHeight() < 1 || g == null) - break; - - g.setClip(((PaintEvent) event).getUpdateRect()); - - if (id == PaintEvent.PAINT) - awtComponent.paint(g); - else - awtComponent.update(g); - - g.dispose(); - } - catch (InternalError e) - { - System.err.println(e); - } - } + updateComponent((PaintEvent) event); break; case KeyEvent.KEY_PRESSED: ke = (KeyEvent) event; @@ -328,7 +303,49 @@ public class GtkComponentPeer extends GtkGenericPeer break; } } - + + // This method and its overrides are the only methods in the peers + // that should call awtComponent.paint. + protected void paintComponent (PaintEvent event) + { + // Do not call Component.paint if the component is not showing or + // if its bounds form a degenerate rectangle. + if (!awtComponent.isShowing() + || (awtComponent.getWidth() < 1 || awtComponent.getHeight() < 1)) + return; + + // Creating and disposing a GdkGraphics every time paint is called + // seems expensive. However, the graphics state does not carry + // over between calls to paint, and resetting the graphics object + // may even be more costly than simply creating a new one. + Graphics g = getGraphics(); + + g.setClip(event.getUpdateRect()); + + awtComponent.paint(g); + + g.dispose(); + } + + // This method and its overrides are the only methods in the peers + // that should call awtComponent.update. + protected void updateComponent (PaintEvent event) + { + // Do not call Component.update if the component is not showing or + // if its bounds form a degenerate rectangle. + if (!awtComponent.isShowing() + || (awtComponent.getWidth() < 1 || awtComponent.getHeight() < 1)) + return; + + Graphics g = getGraphics(); + + g.setClip(event.getUpdateRect()); + + awtComponent.update(g); + + g.dispose(); + } + public boolean isFocusTraversable () { return true; @@ -369,7 +386,7 @@ public class GtkComponentPeer extends GtkGenericPeer public void repaint (long tm, int x, int y, int width, int height) { - if (x == 0 && y == 0 && width == 0 && height == 0) + if (width < 1 || height < 1) return; if (tm <= 0) @@ -490,10 +507,28 @@ public class GtkComponentPeer extends GtkGenericPeer public void setCursor (Cursor cursor) { + int x, y; + GtkImage image; + int type = cursor.getType(); + if (cursor instanceof GtkCursor) + { + GtkCursor gtkCursor = (GtkCursor) cursor; + image = gtkCursor.getGtkImage(); + Point hotspot = gtkCursor.getHotspot(); + x = hotspot.x; + y = hotspot.y; + } + else + { + image = null; + x = 0; + y = 0; + } + if (Thread.currentThread() == GtkToolkit.mainThread) - gtkWidgetSetCursorUnlocked (cursor.getType ()); + gtkWidgetSetCursorUnlocked(cursor.getType(), image, x, y); else - gtkWidgetSetCursor (cursor.getType ()); + gtkWidgetSetCursor(cursor.getType(), image, x, y); } public void setEnabled (boolean b) @@ -532,7 +567,7 @@ public class GtkComponentPeer extends GtkGenericPeer public void setVisible (boolean b) { // Only really set visible when component is bigger than zero pixels. - if (b) + if (b && ! (awtComponent instanceof Window)) { Rectangle bounds = awtComponent.getBounds(); b = (bounds.width > 0) && (bounds.height > 0); @@ -561,10 +596,22 @@ public class GtkComponentPeer extends GtkGenericPeer clickCount, popupTrigger)); } + /** + * 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) + { + q().postEvent(new MouseWheelEvent(awtComponent, id, when, mods, + x, y, clickCount, popupTrigger, + type, amount, rotation)); + } + protected void postExposeEvent (int x, int y, int width, int height) { - if (!isInRepaint) - q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, + q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, new Rectangle (x, y, width, height))); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java index 23737b0b0a0..06076e77f45 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java @@ -99,11 +99,6 @@ public class GtkContainerPeer extends GtkComponentPeer } } - public Graphics getGraphics () - { - return super.getGraphics(); - } - public void beginLayout () { } public void endLayout () { } public boolean isPaintPending () { return false; } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkCursor.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCursor.java new file mode 100644 index 00000000000..eb9e713d08c --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkCursor.java @@ -0,0 +1,72 @@ +/* GtkCursor.java -- Simple wrapper for custom cursor. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.gtk; + +import java.awt.Cursor; +import java.awt.Image; +import java.awt.Point; + +/** + * Simple wrapper for custom Cursor. + */ +public class GtkCursor extends Cursor +{ + private final GtkImage image; + private final Point hotspot; + + GtkCursor(Image image, Point hotspot, String name) + { + super(name); + if (image instanceof GtkImage) + this.image = (GtkImage) image; + else + this.image = new GtkImage(image.getSource()); + this.hotspot = hotspot; + } + + GtkImage getGtkImage() + { + return image; + } + + Point getHotspot() + { + return hotspot; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java index 3e3125a2b38..3254f566d17 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java @@ -51,34 +51,6 @@ public class GtkDialogPeer extends GtkWindowPeer { super (dialog); } - - public Graphics getGraphics () - { - Graphics g; - if (GtkToolkit.useGraphics2D ()) - g = new GdkGraphics2D (this); - else - g = new GdkGraphics (this); - g.translate (-insets.left, -insets.top); - return g; - } - - protected void postMouseEvent(int id, long when, int mods, int x, int y, - int clickCount, boolean popupTrigger) - { - super.postMouseEvent (id, when, mods, - x + insets.left, y + insets.top, - clickCount, popupTrigger); - } - - protected void postExposeEvent (int x, int y, int width, int height) - { - if (!isInRepaint) - q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, - new Rectangle (x + insets.left, - y + insets.top, - width, height))); - } void create () { diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java index a0ae9e9eef5..8650578f70e 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java @@ -41,6 +41,7 @@ package gnu.java.awt.peer.gtk; import java.awt.Dialog; import java.awt.FileDialog; import java.awt.Graphics; +import java.awt.event.PaintEvent; import java.awt.peer.FileDialogPeer; import java.io.File; import java.io.FilenameFilter; @@ -166,10 +167,10 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer return filter.accept(dir, filename); } - public Graphics getGraphics () + // Sun does not call FileDialog.update. + protected void updateComponent (PaintEvent event) { - // GtkFileDialog will repaint by itself - return null; + // Override GtkComponetPeer.updateComponent to do nothing. } // called back by native side: handle_response_cb diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFontPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFontPeer.java deleted file mode 100644 index 80ad1580362..00000000000 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFontPeer.java +++ /dev/null @@ -1,225 +0,0 @@ -/* GtkFontPeer.java -- Implements FontPeer with GTK+ - Copyright (C) 1999, 2004, 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.java.awt.peer.gtk; - -import gnu.java.awt.peer.ClasspathFontPeer; - -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.Rectangle2D; -import java.text.CharacterIterator; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -public class GtkFontPeer extends ClasspathFontPeer -{ - private static ResourceBundle bundle; - - static - { - try - { - bundle = ResourceBundle.getBundle ("gnu.java.awt.peer.gtk.font"); - } - catch (Throwable ignored) - { - bundle = null; - } - } - - private final String Xname; - - public GtkFontPeer (String name, int style) - { - // All fonts get a default size of 12 if size is not specified. - this(name, style, 12); - } - - public GtkFontPeer (String name, int style, int size) - { - super(name, style, size); - - String Xname = null; - if (bundle != null) - { - try - { - Xname = bundle.getString (name.toLowerCase () + "." + style); - } - catch (MissingResourceException mre) - { - // ignored - } - } - - if (Xname == null) - { - String weight; - String slant; - String spacing; - - if (style == Font.ITALIC || (style == (Font.BOLD+Font.ITALIC))) - slant = "i"; - else - slant = "r"; - if (style == Font.BOLD || (style == (Font.BOLD+Font.ITALIC))) - weight = "bold"; - else - weight = "medium"; - if (name.equals("Serif") || name.equals("SansSerif") - || name.equals("Helvetica") || name.equals("Times")) - spacing = "p"; - else - spacing = "c"; - - Xname = "-*-*-" + weight + "-" + slant + "-normal-*-*-" + size + "-*-*-" + spacing + "-*-*-*"; - } - - this.Xname = Xname; - } - - public String getXLFD () - { - return Xname; - } - - - /* remaining methods are for static compatibility with the newer - ClasspathFontPeer superclass; none of these methods ever existed or - worked on the older FontPeer interface, but we need to pretend to - support them anyways. */ - - public boolean canDisplay (Font font, char c) - { - throw new UnsupportedOperationException(); - } - - public int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit) - { - throw new UnsupportedOperationException(); - } - - public String getSubFamilyName (Font font, Locale locale) - { - throw new UnsupportedOperationException(); - } - - public String getPostScriptName (Font font) - { - throw new UnsupportedOperationException(); - } - - public int getNumGlyphs (Font font) - { - throw new UnsupportedOperationException(); - } - - public int getMissingGlyphCode (Font font) - { - throw new UnsupportedOperationException(); - } - - public byte getBaselineFor (Font font, char c) - { - throw new UnsupportedOperationException(); - } - - public String getGlyphName (Font font, int glyphIndex) - { - throw new UnsupportedOperationException(); - } - - public GlyphVector createGlyphVector (Font font, - FontRenderContext frc, - CharacterIterator ci) - { - throw new UnsupportedOperationException(); - } - - public GlyphVector createGlyphVector (Font font, - FontRenderContext ctx, - int[] glyphCodes) - { - throw new UnsupportedOperationException(); - } - - public GlyphVector layoutGlyphVector (Font font, - FontRenderContext frc, - char[] chars, int start, - int limit, int flags) - { - throw new UnsupportedOperationException(); - } - - public FontMetrics getFontMetrics (Font font) - { - throw new UnsupportedOperationException(); - } - - public boolean hasUniformLineMetrics (Font font) - { - throw new UnsupportedOperationException(); - } - - public LineMetrics getLineMetrics (Font font, - CharacterIterator ci, - int begin, int limit, - FontRenderContext rc) - { - throw new UnsupportedOperationException(); - } - - public Rectangle2D getMaxCharBounds (Font font, - FontRenderContext rc) - { - throw new UnsupportedOperationException(); - } - - public Rectangle2D getStringBounds (Font font, - CharacterIterator ci, - int begin, int limit, - FontRenderContext frc) - { - throw new UnsupportedOperationException(); - } -} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java index f59e781c2a4..6ec0b72982b 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java @@ -1,5 +1,5 @@ /* GtkFramePeer.java -- Implements FramePeer with GTK - Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 1999, 2002, 2004, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -122,25 +122,11 @@ public class GtkFramePeer extends GtkWindowPeer public void setBounds (int x, int y, int width, int height) { - // prevent window_configure_cb -> awtComponent.setSize -> - // peer.setBounds -> nativeSetBounds self-deadlock on GDK lock. - if (Thread.currentThread() == GtkToolkit.mainThread) - { - int menuBarWidth = width - insets.left - insets.right; - if (menuBar != null && menuBarWidth > 0) - setMenuBarWidthUnlocked (menuBar, menuBarWidth); - - return; - } - int menuBarWidth = width - insets.left - insets.right; if (menuBar != null && menuBarWidth > 0) setMenuBarWidth (menuBar, menuBarWidth); - nativeSetBounds (x, y, - width - insets.left - insets.right, - height - insets.top - insets.bottom - + menuBarHeight); + super.setBounds(x, y, width, height + menuBarHeight); } public void setResizable (boolean resizable) @@ -196,56 +182,21 @@ public class GtkFramePeer extends GtkWindowPeer } } - public Graphics getGraphics () - { - Graphics g; - if (GtkToolkit.useGraphics2D ()) - g = new GdkGraphics2D (this); - else - g = new GdkGraphics (this); - g.translate (-insets.left, -insets.top); - return g; - } - protected void postConfigureEvent (int x, int y, int width, int height) { - int frame_width = width + insets.left + insets.right; + if (menuBar != null && width > 0) + setMenuBarWidthUnlocked (menuBar, width); + // Since insets.top already includes the MenuBar's height, we need // to subtract the MenuBar's height from the top inset. - int frame_height = height + insets.top + insets.bottom - menuBarHeight; - - if (frame_width != awtComponent.getWidth() - || frame_height != awtComponent.getHeight()) - awtComponent.setSize(frame_width, frame_height); + int frame_height = height - menuBarHeight; - int frame_x = x - insets.left; // Likewise, since insets.top includes the MenuBar height, we need // to add back the MenuBar height to the frame's y position. If // no MenuBar exists in this frame, the MenuBar height will be 0. - int frame_y = y - insets.top + menuBarHeight; + int frame_y = y + menuBarHeight; - if (frame_x != awtComponent.getX() - || frame_y != awtComponent.getY()) - { - // awtComponent.setLocation(frame_x, frame_y); - } - } - - protected void postMouseEvent(int id, long when, int mods, int x, int y, - int clickCount, boolean popupTrigger) - { - super.postMouseEvent (id, when, mods, - x + insets.left, y + insets.top, - clickCount, popupTrigger); - } - - protected void postExposeEvent (int x, int y, int width, int height) - { - if (!isInRepaint) - q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, - new Rectangle (x + insets.left, - y + insets.top, - width, height))); + super.postConfigureEvent(x, frame_y, width, frame_height); } public int getState () diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java index b48a2049e27..5e5f1de0113 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkImage.java @@ -123,41 +123,50 @@ public class GtkImage extends Image /** * Returns a copy of the pixel data as a java array. + * Should be called with the GdkPixbufDecoder.pixbufLock held. */ private native int[] getPixels(); /** * Sets the pixel data from a java array. + * Should be called with the GdkPixbufDecoder.pixbufLock held. */ private native void setPixels(int[] pixels); /** * Loads an image using gdk-pixbuf from a file. + * Should be called with the GdkPixbufDecoder.pixbufLock held. */ private native boolean loadPixbuf(String name); /** * Loads an image using gdk-pixbuf from data. + * Should be called with the GdkPixbufDecoder.pixbufLock held. */ private native boolean loadImageFromData(byte[] data); /** * Allocates a Gtk Pixbuf or pixmap + * Should be called with the GdkPixbufDecoder.pixbufLock held. */ private native void createPixmap(); /** * Frees the above. + * Should be called with the GdkPixbufDecoder.pixbufLock held. */ private native void freePixmap(); /** * Sets the pixmap to scaled copy of src image. hints are rendering hints. + * Should be called with the GdkPixbufDecoder.pixbufLock held. */ private native void createScaledPixmap(GtkImage src, int hints); /** * Draws the image, optionally scaled and composited. + * Should be called with the GdkPixbufDecoder.pixbufLock held. + * Also acquires global gdk lock for drawing. */ private native void drawPixelsScaled (GdkGraphics gc, int bg_red, int bg_green, int bg_blue, @@ -166,6 +175,8 @@ public class GtkImage extends Image /** * Draws the image, optionally scaled flipped and composited. + * Should be called with the GdkPixbufDecoder.pixbufLock held. + * Also acquires global gdk lock for drawing. */ private native void drawPixelsScaledFlipped (GdkGraphics gc, int bg_red, int bg_green, @@ -219,12 +230,21 @@ public class GtkImage extends Image File f = new File(filename); try { - if (loadPixbuf(f.getCanonicalPath()) != true) - throw new IllegalArgumentException("Couldn't load image: "+filename); + String path = f.getCanonicalPath(); + synchronized(GdkPixbufDecoder.pixbufLock) + { + if (loadPixbuf(f.getCanonicalPath()) != true) + throw new IllegalArgumentException("Couldn't load image: " + + filename); + } } catch(IOException e) { - throw new IllegalArgumentException("Couldn't load image: "+filename); + IllegalArgumentException iae; + iae = new IllegalArgumentException("Couldn't load image: " + + filename); + iae.initCause(e); + throw iae; } isLoaded = true; @@ -241,8 +261,11 @@ public class GtkImage extends Image */ public GtkImage (byte[] data) { - if (loadImageFromData (data) != true) - throw new IllegalArgumentException ("Couldn't load image."); + synchronized(GdkPixbufDecoder.pixbufLock) + { + if (loadImageFromData (data) != true) + throw new IllegalArgumentException ("Couldn't load image."); + } isLoaded = true; observers = null; @@ -277,8 +300,12 @@ public class GtkImage extends Image { throw new IllegalArgumentException ("Couldn't load image."); } - if (loadImageFromData (baos.toByteArray()) != true) - throw new IllegalArgumentException ("Couldn't load image."); + byte[] array = baos.toByteArray(); + synchronized(GdkPixbufDecoder.pixbufLock) + { + if (loadImageFromData(array) != true) + throw new IllegalArgumentException ("Couldn't load image."); + } isLoaded = true; observers = null; @@ -296,7 +323,10 @@ public class GtkImage extends Image isLoaded = true; observers = null; offScreen = true; - createPixmap(); + synchronized(GdkPixbufDecoder.pixbufLock) + { + createPixmap(); + } } /** @@ -312,7 +342,10 @@ public class GtkImage extends Image offScreen = false; // Use the GDK scaling method. - createScaledPixmap(src, hints); + synchronized(GdkPixbufDecoder.pixbufLock) + { + createScaledPixmap(src, hints); + } } /** @@ -322,7 +355,10 @@ public class GtkImage extends Image GtkImage (Pointer pixbuf) { pixmap = pixbuf; - createFromPixbuf(); + synchronized(GdkPixbufDecoder.pixbufLock) + { + createFromPixbuf(); + } isLoaded = true; observers = null; offScreen = false; @@ -349,6 +385,7 @@ public class GtkImage extends Image /** * Native helper function for constructor that takes a pixbuf Pointer. + * Should be called with the GdkPixbufDecoder.pixbufLock held. */ private native void createFromPixbuf(); @@ -370,8 +407,11 @@ public class GtkImage extends Image isLoaded = true; deliver(); - createPixmap(); - setPixels(pixels); + synchronized(GdkPixbufDecoder.pixbufLock) + { + createPixmap(); + setPixels(pixels); + } } // java.awt.Image methods //////////////////////////////////////////////// @@ -408,7 +448,13 @@ public class GtkImage extends Image { if (!isLoaded) return null; - return new MemoryImageSource(width, height, nativeModel, getPixels(), + + int[] pixels; + synchronized(GdkPixbufDecoder.pixbufLock) + { + pixels = getPixels(); + } + return new MemoryImageSource(width, height, nativeModel, pixels, 0, width); } @@ -454,7 +500,10 @@ public class GtkImage extends Image { observers = new Vector(); isLoaded = false; - freePixmap(); + synchronized(GdkPixbufDecoder.pixbufLock) + { + freePixmap(); + } source.startProduction(new GtkImageConsumer(this, source)); } } @@ -462,7 +511,12 @@ public class GtkImage extends Image public void finalize() { if (isLoaded) - freePixmap(); + { + synchronized(GdkPixbufDecoder.pixbufLock) + { + freePixmap(); + } + } } /** @@ -529,23 +583,29 @@ public class GtkImage extends Image srcHeight = height - srcY; } + if ( this.width <= 0 || this.height <= 0 ) + return true; + if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0) return true; - if(bgcolor != null) - drawPixelsScaledFlipped (g, bgcolor.getRed (), bgcolor.getGreen (), - bgcolor.getBlue (), - flipX, flipY, - srcX, srcY, - srcWidth, srcHeight, - dstX, dstY, - dstWidth, dstHeight, - true); - else - drawPixelsScaledFlipped (g, 0, 0, 0, flipX, flipY, - srcX, srcY, srcWidth, srcHeight, - dstX, dstY, dstWidth, dstHeight, - false); + synchronized(GdkPixbufDecoder.pixbufLock) + { + if(bgcolor != null) + drawPixelsScaledFlipped (g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), + flipX, flipY, + srcX, srcY, + srcWidth, srcHeight, + dstX, dstY, + dstWidth, dstHeight, + true); + else + drawPixelsScaledFlipped (g, 0, 0, 0, flipX, flipY, + srcX, srcY, srcWidth, srcHeight, + dstX, dstY, dstWidth, dstHeight, + false); + } return true; } @@ -559,11 +619,17 @@ public class GtkImage extends Image if (addObserver(observer)) return false; - if(bgcolor != null) - drawPixelsScaled(g, bgcolor.getRed (), bgcolor.getGreen (), - bgcolor.getBlue (), x, y, width, height, true); - else - drawPixelsScaled(g, 0, 0, 0, x, y, width, height, false); + if ( this.width <= 0 || this.height <= 0 ) + return true; + + synchronized(GdkPixbufDecoder.pixbufLock) + { + if(bgcolor != null) + drawPixelsScaled(g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), x, y, width, height, true); + else + drawPixelsScaled(g, 0, 0, 0, x, y, width, height, false); + } return true; } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java index 285f79416f3..bd6ec0aef75 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkListPeer.java @@ -40,6 +40,7 @@ package gnu.java.awt.peer.gtk; import java.awt.AWTEvent; import java.awt.Dimension; +import java.awt.FontMetrics; import java.awt.List; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; @@ -120,11 +121,12 @@ public class GtkListPeer extends GtkComponentPeer public Dimension preferredSize (int rows) { - int dims[] = new int[2]; - - int visibleRows = ((List) awtComponent).getRows(); - getSize (rows, visibleRows, dims); - return new Dimension (dims[0], dims[1]); + // getSize returns the minimum size of the list. + // The width is too narrow for a typical list. + List l = (List) awtComponent; + Dimension d = getMinimumSize(); + FontMetrics fm = l.getFontMetrics(l.getFont()); + return new Dimension(d.width + fm.stringWidth("1234567890"), d.height); } public void removeAll () diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java index 88bb715694d..51fe2bc8e0c 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkPanelPeer.java @@ -39,9 +39,7 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.AWTEvent; -import java.awt.Graphics; import java.awt.Panel; -import java.awt.event.ComponentEvent; import java.awt.event.MouseEvent; import java.awt.event.PaintEvent; import java.awt.peer.PanelPeer; @@ -59,35 +57,10 @@ public class GtkPanelPeer extends GtkContainerPeer public void handleEvent(AWTEvent event) { int id = event.getID(); - switch (id) - { - case MouseEvent.MOUSE_PRESSED: - awtComponent.requestFocusInWindow(); - break; - case PaintEvent.UPDATE: - case PaintEvent.PAINT: - { - try - { - Graphics g = getGraphics(); - if (! awtComponent.isShowing() || awtComponent.getWidth() < 1 - || awtComponent.getHeight() < 1 || g == null) - return; - g.setClip(((PaintEvent) event).getUpdateRect()); - - // Do not want to clear anything before painting.); - awtComponent.paint(g); - - g.dispose(); - return; - } - catch (InternalError e) - { - System.err.println(e); - } - } - } + if (id == MouseEvent.MOUSE_PRESSED) + awtComponent.requestFocusInWindow(); + super.handleEvent(event); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java index 08b6b66dd1f..6a92f86e8b0 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkSelection.java @@ -55,9 +55,6 @@ import java.awt.Image; * that the available flavors might have changed. When requested it * (lazily) caches the targets, and (text, image, or files/uris) * clipboard contents. - * - * XXX - should only cache when - * gdk_display_supports_selection_notification is true. */ public class GtkSelection implements Transferable { @@ -67,6 +64,11 @@ public class GtkSelection implements Transferable static private Object requestLock = new Object(); /** + * Whether we belong to the Clipboard (true) or to the Primary selection. + */ + private final boolean clipboard; + + /** * Whether a request for mimetypes, text, images, uris or byte[] is * currently in progress. Should only be tested or set with * requestLock held. When true no other requests should be made till @@ -143,10 +145,13 @@ public class GtkSelection implements Transferable private byte[] bytes; /** - * Should only be created by the GtkClipboard class. + * Should only be created by the GtkClipboard class. The clipboard + * should be either GtkClipboard.clipboard or + * GtkClipboard.selection. */ - GtkSelection() + GtkSelection(GtkClipboard clipboard) { + this.clipboard = (clipboard == GtkClipboard.clipboard); } /** @@ -181,7 +186,7 @@ public class GtkSelection implements Transferable if (! mimeTypesDelivered) { requestInProgress = true; - requestMimeTypes(); + requestMimeTypes(clipboard); while (! mimeTypesDelivered) { try @@ -312,7 +317,7 @@ public class GtkSelection implements Transferable if (! textDelivered) { requestInProgress = true; - requestText(); + requestText(clipboard); while (! textDelivered) { try @@ -385,7 +390,7 @@ public class GtkSelection implements Transferable if (! imageDelivered) { requestInProgress = true; - requestImage(); + requestImage(clipboard); while (! imageDelivered) { try @@ -464,7 +469,7 @@ public class GtkSelection implements Transferable if (! urisDelivered) { requestInProgress = true; - requestURIs(); + requestURIs(clipboard); while (! urisDelivered) { try @@ -547,7 +552,7 @@ public class GtkSelection implements Transferable // Request bytes and wait till they are available. requestInProgress = true; - requestBytes(target); + requestBytes(clipboard, target); while (! bytesDelivered) { try @@ -653,12 +658,14 @@ public class GtkSelection implements Transferable * content is available the contentLock will be notified through * textAvailable, imageAvailable, urisAvailable or bytesAvailable and the * appropriate field is set. + * The clipboard argument is true if we want the Clipboard, and false + * if we want the (primary) selection. */ - private native void requestText(); - private native void requestImage(); - private native void requestURIs(); - private native void requestBytes(String target); + private native void requestText(boolean clipboard); + private native void requestImage(boolean clipboard); + private native void requestURIs(boolean clipboard); + private native void requestBytes(boolean clipboard, String target); /* Similar to the above but for requesting the supported targets. */ - private native void requestMimeTypes(); + private native void requestMimeTypes(boolean clipboard); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java index 70e25a31957..7757db0c5c5 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -361,7 +361,16 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit if (secman != null) secman.checkSystemClipboardAccess(); - return GtkClipboard.getInstance(); + return GtkClipboard.getClipboardInstance(); + } + + public Clipboard getSystemSelection() + { + SecurityManager secman = System.getSecurityManager(); + if (secman != null) + secman.checkSystemClipboardAccess(); + + return GtkClipboard.getSelectionInstance(); } /** @@ -570,6 +579,11 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit return q; } + public Cursor createCustomCursor(Image image, Point hotspot, String name) + { + return new GtkCursor(image, hotspot, name); + } + protected native void loadSystemColors (int[] systemColors); public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e) diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java index 6cc1390ea39..d15beacb4db 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java @@ -1,5 +1,5 @@ /* GtkWindowPeer.java -- Implements WindowPeer with GTK - Copyright (C) 1998, 1999, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,7 +42,9 @@ import java.awt.AWTEvent; import java.awt.Component; import java.awt.Frame; import java.awt.Graphics; +import java.awt.Rectangle; import java.awt.Window; +import java.awt.event.ComponentEvent; import java.awt.event.PaintEvent; import java.awt.event.WindowEvent; import java.awt.peer.WindowPeer; @@ -62,20 +64,37 @@ public class GtkWindowPeer extends GtkContainerPeer private boolean hasBeenShown = false; private int oldState = Frame.NORMAL; + // Cached awt window component location, width and height. + private int x, y, width, height; + native void gtkWindowSetTitle (String title); native void gtkWindowSetResizable (boolean resizable); native void gtkWindowSetModal (boolean modal); native void realize (); + /** Returns the cached width of the AWT window component. */ + int getX () + { + return x; + } + + /** Returns the cached width of the AWT window component. */ + int getY () + { + return y; + } + + /** Returns the cached width of the AWT window component. */ int getWidth () { - return awtComponent.getWidth(); + return width; } + /** Returns the cached height of the AWT window component. */ int getHeight () { - return awtComponent.getHeight(); + return height; } native void create (int type, boolean decorated, GtkWindowPeer parent); @@ -85,6 +104,10 @@ public class GtkWindowPeer extends GtkContainerPeer Window window = (Window) awtComponent; GtkWindowPeer parent_peer = null; Component parent = awtComponent.getParent(); + x = awtComponent.getX(); + y = awtComponent.getY(); + height = awtComponent.getHeight(); + width = awtComponent.getWidth(); if (!window.isFocusableWindow()) type = GDK_WINDOW_TYPE_HINT_MENU; @@ -129,37 +152,28 @@ public class GtkWindowPeer extends GtkContainerPeer native void nativeSetLocation (int x, int y); native void nativeSetLocationUnlocked (int x, int y); - public void setLocation (int x, int y) + // Called from show. + protected void setLocation (int x, int y) { - // prevent window_configure_cb -> awtComponent.setSize -> - // peer.setBounds -> nativeSetBounds self-deadlock on GDK lock. - if (Thread.currentThread() == GtkToolkit.mainThread) - return; nativeSetLocation (x, y); } - public void setLocationUnlocked (int x, int y) - { - nativeSetLocationUnlocked (x, y); - } - public void setBounds (int x, int y, int width, int height) { - // prevent window_configure_cb -> awtComponent.setSize -> - // peer.setBounds -> nativeSetBounds self-deadlock on GDK lock. - if (Thread.currentThread() == GtkToolkit.mainThread) - return; - - nativeSetBounds (x, y, - width - insets.left - insets.right, - height - insets.top - insets.bottom); - } - - public void setBoundsUnlocked (int x, int y, int width, int height) - { - nativeSetBoundsUnlocked (x, y, - width - insets.left - insets.right, - height - insets.top - insets.bottom); + if (x != getX() + || y != getY() + || width != getWidth() + || height != getHeight()) + { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + + nativeSetBounds (x, y, + width - insets.left - insets.right, + height - insets.top - insets.bottom); + } } public void setTitle (String title) @@ -167,15 +181,25 @@ public class GtkWindowPeer extends GtkContainerPeer gtkWindowSetTitle (title); } - native void setSize (int width, int height); - + // Called from setResizable + protected native void setSize (int width, int height); + + /** + * Needed by both GtkFramePeer and GtkDialogPeer subclasses, so + * implemented here. But never actually called on a GtkWindowPeer + * itself. + */ public void setResizable (boolean resizable) { // Call setSize; otherwise when resizable is changed from true to // false the window will shrink to the dimensions it had before it // was resizable. - setSize (awtComponent.getWidth() - insets.left - insets.right, - awtComponent.getHeight() - insets.top - insets.bottom); + x = awtComponent.getX(); + y = awtComponent.getY(); + width = awtComponent.getWidth(); + height = awtComponent.getHeight(); + setSize (width - insets.left - insets.right, + height - insets.top - insets.bottom); gtkWindowSetResizable (resizable); } @@ -195,23 +219,35 @@ public class GtkWindowPeer extends GtkContainerPeer int frame_width = width + insets.left + insets.right; int frame_height = height + insets.top + insets.bottom; - if (frame_width != awtComponent.getWidth() - || frame_height != awtComponent.getHeight()) - awtComponent.setSize(frame_width, frame_height); + if (frame_width != getWidth() + || frame_height != getHeight()) + { + this.width = frame_width; + this.height = frame_height; + q().postEvent(new ComponentEvent(awtComponent, + ComponentEvent.COMPONENT_RESIZED)); + } int frame_x = x - insets.left; int frame_y = y - insets.top; - if (frame_x != awtComponent.getX() - || frame_y != awtComponent.getY()) + if (frame_x != getX() + || frame_y != getY()) { - // awtComponent.setLocation(frame_x, frame_y); + this.x = frame_x; + this.y = frame_y; + q().postEvent(new ComponentEvent(awtComponent, + ComponentEvent.COMPONENT_MOVED)); } } public void show () { - setLocation(awtComponent.getX(), awtComponent.getY()); + x = awtComponent.getX(); + y = awtComponent.getY(); + width = awtComponent.getWidth(); + height = awtComponent.getHeight(); + setLocation(x, y); setVisible (true); } @@ -244,37 +280,62 @@ public class GtkWindowPeer extends GtkContainerPeer // TODO Auto-generated method stub } + + protected void postExposeEvent (int x, int y, int width, int height) + { + // Translate GTK co-ordinates, which do not include a window + // frame's insets, to AWT co-ordinates, which do include a window + // frame's insets. GtkWindowPeer should always have all-zero + // insets but GtkFramePeer and GtkDialogPeer insets will be + // non-zero. + q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, + new Rectangle (x + insets.left, + y + insets.top, + width, height))); + } + public boolean requestWindowFocus() { // TODO Auto-generated method stub return false; } - public void handleEvent(AWTEvent event) + public Graphics getGraphics () { - int id = event.getID(); - if (id == PaintEvent.UPDATE || id == PaintEvent.PAINT) - { - try - { - Graphics g = getGraphics(); - if (! awtComponent.isShowing() || awtComponent.getWidth() < 1 - || awtComponent.getHeight() < 1 || g == null) - return; - - g.setClip(((PaintEvent) event).getUpdateRect()); - - // Do not want to clear anything before painting. - awtComponent.paint(g); - - g.dispose(); - return; - } - catch (InternalError e) - { - System.err.println(e); - } - } - super.handleEvent(event); + Graphics g = super.getGraphics (); + // Translate AWT co-ordinates, which include a window frame's + // insets, to GTK co-ordinates, which do not include a window + // frame's insets. GtkWindowPeer should always have all-zero + // insets but GtkFramePeer and GtkDialogPeer insets will be + // non-zero. + g.translate (-insets.left, -insets.top); + return g; + } + + protected void updateComponent (PaintEvent event) + { + // Do not clear anything before painting. Sun never calls + // Window.update, only Window.paint. + paintComponent(event); + } + + protected void postMouseEvent(int id, long when, int mods, int x, int y, + int clickCount, boolean popupTrigger) + { + // Translate AWT co-ordinates, which include a window frame's + // insets, to GTK co-ordinates, which do not include a window + // frame's insets. GtkWindowPeer should always have all-zero + // insets but GtkFramePeer and GtkDialogPeer insets will be + // non-zero. + super.postMouseEvent (id, when, mods, + x + insets.left, y + insets.top, + clickCount, popupTrigger); + } + + // We override this to keep it in sync with our internal + // representation. + public Rectangle getBounds() + { + return new Rectangle(x, y, width, height); } } diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java index 5e34bc9dd21..5d484e021b2 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java @@ -590,8 +590,7 @@ public class SwingComponentPeer */ public void setBounds(int x, int y, int width, int height) { - if (swingComponent != null) - swingComponent.getJComponent().setBounds(x, y, width, height); + reshape(x, y, width, height); } /** diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingContainerPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingContainerPeer.java index 37bea751f86..0b2fb992fb9 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingContainerPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingContainerPeer.java @@ -61,7 +61,7 @@ public class SwingContainerPeer * * @param awtCont */ - public SwingContainerPeer(Container awtCont) + public SwingContainerPeer(Component awtCont) { init(awtCont, null); } @@ -92,12 +92,7 @@ public class SwingContainerPeer */ public Insets getInsets() { - Insets retVal; - if (swingComponent != null) - retVal = swingComponent.getJComponent().getInsets(); - else - retVal = new Insets(0, 0, 0, 0); - return retVal; + return insets(); } /** @@ -214,12 +209,15 @@ public class SwingContainerPeer protected void handleMouseEvent(MouseEvent ev) { Component comp = awtComponent.getComponentAt(ev.getPoint()); - ComponentPeer peer = comp.getPeer(); - if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer) + if (comp != null) { - ev.translatePoint(comp.getX(), comp.getY()); - ev.setSource(comp); - ((SwingComponentPeer) peer).handleMouseEvent(ev); + ComponentPeer peer = comp.getPeer(); + if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer) + { + ev.translatePoint(comp.getX(), comp.getY()); + ev.setSource(comp); + ((SwingComponentPeer) peer).handleMouseEvent(ev); + } } } @@ -231,11 +229,14 @@ public class SwingContainerPeer protected void handleMouseMotionEvent(MouseEvent ev) { Component comp = awtComponent.getComponentAt(ev.getPoint()); - ComponentPeer peer = comp.getPeer(); - if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer) + if (comp != null) { - ev.translatePoint(comp.getX(), comp.getY()); - ((SwingComponentPeer) peer).handleMouseMotionEvent(ev); + ComponentPeer peer = comp.getPeer(); + if (awtComponent != comp && !comp.isLightweight() && peer instanceof SwingComponentPeer) + { + ev.translatePoint(comp.getX(), comp.getY()); + ((SwingComponentPeer) peer).handleMouseMotionEvent(ev); + } } } } |