diff options
author | Graydon Hoare <graydon@redhat.com> | 2005-01-04 18:45:23 +0000 |
---|---|---|
committer | Graydon Hoare <graydon@redhat.com> | 2005-01-04 18:45:23 +0000 |
commit | 332677cf44c63b9e97096f2fe7b184a43a216d85 (patch) | |
tree | 1af1110e089fe0fd35fdb253ccba3d46f93c7116 /libjava/gnu | |
parent | c7fa07b2f6a20230c9a132178721d6883abbc2c6 (diff) |
2005-01-04 Graydon Hoare <graydon@redhat.com>
* Makefile.am
(jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c)
(gnu/java/awt/peer/gtk/GtkMainThread.java) : Remove.
* Makefile.in: Regenerate.
* gnu/awt/xlib/XEventLoop.java: Fix to match thread model.
* gnu/awt/xlib/XFramePeer.java: Likewise.
* gnu/awt/xlib/XToolkit.java: Likewise.
* gnu/gcj/xlib/XAnyEvent.java: Likewise.
* gnu/gcj/xlib/natXAnyEvent.cc: Likewise.
* gnu/java/awt/ClasspathToolkit.java
(nativeQueueEmpty)
(wakeNativeQueue)
(iterateNativeQueue): New methods.
* gnu/java/awt/peer/gtk/GtkMainThread.java: Remove.
* gnu/java/awt/peer/gtk/GtkToolkit.java
(gtkInit): Absorb from defunct GtkMainThread class.
(static): Run gtkInit in static startup block.
(GtkToolkit): Remove construction of GtkMainThread and queue.
(getSystemEventQueueImpl): Construct queue when requested.
(nativeQueueEmpty)
(wakeNativeQueue)
(iterateNativeQueue): New methods.
* java/awt/Component.java (removeNotify): Remove race.
* java/awt/EventDispatchThread.java
(EventDispatchThread): Don't start on construction.
(run): Remove isInterrupted check.
* java/awt/EventQueue.java (shutdown): New flag.
(isShutdown): New method checking J2SE shutdown condition.
(setShutdown): New method.
(getNextEvent): Restructure to use ClasspathToolkit.
(postEvent): Activate new thread on posting, wake thread on
post of possible shutdown condition event.
* java/awt/Frame.java
(Frame): Call noteFrame in all constructors.
(fireDummyEvent): New helper method.
(addNotify): Fire a dummy event to wake up queue.
(removeNotify): Fire a dummy event to wake up queue.
(noteFrame): New method.
(weakFrames): New static field.
(getFrames): Implement.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c:
Remove.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c:
Move everything from GtkMainThread into this file
(Java_gnu_java_awt_peer_gtk_GtkToolkit_iterateNativeQueue)
(Java_gnu_java_awt_peer_gtk_GtkToolkit_wakeNativeQueue)
(Java_gnu_java_awt_peer_gtk_GtkToolkit_nativeQueueEmpty):
New functions to implement single-threaded queue semantics.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/java-gui-branch@92900 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/gnu')
-rw-r--r-- | libjava/gnu/awt/xlib/XEventLoop.java | 30 | ||||
-rw-r--r-- | libjava/gnu/awt/xlib/XFramePeer.java | 2 | ||||
-rw-r--r-- | libjava/gnu/awt/xlib/XToolkit.java | 20 | ||||
-rw-r--r-- | libjava/gnu/gcj/xlib/XAnyEvent.java | 4 | ||||
-rw-r--r-- | libjava/gnu/gcj/xlib/natXAnyEvent.cc | 57 | ||||
-rw-r--r-- | libjava/gnu/java/awt/ClasspathToolkit.java | 5 | ||||
-rw-r--r-- | libjava/gnu/java/awt/peer/gtk/GtkMainThread.java | 22 | ||||
-rw-r--r-- | libjava/gnu/java/awt/peer/gtk/GtkToolkit.java | 38 |
8 files changed, 147 insertions, 31 deletions
diff --git a/libjava/gnu/awt/xlib/XEventLoop.java b/libjava/gnu/awt/xlib/XEventLoop.java index 66878185b51..bda5a9f4822 100644 --- a/libjava/gnu/awt/xlib/XEventLoop.java +++ b/libjava/gnu/awt/xlib/XEventLoop.java @@ -21,12 +21,11 @@ import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.util.Vector; -public class XEventLoop implements Runnable +public class XEventLoop { Display display; EventQueue queue; XAnyEvent anyEvent; - Thread eventLoopThread; LightweightRedirector lightweightRedirector = new LightweightRedirector(); @@ -36,20 +35,18 @@ public class XEventLoop implements Runnable this.queue = queue; anyEvent = new XAnyEvent(display); - eventLoopThread = new Thread(this, "AWT thread for XEventLoop"); - eventLoopThread.start(); } - public void run() + void interrupt() { - while (true) - postNextEvent(); + anyEvent.interrupt(); } void postNextEvent() { AWTEvent evt = getNextEvent(); - queue.postEvent(evt); + if (evt != null) + queue.postEvent(evt); } /** get next event. Will block until events become available. */ @@ -61,19 +58,17 @@ public class XEventLoop implements Runnable throw new Error("should not be idle"); AWTEvent event = null; - while (event == null) + if (loadNextEvent()) { - loadNextEvent(); - event = createEvent(); - } - - event = lightweightRedirector.redirect(event); - + event = createEvent(); + event = lightweightRedirector.redirect(event); + } return event; } - void loadNextEvent() + boolean loadNextEvent() { + boolean gotEvent = false; try { setIdle(true); @@ -100,7 +95,7 @@ public class XEventLoop implements Runnable of events. */ //display.flush(); // implicit? - anyEvent.loadNext(); + gotEvent = anyEvent.loadNext(); } catch (RuntimeException re) { @@ -110,6 +105,7 @@ public class XEventLoop implements Runnable { setIdle(false); } + return gotEvent; } /** diff --git a/libjava/gnu/awt/xlib/XFramePeer.java b/libjava/gnu/awt/xlib/XFramePeer.java index ec159078aba..f3c655ecf80 100644 --- a/libjava/gnu/awt/xlib/XFramePeer.java +++ b/libjava/gnu/awt/xlib/XFramePeer.java @@ -78,7 +78,7 @@ public class XFramePeer extends XCanvasPeer implements FramePeer bounds. */ public void setBounds(int x, int y, int width, int height) { - if (Thread.currentThread() == getXToolkit().eventLoop.eventLoopThread) + if (EventQueue.isDispatchThread()) return; super.setBounds(x, y, width, height); diff --git a/libjava/gnu/awt/xlib/XToolkit.java b/libjava/gnu/awt/xlib/XToolkit.java index c353d8f474d..814b12637e8 100644 --- a/libjava/gnu/awt/xlib/XToolkit.java +++ b/libjava/gnu/awt/xlib/XToolkit.java @@ -443,4 +443,24 @@ public class XToolkit extends ClasspathToolkit { throw new java.lang.UnsupportedOperationException (); } + + boolean interrupted; + + public boolean nativeQueueEmpty() + { + return eventLoop.isIdle(); + } + + public void wakeNativeQueue() + { + interrupted = true; + eventLoop.interrupt(); + } + + public void iterateNativeQueue(java.awt.EventQueue locked) + { + interrupted = false; + while (!interrupted) + eventLoop.postNextEvent(); + }; } diff --git a/libjava/gnu/gcj/xlib/XAnyEvent.java b/libjava/gnu/gcj/xlib/XAnyEvent.java index 061d6137b17..317d444dc00 100644 --- a/libjava/gnu/gcj/xlib/XAnyEvent.java +++ b/libjava/gnu/gcj/xlib/XAnyEvent.java @@ -70,7 +70,8 @@ public final class XAnyEvent /** * Load next event into the event structure. */ - public native void loadNext(); + public native boolean loadNext(); + public native void interrupt(); public native int getType(); public native void setType(int type); @@ -86,6 +87,7 @@ public final class XAnyEvent public native void send(Window destination, boolean propagate, long mask); + RawData pipefds; RawData structure; Display display; diff --git a/libjava/gnu/gcj/xlib/natXAnyEvent.cc b/libjava/gnu/gcj/xlib/natXAnyEvent.cc index 439f204b373..d9713d3e502 100644 --- a/libjava/gnu/gcj/xlib/natXAnyEvent.cc +++ b/libjava/gnu/gcj/xlib/natXAnyEvent.cc @@ -6,6 +6,12 @@ This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ +#include <config.h> +#include <platform.h> + +#include <gcj/javaprims.h> +#include <jvm.h> + #include <X11/Xlib.h> #include <gcj/cni.h> @@ -22,24 +28,69 @@ details. */ #include <gnu/gcj/xlib/XExposeEvent.h> #include <gnu/gcj/xlib/XException.h> +#include <unistd.h> +#include <posix.h> + void gnu::gcj::xlib::XAnyEvent::init() { ::XEvent* event = new ::XEvent; + int *pipes = new int[2]; + pipe(pipes); structure = reinterpret_cast<gnu::gcj::RawData*>(event); + pipefds = reinterpret_cast<gnu::gcj::RawData*>(pipes); } void gnu::gcj::xlib::XAnyEvent::finalize() { delete structure; + int *pipe = reinterpret_cast<int *>(pipefds); + close(pipe[0]); + close(pipe[1]); + delete [] pipefds; + pipefds = 0; structure = 0; } -void gnu::gcj::xlib::XAnyEvent::loadNext() +jboolean gnu::gcj::xlib::XAnyEvent::loadNext() { ::Display* dpy = (::Display*) display->display; ::XEvent* evt = (::XEvent*) structure; - XNextEvent(dpy, evt); - // What does XNextEvent return? + + if (XPending(dpy)) + { + XNextEvent(dpy, evt); + return true; + } + + int *pipe = reinterpret_cast<int *>(pipefds); + int xfd = XConnectionNumber(dpy); + int pipefd = pipe[0]; + int n = (xfd > pipefd ? xfd : pipefd) + 1; + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(xfd, &rfds); + FD_SET(pipefd, &rfds); + int sel = _Jv_select (n, &rfds, NULL, NULL, NULL); + if (sel > 0) + { + if (FD_ISSET(xfd, &rfds)) + { + XNextEvent(dpy, evt); + return true; + } + if (FD_ISSET(pipefd, &rfds)) + { + char c; + read(pipefd, &c, 1); + } + } + return false; +} + +void gnu::gcj::xlib::XAnyEvent::interrupt() +{ + int *pipe = reinterpret_cast<int *>(pipefds); + write(pipe[1], "W", 1); } jint gnu::gcj::xlib::XAnyEvent::getType() diff --git a/libjava/gnu/java/awt/ClasspathToolkit.java b/libjava/gnu/java/awt/ClasspathToolkit.java index 3f0b964b4e9..1ae54742bb5 100644 --- a/libjava/gnu/java/awt/ClasspathToolkit.java +++ b/libjava/gnu/java/awt/ClasspathToolkit.java @@ -45,6 +45,7 @@ import java.awt.AWTException; import java.awt.Image; import java.awt.Dimension; import java.awt.DisplayMode; +import java.awt.EventQueue; import java.awt.Font; import java.awt.FontMetrics; import java.awt.GraphicsEnvironment; @@ -354,4 +355,8 @@ public abstract class ClasspathToolkit public abstract RobotPeer createRobot (GraphicsDevice screen) throws AWTException; + + public abstract boolean nativeQueueEmpty(); + public abstract void wakeNativeQueue(); + public abstract void iterateNativeQueue(EventQueue locked); } diff --git a/libjava/gnu/java/awt/peer/gtk/GtkMainThread.java b/libjava/gnu/java/awt/peer/gtk/GtkMainThread.java index 4cbe190731c..2a6c3d26f35 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkMainThread.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkMainThread.java @@ -55,7 +55,21 @@ public class GtkMainThread extends GtkGenericPeer implements Runnable * set to "false". -1 if unset. */ static native void gtkInit(int portableNativeSync); - native void gtkMain(); + + public native void wakeup(); + native void iterate(); + + boolean running = true; + public synchronized boolean stillRunning() + { + return running; + } + + public synchronized void quit() + { + running = false; + wakeup(); + } public GtkMainThread() { @@ -63,7 +77,8 @@ public class GtkMainThread extends GtkGenericPeer implements Runnable synchronized (mainThreadLock) { if (mainThread != null) - throw new IllegalStateException(); + return; + //throw new IllegalStateException(); mainThread = new Thread(this, "GtkMain"); } @@ -103,7 +118,8 @@ public class GtkMainThread extends GtkGenericPeer implements Runnable gtkInitCalled = true; notifyAll(); } - gtkMain(); + while(stillRunning()) + iterate(); } } diff --git a/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java index bf5b814aa6c..c7df27ef70a 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -70,6 +70,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.MissingResourceException; import java.util.Properties; +import javax.imageio.spi.IIORegistry; /* This class uses a deprecated method java.awt.peer.ComponentPeer.getPeer(). This merits comment. We are basically calling Sun's bluff on this one. @@ -88,9 +89,8 @@ import java.util.Properties; public class GtkToolkit extends gnu.java.awt.ClasspathToolkit implements EmbeddedWindowSupport { - GtkMainThread main; Hashtable containers = new Hashtable(); - static EventQueue q = new EventQueue(); + static EventQueue q; static Clipboard systemClipboard; static boolean useGraphics2dSet; static boolean useGraphics2d; @@ -105,19 +105,32 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit return useGraphics2d; } + static native void gtkInit(int portableNativeSync); + static { if (Configuration.INIT_LOAD_LIBRARY) System.loadLibrary("gtkpeer"); + + int portableNativeSync; + String portNatSyncProp = + System.getProperty("gnu.classpath.awt.gtk.portable.native.sync"); + + if (portNatSyncProp == null) + portableNativeSync = -1; // unset + else if (Boolean.valueOf(portNatSyncProp).booleanValue()) + portableNativeSync = 1; // true + else + portableNativeSync = 0; // false + + gtkInit(portableNativeSync); } public GtkToolkit () { - main = new GtkMainThread (); systemClipboard = new GtkClipboard (); - GtkGenericPeer.enableQueue (q); } - + native public void beep (); native private void getScreenSizeDimensions (int[] xy); @@ -596,6 +609,14 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit protected EventQueue getSystemEventQueueImpl() { + synchronized (GtkToolkit.class) + { + if (q == null) + { + q = new EventQueue(); + GtkGenericPeer.enableQueue (q); + } + } return q; } @@ -627,4 +648,9 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit { return new GdkRobotPeer (screen); } -} + + public native boolean nativeQueueEmpty(); + public native void wakeNativeQueue(); + public native void iterateNativeQueue(EventQueue locked); + +} // class GtkToolkit |