[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gzz-commits] gzz gfx/jni/GzzGL-jni.cxx gfx/libos/Os-GLX.cxx ...
From: |
Tuomas J. Lukka |
Subject: |
[Gzz-commits] gzz gfx/jni/GzzGL-jni.cxx gfx/libos/Os-GLX.cxx ... |
Date: |
Sat, 18 Jan 2003 09:53:09 -0500 |
CVSROOT: /cvsroot/gzz
Module name: gzz
Changes by: Tuomas J. Lukka <address@hidden> 03/01/18 09:53:09
Modified files:
gfx/jni : GzzGL-jni.cxx
gfx/libos : Os-GLX.cxx Os.hxx
gzz/client : AbstractUpdateManager.java
gzz/client/gl : GLUpdateManager.java
gzz/gfx/gl : GL.java
Log message:
Rework event loop; next: retry mipzip
CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/jni/GzzGL-jni.cxx.diff?tr1=1.77&tr2=1.78&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/libos/Os-GLX.cxx.diff?tr1=1.20&tr2=1.21&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/libos/Os.hxx.diff?tr1=1.17&tr2=1.18&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gzz/client/AbstractUpdateManager.java.diff?tr1=1.30&tr2=1.31&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gzz/client/gl/GLUpdateManager.java.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gzz/gfx/gl/GL.java.diff?tr1=1.41&tr2=1.42&r1=text&r2=text
Patches:
Index: gzz/gfx/jni/GzzGL-jni.cxx
diff -u gzz/gfx/jni/GzzGL-jni.cxx:1.77 gzz/gfx/jni/GzzGL-jni.cxx:1.78
--- gzz/gfx/jni/GzzGL-jni.cxx:1.77 Thu Jan 16 07:54:24 2003
+++ gzz/gfx/jni/GzzGL-jni.cxx Sat Jan 18 09:53:08 2003
@@ -210,29 +210,6 @@
}
};
-/*
-struct GZZJNIIdler : public Gzz::AbstractWin::IdleTasks {
- jobject globalRef;
- jclass globalclass; // must keep for mid to remain valid
- jmethodID mid_tick;
- GZZJNIIdler(JNIEnv *env, jobject globalRef) : globalRef(globalRef) {
- jclass cls = env->GetObjectClass(globalRef);
- globalclass = (jclass)env->NewGlobalRef(cls);
- mid_tick = env->GetMethodID(globalclass,
- "tick", "()Z");
- }
- ~GZZJNIIdler() {
- }
- bool tick() {
- // cout << "Starting to call tick\n";
- // cout << "Calling tick "<<mid<<"\n";
- bool ret = jnienv_eventloop->CallBooleanMethod(globalRef, mid_tick);
- // cout << "Finished: \n" << ret;
- return ret;
- }
-};
-*/
-
extern "C" {
int inited = 0;
@@ -315,13 +292,6 @@
windows.remove(id);
}
-JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_repaintWindow
- (JNIEnv *env, jclass, jint id) {
- DBG(dbg_event) << "RepaintWindow called\n";
- Os::Window *w = (Os::Window *)windows.get(id);
- w->repaint();
- }
-
JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_getWindowSize
(JNIEnv *env, jclass, jint id, jobject rect) {
Os::RenderingSurface *win = windows.get(id);
@@ -1023,12 +993,15 @@
} catch(JavaException e) {
cerr << "CAUGHT JAVA EXCEPTION\n";
}
- /*
- ticker = env->NewGlobalRef(ticker);
- ws->addIdle(new GZZJNIIdler(env, ticker));
- ws->eventLoop();
- */
}
+
+JNIEXPORT void JNICALL Java_gzz_gfx_gl_GL_interruptEventloop
+ (JNIEnv *env, jclass) {
+ DBG(dbg) << "Interrupting C++ eventloop";
+ ws->interrupt();
+ DBG(dbg) << "Done interrupting - should wake soon";
+ }
+
#include <sys/time.h>
double getTime() {
Index: gzz/gfx/libos/Os-GLX.cxx
diff -u gzz/gfx/libos/Os-GLX.cxx:1.20 gzz/gfx/libos/Os-GLX.cxx:1.21
--- gzz/gfx/libos/Os-GLX.cxx:1.20 Thu Dec 19 04:12:39 2002
+++ gzz/gfx/libos/Os-GLX.cxx Sat Jan 18 09:53:08 2003
@@ -31,6 +31,8 @@
#include <sys/time.h>
#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
#include <libos/Os.hxx>
@@ -155,6 +157,8 @@
typedef ::Window Win; // work around a syntax error.
+ /** Return the current time as milliseconds after some unit.
+ */
long curTime() {
struct timeval t;
gettimeofday(&t, 0);
@@ -179,6 +183,15 @@
}
struct LXWindowSystem : public Os::WindowSystem {
+
+ /** A pipe, used to interrupt waiting of eventloop.
+ */
+ int interruptPipe[2];
+
+ fd_set readFds;
+ fd_set tmpReadFds;
+ int fdsMax;
+
Display *dpy;
XSetWindowAttributes swa;
int swaMask;
@@ -209,8 +222,20 @@
Drawable pixmapDrawable;
LXWindowSystem() {
+ if(pipe(interruptPipe) < 0) {
+ perror("Making interrupt pipe");
+ exit(1);
+ }
+ fcntl(interruptPipe[0], F_SETFL, O_NONBLOCK);
+ fcntl(interruptPipe[1], F_SETFL, O_NONBLOCK);
+
if(!(dpy = XOpenDisplay( NULL ))) BARF("Can't start X");
+ FD_ZERO(&readFds);
+ FD_SET(ConnectionNumber(dpy), &readFds);
+ FD_SET(interruptPipe[0], &readFds);
+ fdsMax = (ConnectionNumber(dpy) >? interruptPipe[0]) + 5;
+
int nel;
@@ -304,6 +329,7 @@
return f;
}
+ void interrupt();
void eventLoop(bool wait);
/*
@@ -313,7 +339,6 @@
*/
private:
- bool tryRepaint();
};
@@ -411,7 +436,6 @@
virtual void setEventHandler(Eventhandler *h) {
eventhandler = h;
DBG(dbg) << "Set window "<<xw<<" eventhandler to "<<((int)h)<<"\n";
- repaint();
}
LXWindow(LXWindowSystem *ws, int x, int y, int w, int h) : ws(ws),
@@ -477,21 +501,6 @@
glXSwapBuffers(ws->dpy, xw);
}
- virtual void repaint() {
- needRepaint = true;
- }
-
- bool tryRepaint() {
- // cout << "TryRepaint\n";
- if(needRepaint) {
- needRepaint = false;
- if(eventhandler) {
- eventhandler->repaint();
- return true;
- }
- }
- return false;
- }
virtual void move(int x, int y) {
XMoveWindow(ws->dpy, xw, x, y);
@@ -593,19 +602,19 @@
}
case Expose:
DBG(dbg) << "Expose\n";
- repaint();
+ eventhandler->repaint();
break;
case ConfigureNotify:
DBG(dbg) << "Configurenotify\n";
- repaint();
+ eventhandler->repaint();
break;
case MapRequest:
DBG(dbg) << "MapRequest\n";
- repaint();
+ eventhandler->repaint();
break;
case MapNotify:
DBG(dbg) << "MapNotify\n";
- repaint();
+ eventhandler->repaint();
break;
default:
DBG(dbg) << "Unknown event "<<e->type<<"\n";
@@ -636,52 +645,66 @@
return instance;
}
+ char intr = 'S';
+ void LXWindowSystem::interrupt() {
+ write(interruptPipe[1], &intr, 1);
+ }
+
void LXWindowSystem::eventLoop(bool wait) {
DBG(dbg) << "In C++ eventloop : "<<wait<<"\n";
// We don't want to block;
while(1) {
DBG(dbg) << "Start loop\n";
- XEvent e;
- if(tryRepaint()) {
- DBG(dbg) << "TryRepaint returned true, doing again... if no
events (not now)\n";
- /*
- if(!XEventsQueued(dpy, QueuedAfterFlush))
- continue;
- */
- }
- /*
- for(int i=0; i<idletasks.size(); i++) {
- donthang = (donthang || idletasks[i]->tick());
- }
- */
- DBG(dbg) << "Repaint done\n";
bool eventsWaiting = XEventsQueued(dpy, QueuedAfterFlush);
+ // If we should not wait and there are no events, return now
if(!wait && !eventsWaiting) return;
+ // We only wait once: on the next iteration of the loop,
+ // we'll return
+ wait = false;
- DBG(dbg) << "Get next event\n";
- // If we're waiting for a timeout, handle things
- // differently.
- if(timeouts.size() && !eventsWaiting) {
- long t = curTime();
- for(unsigned i=0; i<timeouts.size(); i++) {
- if(timeouts[i].time < t) {
- int id = timeouts[i].id;
- LXWindow *w = windowsByX[timeouts[i].window];
- timeouts.erase(timeouts.begin()+i);
- w->deliverTimeout(id);
- return;
+ DBG(dbg) << "Wait for next event, interrupt or timeout\n";
+
+ // If no events were waiting, now's the time to
+ // wait for them.
+ if(!eventsWaiting) {
+ // Visit Java at least every .5 seconds
+ timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 500 * 1000;
+
+ // If we're waiting for a timeout, sleep less.
+ if(timeouts.size() && !eventsWaiting) {
+ long t = curTime();
+ for(unsigned i=0; i<timeouts.size(); i++) {
+ if(timeouts[i].time < t) {
+ int id = timeouts[i].id;
+ LXWindow *w = windowsByX[timeouts[i].window];
+ timeouts.erase(timeouts.begin()+i);
+ w->deliverTimeout(id);
+ return;
+ } else {
+ int ms = timeouts[i].time - t;
+ if(ms < timeout.tv_usec / 1000)
+ timeout.tv_sec = 1000 * ms;
+ }
}
}
- timespec ts;
- ts.tv_sec = 0;
- ts.tv_nsec = 50000000; // 50 ms - very bad
- nanosleep(&ts, &ts);
- continue;
+ // Call select to wait for something to happen.
+ tmpReadFds = readFds;
+ select(fdsMax, &tmpReadFds, 0, 0, &timeout);
+ char b[4];
+ DBG(dbg) << "Emptying interrupt pipe\n";
+ while(read(interruptPipe[0], &b, 4) > 0) {
+ DBG(dbg) << "Got "<<b[0]<<" "<<b[1]<<" "<<b[2]<< "
"<<b[3]<<"\n";
+ }
+ DBG(dbg) << "Empty\n";
}
- wait = false;
+
+
+ XEvent e;
XNextEvent(dpy, &e);
//cout << "getWindow\n";
LXWindow *w = windowsByX[e.xkey.window];
@@ -692,13 +715,6 @@
//cout << "deliver\n";
w->deliverEvent(&e);
}
- }
-
- bool LXWindowSystem::tryRepaint() {
- for(unsigned i=0; i<windows.size(); i++) {
- if(windows[i]->tryRepaint()) return true;
- }
- return false;
}
/** Load an image into a raster using gdk-pixbuf.
Index: gzz/gfx/libos/Os.hxx
diff -u gzz/gfx/libos/Os.hxx:1.17 gzz/gfx/libos/Os.hxx:1.18
--- gzz/gfx/libos/Os.hxx:1.17 Mon Jan 13 01:48:49 2003
+++ gzz/gfx/libos/Os.hxx Sat Jan 18 09:53:08 2003
@@ -99,9 +99,6 @@
public:
Window() { }
virtual ~Window() { };
- /** Queue a repaint request.
- */
- virtual void repaint() = 0;
virtual void setEventHandler(Eventhandler *h) = 0;
/*
virtual Eventhandler *getEventHandler() {
@@ -148,7 +145,23 @@
virtual Text::Font *loadFont(const char *javaName,
int pt) = 0;
+ /** Handle events.
+ * @param wait If true, this function will wait for the next event
+ * and handle it before returning; if false, will return
+ * immediately.
+ */
virtual void eventLoop(bool wait) = 0;
+
+ /** Interrupt event loop waiting.
+ * Because there are things happening in multiple threads in Java,
+ * it is useful to be able to stop the event loop from waiting
+ * to perform idle tasks again.
+ * <p>
+ * This is the ONLY function here that may be called from another
+ * thread.
+ */
+ virtual void interrupt() = 0;
+
};
Index: gzz/gzz/client/AbstractUpdateManager.java
diff -u gzz/gzz/client/AbstractUpdateManager.java:1.30
gzz/gzz/client/AbstractUpdateManager.java:1.31
--- gzz/gzz/client/AbstractUpdateManager.java:1.30 Sat Jan 18 08:30:58 2003
+++ gzz/gzz/client/AbstractUpdateManager.java Sat Jan 18 09:53:08 2003
@@ -41,7 +41,7 @@
*/
public abstract class AbstractUpdateManager implements Runnable {
-public static final String rcsid = "$Id: AbstractUpdateManager.java,v 1.30
2003/01/18 13:30:58 tjl Exp $";
+public static final String rcsid = "$Id: AbstractUpdateManager.java,v 1.31
2003/01/18 14:53:08 tjl Exp $";
public static boolean dbg = false;
private static void pa(String s) { System.err.println(s); }
@@ -330,7 +330,10 @@
queue.add(r, priority);
queue.notifyAll();
}
+ instance.interruptEventloop();
}
+
+ protected void interruptEventloop() { }
/** Do the background tasks that need to be done in
* the main thread.
Index: gzz/gzz/client/gl/GLUpdateManager.java
diff -u gzz/gzz/client/gl/GLUpdateManager.java:1.10
gzz/gzz/client/gl/GLUpdateManager.java:1.11
--- gzz/gzz/client/gl/GLUpdateManager.java:1.10 Fri Jan 10 13:44:51 2003
+++ gzz/gzz/client/gl/GLUpdateManager.java Sat Jan 18 09:53:09 2003
@@ -30,7 +30,7 @@
import java.util.*;
public class GLUpdateManager extends AbstractUpdateManager {
-public static final String rcsid = "$Id: GLUpdateManager.java,v 1.10
2003/01/10 18:44:51 tjl Exp $";
+public static final String rcsid = "$Id: GLUpdateManager.java,v 1.11
2003/01/18 14:53:09 tjl Exp $";
private static boolean dbg = false;
private static void p(String s) { if(dbg) pa(s); }
private static void pa(String s) { System.err.println(s); }
@@ -57,5 +57,9 @@
if(super.doIdle()) return true;
GL.freeQueue();
return false;
+ }
+
+ protected void interruptEventloop() {
+ GL.interruptEventloop();
}
}
Index: gzz/gzz/gfx/gl/GL.java
diff -u gzz/gzz/gfx/gl/GL.java:1.41 gzz/gzz/gfx/gl/GL.java:1.42
--- gzz/gzz/gfx/gl/GL.java:1.41 Fri Jan 17 09:37:17 2003
+++ gzz/gzz/gfx/gl/GL.java Sat Jan 18 09:53:09 2003
@@ -264,8 +264,6 @@
private Window(int id) { super(id); }
- // XXX ???
- public void repaint() { GL.repaintWindow(getId()); }
/** Call the EventHandler.timeout(id) with the given id,
* after at least ms milliseconds have passed.
@@ -291,8 +289,6 @@
static private native int createWindowImpl(int x, int y, int w, int h,
EventHandler eh);
static private native void deleteWindow(int i);
- static private native void repaintWindow(int id);
-
static private native void getWindowSize(int id, Rectangle into);
static private native void addTimeoutWindow(int id, int ms, int tid);
@@ -825,6 +821,12 @@
* for the next native event.
*/
public static native void eventLoop(boolean wait);
+ /** Interrupt the event loop.
+ * Unlike most functions in GL, this can be called from other threads
+ * to interrup a waiting event loop at any time.
+ * This is useful as a response e.g. for incoming network data.
+ */
+ public static native void interruptEventloop();
public static native void setDebugVar(String name, int value);
- [Gzz-commits] gzz gfx/jni/GzzGL-jni.cxx gfx/libos/Os-GLX.cxx ...,
Tuomas J. Lukka <=