summaryrefslogtreecommitdiffstats
path: root/src/newt/native/X11Window.c
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2009-10-10 04:24:26 -0700
committerSven Gothel <[email protected]>2009-10-10 04:24:26 -0700
commit2268a6ce8a900ae7aa9f20d5f595f811185574a9 (patch)
treeb4426ed20e1957bd5cba095d5a036df2bbc1736a /src/newt/native/X11Window.c
parent20c6d89bfc4f72144b8bcc48839da7ef9bc40681 (diff)
NEWT: Add EventDispatchThread (EDT) pattern.
Due to limitations on Windows, we need to standardize the one thread for - window creation, and - event dispatching This was already mentioned in the previous implementation but while integrating into another threading model (Plugin3), it turned out that manual managing the thread is too much of a burden. NEWT now uses a EDT per Display and Thread as the default, where Display creation, Window creation and event dispatching is 'pipelined' into. This can be switched off: NewtFactory.setUseEDT(boolean onoff); and queried via: NewtFactory.useEDT(); Note this EDT impl. does not implicate a global lock or whatsoever. The experimantal semantics of a current GL context for input event dispatching is removed, i.e. the GL context is no more made current for mouse/key listener. This reduces the complexity and allows the proper impl. of the external dispatch via EDT .. for example. Removed: GLWindow: setEventHandlerMode(int) .. etc X11Display: XLockDisplay/XUnlockDisplay needed to be utilized to allow the new multithreading (EDT/Render) Display usage. X11Window: lockSurface/unlockSurface locks X11Display as well .. +++++ NEWT: 'getSurfaceHandle()' semantics changed. To allow usage of the surfaceHandle for OS where it is allocated thread local (MS-Windows), it shall be aquired/released while lockSurface/unlockSurface. This is done in the Windows Window implementation. GLWindow can no more query 'getSurfaceHandle()' to verify if 'setRealized()' was successful. NEWT: Window surface lock is recursive and blocking now, as it shall be.
Diffstat (limited to 'src/newt/native/X11Window.c')
-rwxr-xr-xsrc/newt/native/X11Window.c171
1 files changed, 140 insertions, 31 deletions
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 0242678d1..097d68cca 100755
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -166,11 +166,15 @@ static jmethodID sendKeyEventID = NULL;
static jmethodID displayCompletedID = NULL;
-static void _throwNewRuntimeException(JNIEnv *env, const char* msg, ...)
+static void _throwNewRuntimeException(Display * unlockDisplay, JNIEnv *env, const char* msg, ...)
{
char buffer[512];
va_list ap;
+ if(NULL!=unlockDisplay) {
+ XUnlockDisplay(unlockDisplay);
+ }
+
va_start(ap, msg);
vsnprintf(buffer, sizeof(buffer), msg, ap);
va_end(ap);
@@ -192,6 +196,10 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Display_initIDs
{
jclass c;
+ if( 0 == XInitThreads() ) {
+ fprintf(stderr, "Warning: XInitThreads() failed\n");
+ }
+
displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
if (displayCompletedID == NULL) {
return JNI_FALSE;
@@ -228,6 +236,37 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Display_initIDs
return JNI_TRUE;
}
+/*
+ * Class: com_sun_javafx_newt_x11_X11Display
+ * Method: LockDisplay
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_LockDisplay
+ (JNIEnv *env, jobject obj, jlong display)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ if(dpy==NULL) {
+ _throwNewRuntimeException(NULL, env, "given display connection is NULL\n");
+ }
+ XLockDisplay(dpy) ;
+}
+
+
+/*
+ * Class: com_sun_javafx_newt_x11_X11Display
+ * Method: UnlockDisplay
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_UnlockDisplay
+ (JNIEnv *env, jobject obj, jlong display)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ if(dpy==NULL) {
+ _throwNewRuntimeException(NULL, env, "given display connection is NULL\n");
+ }
+ XUnlockDisplay(dpy) ;
+}
+
/*
* Class: com_sun_javafx_newt_x11_X11Display
@@ -240,22 +279,27 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_CompleteDisplay
Display * dpy = (Display *)(intptr_t)display;
jlong javaObjectAtom;
jlong windowDeleteAtom;
+
if(dpy==NULL) {
- _throwNewRuntimeException(env, "given display connection is NULL\n");
+ _throwNewRuntimeException(NULL, env, "given display connection is NULL\n");
}
+ XLockDisplay(dpy) ;
javaObjectAtom = (jlong) XInternAtom(dpy, "JOGL_JAVA_OBJECT", False);
if(None==javaObjectAtom) {
- _throwNewRuntimeException(env, "could not create Atom JOGL_JAVA_OBJECT, bail out!\n");
+ _throwNewRuntimeException(dpy, env, "could not create Atom JOGL_JAVA_OBJECT, bail out!\n");
return;
}
windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
if(None==windowDeleteAtom) {
- _throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!\n");
+ _throwNewRuntimeException(dpy, env, "could not create Atom WM_DELETE_WINDOW, bail out!\n");
return;
}
+ // XSetCloseDownMode(dpy, RetainTemporary); // Just a try ..
+ XUnlockDisplay(dpy) ;
+
DBG_PRINT1("X11: X11Display_completeDisplay dpy %p\n", dpy);
(*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom);
@@ -285,7 +329,8 @@ static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlon
{
jobject test = (jobject) getPtrOut32Long(jogl_java_object_data);
if( ! (jwindow==test) ) {
- _throwNewRuntimeException(env, "Internal Error .. Encoded Window ref not the same %p != %p !\n", jwindow, test);
+ _throwNewRuntimeException(dpy, env, "Internal Error .. Encoded Window ref not the same %p != %p !\n", jwindow, test);
+ return;
}
}
@@ -311,24 +356,25 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j
&nitems_return, &bytes_after_return, &jogl_java_object_data_pp);
if ( Success != res ) {
- _throwNewRuntimeException(env, "could not fetch Atom JOGL_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, bail out!\n",
+ _throwNewRuntimeException(dpy, env, "could not fetch Atom JOGL_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, bail out!\n",
res, nitems_return, bytes_after_return);
return NULL;
}
if(actual_type_return!=(Atom)javaObjectAtom || nitems_return<nitems_32 || NULL==jogl_java_object_data_pp) {
XFree(jogl_java_object_data_pp);
- _throwNewRuntimeException(env, "could not fetch Atom JOGL_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, actual_type_return %ld, JOGL_JAVA_OBJECT %ld, bail out!\n",
+ _throwNewRuntimeException(dpy, env, "could not fetch Atom JOGL_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, actual_type_return %ld, JOGL_JAVA_OBJECT %ld, bail out!\n",
res, nitems_return, bytes_after_return, (long)actual_type_return, javaObjectAtom);
return NULL;
}
}
+
jwindow = (jobject) getPtrOut32Long( (unsigned long *) jogl_java_object_data_pp ) ;
XFree(jogl_java_object_data_pp);
#ifdef VERBOSE_ON
if(JNI_FALSE == (*env)->IsInstanceOf(env, jwindow, newtWindowClz)) {
- _throwNewRuntimeException(env, "fetched Atom JOGL_JAVA_OBJECT window is not a NEWT Window: javaWindow 0x%X !\n", jwindow);
+ _throwNewRuntimeException(NULL, env, "fetched Atom JOGL_JAVA_OBJECT window is not a NEWT Window: javaWindow 0x%X !\n", jwindow);
}
#endif
return jwindow;
@@ -343,10 +389,24 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_DispatchMessages
(JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong wmDeleteAtom)
{
Display * dpy = (Display *) (intptr_t) display;
- int num_events = 0;
+ int num_events = 100;
+
+ if ( NULL == dpy ) {
+ return;
+ }
// Periodically take a break
- while( num_events<100 && XPending(dpy)>0 ) {
+ while( num_events > 0 ) {
+
+ XLockDisplay(dpy) ;
+
+ // num_events = XPending(dpy); // XEventsQueued(dpy, QueuedAfterFlush); // I/O Flush ..
+ // num_events = XEventsQueued(dpy, QueuedAlready); // Better, no I/O ..
+ if ( 0 >= XEventsQueued(dpy, QueuedAlready) ) {
+ XUnlockDisplay(dpy) ;
+ return;
+ }
+
jobject jwindow = NULL;
XEvent evt;
KeySym keySym;
@@ -354,23 +414,41 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_DispatchMessages
char text[255];
XNextEvent(dpy, &evt);
- num_events++;
+ num_events--;
if( 0==evt.xany.window ) {
- _throwNewRuntimeException(env, "event window NULL, bail out!\n");
+ _throwNewRuntimeException(dpy, env, "event window NULL, bail out!\n");
+ return ;
}
if(dpy!=evt.xany.display) {
- _throwNewRuntimeException(env, "wrong display");
- continue;
+ _throwNewRuntimeException(dpy, env, "wrong display, bail out!\n");
+ return ;
}
jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom);
+
if(NULL==jwindow) {
// just leave .. _throwNewRuntimeException(env, "could not fetch Java Window object, bail out!\n");
+ XUnlockDisplay(dpy) ;
return;
}
switch(evt.type) {
+ case KeyRelease:
+ case KeyPress:
+ if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
+ keyChar=text[0];
+ } else {
+ keyChar=0;
+ }
+ break;
+ default:
+ break;
+ }
+
+ XUnlockDisplay(dpy) ;
+
+ switch(evt.type) {
case ButtonPress:
(*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED,
(jint) evt.xbutton.state,
@@ -387,21 +465,11 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_DispatchMessages
(jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
break;
case KeyPress:
- if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
- keyChar=text[0];
- } else {
- keyChar=0;
- }
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
(jint) evt.xkey.state,
X11KeySym2NewtVKey(keySym), (jchar) keyChar);
break;
case KeyRelease:
- if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
- keyChar=text[0];
- } else {
- keyChar=0;
- }
(*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
(jint) evt.xkey.state,
X11KeySym2NewtVKey(keySym), (jchar) keyChar);
@@ -456,7 +524,7 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_DispatchMessages
default:
DBG_PRINT3("X11: event . unhandled %d 0x%X call 0x%X\n", evt.type, evt.type, evt.xunmap.window);
}
- }
+ }
}
@@ -474,10 +542,13 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Screen_GetScreen
{
Display * dpy = (Display *)(intptr_t)display;
Screen * scrn= NULL;
+
if(dpy==NULL) {
- fprintf(stderr, "[GetScreen] invalid display connection..\n");
+ _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
return 0;
}
+ XLockDisplay(dpy);
+
scrn = ScreenOfDisplay(dpy,screen_index);
if(scrn==NULL) {
scrn=DefaultScreenOfDisplay(dpy);
@@ -485,6 +556,7 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Screen_GetScreen
if(scrn==NULL) {
fprintf(stderr, "couldn't get screen ..\n");
}
+ XUnlockDisplay(dpy) ;
return (jlong) (intptr_t) scrn;
}
@@ -564,15 +636,17 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow
DBG_PRINT4( "X11: CreateWindow %x/%d %dx%d\n", x, y, width, height);
if(dpy==NULL) {
- fprintf(stderr, "[CreateWindow] invalid display connection..\n");
+ _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
return 0;
}
if(visualID<0) {
- fprintf(stderr, "[CreateWindow] invalid VisualID ..\n");
+ _throwNewRuntimeException(NULL, env, "invalid VisualID ..\n");
return 0;
}
+ XLockDisplay(dpy) ;
+
XSync(dpy, False);
scrn = ScreenOfDisplay(dpy, screen_index);
@@ -594,7 +668,7 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow
if (visual==NULL)
{
- _throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!\n");
+ _throwNewRuntimeException(dpy, env, "could not query Visual by given VisualID, bail out!\n");
return 0;
}
@@ -652,6 +726,8 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow
*/
}
+ XUnlockDisplay(dpy) ;
+
DBG_PRINT2( "X11: [CreateWindow] created window %p on display %p\n", window, dpy);
(*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) window);
@@ -670,13 +746,20 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_CloseWindow
Window w = (Window)window;
jobject jwindow;
+ if(dpy==NULL) {
+ _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
+ return;
+ }
+ XLockDisplay(dpy) ;
+
jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom);
if(NULL==jwindow) {
- _throwNewRuntimeException(env, "could not fetch Java Window object, bail out!\n");
+ _throwNewRuntimeException(dpy, env, "could not fetch Java Window object, bail out!\n");
return;
}
if ( JNI_FALSE == (*env)->IsSameObject(env, jwindow, obj) ) {
- _throwNewRuntimeException(env, "Internal Error .. Window global ref not the same!\n");
+ _throwNewRuntimeException(dpy, env, "Internal Error .. Window global ref not the same!\n");
+ return;
}
(*env)->DeleteGlobalRef(env, jwindow);
@@ -690,6 +773,9 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_CloseWindow
XSync(dpy, False);
XDestroyWindow(dpy, w);
XSync(dpy, False);
+
+ XUnlockDisplay(dpy) ;
+
(*env)->CallVoidMethod(env, obj, windowDestroyedID);
}
@@ -704,6 +790,13 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setVisible0
Display * dpy = (Display *) (intptr_t) display;
Window w = (Window)window;
DBG_PRINT1( "X11: setVisible0 vis %d\n", visible);
+
+ if(dpy==NULL) {
+ _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
+ return;
+ }
+ XLockDisplay(dpy) ;
+
XSync(dpy, False);
if(visible==JNI_TRUE) {
XMapRaised(dpy, w);
@@ -720,6 +813,7 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setVisible0
XUnmapWindow(dpy, w);
XSync(dpy, False);
}
+ XUnlockDisplay(dpy) ;
}
#define MWM_FULLSCREEN 1
@@ -746,6 +840,12 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setSize0
DBG_PRINT6( "X11: setSize0 %d/%d %dx%d, dec %d, vis %d\n", x, y, width, height, decorationToggle, setVisible);
+ if(dpy==NULL) {
+ _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
+ return;
+ }
+ XLockDisplay(dpy) ;
+
XSync(dpy, False);
if(setVisible==JNI_TRUE) {
@@ -784,6 +884,7 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setSize0
XReparentWindow( dpy, w, parent, x, y );
XSync(dpy, False);
+ XUnlockDisplay(dpy) ;
}
/*
@@ -799,9 +900,17 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setPosition0
XWindowChanges xwc;
DBG_PRINT2( "X11: setPos0 . XConfigureWindow %d/%d\n", x, y);
+ if(dpy==NULL) {
+ _throwNewRuntimeException(NULL, env, "invalid display connection..\n");
+ return;
+ }
+ XLockDisplay(dpy) ;
+
xwc.x=x;
xwc.y=y;
XConfigureWindow(dpy, w, CWX|CWY, &xwc);
XSync(dpy, False);
+
+ XUnlockDisplay(dpy) ;
}