aboutsummaryrefslogtreecommitdiff
path: root/libjava/gnu
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@redhat.com>2005-01-04 18:45:23 +0000
committerGraydon Hoare <graydon@redhat.com>2005-01-04 18:45:23 +0000
commit332677cf44c63b9e97096f2fe7b184a43a216d85 (patch)
tree1af1110e089fe0fd35fdb253ccba3d46f93c7116 /libjava/gnu
parentc7fa07b2f6a20230c9a132178721d6883abbc2c6 (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.java30
-rw-r--r--libjava/gnu/awt/xlib/XFramePeer.java2
-rw-r--r--libjava/gnu/awt/xlib/XToolkit.java20
-rw-r--r--libjava/gnu/gcj/xlib/XAnyEvent.java4
-rw-r--r--libjava/gnu/gcj/xlib/natXAnyEvent.cc57
-rw-r--r--libjava/gnu/java/awt/ClasspathToolkit.java5
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkMainThread.java22
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkToolkit.java38
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