diff options
author | Sven Gothel <[email protected]> | 2011-08-25 00:01:07 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-08-25 00:01:07 +0200 |
commit | 66f8b612106d0a462d1a6382409fce0ad692f746 (patch) | |
tree | 53dfce1f84d6d76b3cc49203867f01a9b872453a | |
parent | b8b25bb01b826e1216551c8f3d192bcec670e265 (diff) |
NEWT/X11 XCB testxcb-test
-rw-r--r-- | make/build-newt.xml | 4 | ||||
-rwxr-xr-x | make/scripts/tests.sh | 6 | ||||
-rw-r--r-- | src/newt/native/AndroidWindow.c | 2 | ||||
-rw-r--r-- | src/newt/native/X11Window.c | 327 | ||||
-rw-r--r-- | src/newt/native/X11Window.h | 54 | ||||
-rw-r--r-- | src/newt/native/X11WindowX11Event.c | 273 | ||||
-rw-r--r-- | src/newt/native/X11WindowX11Event.h | 9 | ||||
-rw-r--r-- | src/newt/native/X11WindowXCBEvent.c | 317 | ||||
-rw-r--r-- | src/newt/native/X11WindowXCBEvent.h | 10 |
9 files changed, 702 insertions, 300 deletions
diff --git a/make/build-newt.xml b/make/build-newt.xml index 74263e456..38e5622fd 100644 --- a/make/build-newt.xml +++ b/make/build-newt.xml @@ -269,6 +269,8 @@ <syslibset libs="X11"/> <syslibset libs="Xrandr"/> <syslibset libs="Xxf86vm" /> + <syslibset libs="X11-xcb" /> + <syslibset libs="xcb" /> </linker> <linker id="linker.cfg.linux.armv7.newt.x11" extends="linker.cfg.linux.armv7"> @@ -469,7 +471,7 @@ <include name="${rootrel.src.c}/WindowsWindow.c" if="isWindows"/> <include name="${rootrel.src.c}/*.m" if="isOSX"/> <include name="${rootrel.src.c}/AndroidWindow.c" if="isAndroid"/> - <include name="${rootrel.src.c}/X11Window.c" if="isX11"/> + <include name="${rootrel.src.c}/X11Window*.c" if="isX11"/> <include name="${rootrel.src.c}/KDWindow.c" if="setup.addNativeKD"/> <include name="${rootrel.src.c}/IntelGDL.c" if="setup.addNativeIntelGDL"/> <include name="${rootrel.src.c}/BroadcomEGL.c" if="setup.addNativeBroadcomEGL"/> diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 5ba1c6e0e..7aa8ba185 100755 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -77,7 +77,7 @@ function jrun() { #D_ARGS="-Djogl.debug.GraphicsConfiguration" #D_ARGS="-Djogl.debug.GLCanvas -Djogl.debug.GraphicsConfiguration" #D_ARGS="-Djogl.debug.GLCanvas" - D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.GLDebugMessageHandler -Djogl.debug.GLSLCode" + D_ARGS="-Dnativewindow.x11.mt-bug=true -Djogl.debug.DebugGL -Djogl.debug.GLDebugMessageHandler -Djogl.debug.GLSLCode" #D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL" #D_ARGS="-Djogl.debug.GLDebugMessageHandler -Dnewt.debug.Window -Dnewt.debug.Display -Dnewt.debug.EDT" #D_ARGS="-Djogl.debug.GLDebugMessageHandler" @@ -143,7 +143,7 @@ function testawtmt() { #testawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT $* -#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* +testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $* #testnoawt com.jogamp.opengl.test.junit.newt.TestGLWindows02NEWTAnimated $* #testawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT #testawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle02NEWT @@ -152,7 +152,7 @@ function testawtmt() { #testawt com.jogamp.opengl.test.junit.newt.TestScreenMode00NEWT #testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode01NEWT #testnoawt com.jogamp.opengl.test.junit.newt.TestScreenMode02NEWT -testnoawt com.jogamp.opengl.test.junit.newt.ManualScreenMode03NEWT +#testnoawt com.jogamp.opengl.test.junit.newt.ManualScreenMode03NEWT #testawt com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT -time 1000000 #testawt -Djava.awt.headless=true com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT #testnoawt com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn $* diff --git a/src/newt/native/AndroidWindow.c b/src/newt/native/AndroidWindow.c index 5eca96fc2..52281fdf9 100644 --- a/src/newt/native/AndroidWindow.c +++ b/src/newt/native/AndroidWindow.c @@ -14,7 +14,7 @@ #include <android/native_window.h> #include <android/native_window_jni.h> -#define VERBOSE_ON 1 +// #define VERBOSE_ON 1 #ifdef VERBOSE_ON #define DBG_PRINT(...) fprintf(stdout, __VA_ARGS__) diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index e0efac6e5..bfcb97628 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -32,19 +32,11 @@ * */ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stdarg.h> - -#include <gluegen_stdint.h> +// #define VERBOSE_ON 1 -#include <unistd.h> -#include <errno.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/keysym.h> -#include <X11/Xatom.h> +#include "X11Window.h" +#include "X11WindowX11Event.h" +#include "X11WindowXCBEvent.h" #include <X11/extensions/Xrandr.h> @@ -60,10 +52,9 @@ #include "NewtCommon.h" -// #define VERBOSE_ON 1 +#include "X11Window.h" #ifdef VERBOSE_ON - #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) #define DUMP_VISUAL_INFO(a,b) _dumpVisualInfo((a),(b)) @@ -89,8 +80,6 @@ #else - #define DBG_PRINT(...) - #define DUMP_VISUAL_INFO(a,b) #endif @@ -101,7 +90,7 @@ #define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b)) -static jint X11KeySym2NewtVKey(KeySym keySym) { +jint X11KeySym2NewtVKey(KeySym keySym) { if(IS_WITHIN(keySym,XK_F1,XK_F12)) return (keySym-XK_F1)+J_VK_F1; @@ -136,7 +125,7 @@ static jint X11KeySym2NewtVKey(KeySym keySym) { return keySym; } -static jint X11InputState2NewtModifiers(unsigned int xstate) { +jint X11InputState2NewtModifiers(unsigned int xstate) { jint modifiers = 0; if ((ControlMask & xstate) != 0) { modifiers |= EVENT_CTRL_MASK; @@ -164,21 +153,21 @@ static const char * const ClazzNameNewtWindow = "com/jogamp/newt/Window"; static jclass newtWindowClz=NULL; -static jmethodID sizeChangedID = NULL; -static jmethodID positionChangedID = NULL; -static jmethodID focusChangedID = NULL; -static jmethodID visibleChangedID = NULL; -static jmethodID windowDestroyNotifyID = NULL; -static jmethodID windowRepaintID = NULL; -static jmethodID windowReparentedID = NULL; -static jmethodID enqueueMouseEventID = NULL; -static jmethodID sendMouseEventID = NULL; -static jmethodID enqueueKeyEventID = NULL; -static jmethodID sendKeyEventID = NULL; -static jmethodID focusActionID = NULL; -static jmethodID enqueueRequestFocusID = NULL; +jmethodID sizeChangedID = NULL; +jmethodID positionChangedID = NULL; +jmethodID focusChangedID = NULL; +jmethodID visibleChangedID = NULL; +jmethodID windowDestroyNotifyID = NULL; +jmethodID windowRepaintID = NULL; +jmethodID windowReparentedID = NULL; +jmethodID enqueueMouseEventID = NULL; +jmethodID sendMouseEventID = NULL; +jmethodID enqueueKeyEventID = NULL; +jmethodID sendKeyEventID = NULL; +jmethodID focusActionID = NULL; +jmethodID enqueueRequestFocusID = NULL; -static jmethodID displayCompletedID = NULL; +jmethodID displayCompletedID = NULL; /** @@ -197,7 +186,7 @@ static void setupJVMVars(JNIEnv * env) { static XErrorHandler origErrorHandler = NULL ; -static int displayDispatchErrorHandler(Display *dpy, XErrorEvent *e) +static int X11WindowDisplayErrorHandler(Display *dpy, XErrorEvent *e) { fprintf(stderr, "Warning: NEWT X11 Error: DisplayDispatch %p, Code 0x%X, errno %s\n", dpy, e->error_code, strerror(errno)); @@ -239,11 +228,11 @@ static int displayDispatchErrorHandler(Display *dpy, XErrorEvent *e) return 0; } -static void displayDispatchErrorHandlerEnable(int onoff, JNIEnv * env) { +void X11WindowDisplayErrorHandlerEnable(int onoff, JNIEnv * env) { if(onoff) { if(NULL==origErrorHandler) { setupJVMVars(env); - origErrorHandler = XSetErrorHandler(displayDispatchErrorHandler); + origErrorHandler = XSetErrorHandler(X11WindowDisplayErrorHandler); } } else { if(NULL!=origErrorHandler) { @@ -356,7 +345,7 @@ static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlon (unsigned char *)&jogl_java_object_data, nitems_32); } -static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) { +jobject X11WindowGetJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) { Atom actual_type_return; int actual_format_return; int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ; @@ -522,262 +511,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0 (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong wmDeleteAtom) { Display * dpy = (Display *) (intptr_t) display; - int num_events = 100; - - if ( NULL == dpy ) { - return; - } - - // Periodically take a break - while( num_events > 0 ) { - jobject jwindow = NULL; - XEvent evt; - KeySym keySym = 0; - jint modifiers = 0; - char keyChar = 0; - char text[255]; - - // XEventsQueued(dpy, X): - // QueuedAlready : No I/O Flush or system call doesn't work on some cards (eg ATI) ?) - // QueuedAfterFlush == XPending(): I/O Flush only if no already queued events are available - // QueuedAfterReading : QueuedAlready + if queue==0, attempt to read more .. - if ( 0 >= XPending(dpy) ) { - // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy); - return; - } - - XNextEvent(dpy, &evt); - num_events--; - - if( 0==evt.xany.window ) { - NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!"); - return ; - } - - if(dpy!=evt.xany.display) { - NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!"); - return ; - } - - // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type); - - displayDispatchErrorHandlerEnable(1, env); - - jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom, - #ifdef VERBOSE_ON - True - #else - False - #endif - ); - - displayDispatchErrorHandlerEnable(0, env); - - if(NULL==jwindow) { - fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", - (void*)dpy, evt.type, (void*)evt.xany.window); - continue; - } - - switch(evt.type) { - case KeyRelease: - case KeyPress: - if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) { - KeySym lower_return = 0, upper_return = 0; - keyChar=text[0]; - XConvertCase(keySym, &lower_return, &upper_return); - // always return upper case, set modifier masks (SHIFT, ..) - keySym = upper_return; - modifiers = X11InputState2NewtModifiers(evt.xkey.state); - } else { - keyChar=0; - } - break; - - case ButtonPress: - case ButtonRelease: - case MotionNotify: - modifiers = X11InputState2NewtModifiers(evt.xbutton.state); - break; - - default: - break; - } - - switch(evt.type) { - case ButtonPress: - (*env)->CallVoidMethod(env, jwindow, enqueueRequestFocusID, JNI_FALSE); - #ifdef USE_SENDIO_DIRECT - (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, - modifiers, - (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); - #else - (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_PRESSED, - modifiers, - (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); - #endif - break; - case ButtonRelease: - #ifdef USE_SENDIO_DIRECT - (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, - modifiers, - (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); - #else - (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_RELEASED, - modifiers, - (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); - #endif - break; - case MotionNotify: - #ifdef USE_SENDIO_DIRECT - (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, - modifiers, - (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/); - #else - (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_MOVED, - modifiers, - (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/); - #endif - break; - case KeyPress: - #ifdef USE_SENDIO_DIRECT - (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED, - modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar); - #else - (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED, - modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar); - #endif - - break; - case KeyRelease: - #ifdef USE_SENDIO_DIRECT - (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED, - modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar); - - (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED, - modifiers, (jint) -1, (jchar) keyChar); - #else - (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED, - modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar); - - (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED, - modifiers, (jint) -1, (jchar) keyChar); - #endif - - break; - case DestroyNotify: - DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n", - (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event); - if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) { - // ignore child destroy notification - } - break; - case CreateNotify: - DBG_PRINT( "X11: event . CreateNotify call %p, parent %p, child-event: 1\n", - (void*)evt.xcreatewindow.window, (void*) evt.xcreatewindow.parent); - break; - case ConfigureNotify: - DBG_PRINT( "X11: event . ConfigureNotify call %p (parent %p, above %p) %d/%d %dx%d %d, child-event: %d\n", - (void*)evt.xconfigure.window, (void*)evt.xconfigure.event, (void*)evt.xconfigure.above, - evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height, - evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event); - if ( evt.xconfigure.window == evt.xconfigure.event ) { - // ignore child window change notification - (*env)->CallVoidMethod(env, jwindow, sizeChangedID, - (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE); - (*env)->CallVoidMethod(env, jwindow, positionChangedID, - (jint) evt.xconfigure.x, (jint) evt.xconfigure.y); - } - break; - case ClientMessage: - if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) { - DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X !!!\n", - (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type); - (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID); - // Called by Window.java: CloseWindow(); - num_events = 0; // end loop in case of destroyed display - } - break; - - case FocusIn: - DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window); - (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_TRUE); - break; - - case FocusOut: - DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window); - (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE); - break; - - case Expose: - DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)evt.xexpose.window, - evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height, evt.xexpose.count); - - if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) { - (*env)->CallVoidMethod(env, jwindow, windowRepaintID, - evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height); - } - break; - - case MapNotify: - DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n", - (void*)evt.xmap.event, (void*)evt.xmap.window, (int)evt.xmap.override_redirect, - evt.xmap.event!=evt.xmap.window); - if( evt.xmap.event == evt.xmap.window ) { - // ignore child window notification - (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE); - } - break; - - case UnmapNotify: - DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, from_configure %d, child-event: %d\n", - (void*)evt.xunmap.event, (void*)evt.xunmap.window, (int)evt.xunmap.from_configure, - evt.xunmap.event!=evt.xunmap.window); - if( evt.xunmap.event == evt.xunmap.window ) { - // ignore child window notification - (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE); - } - break; - - case ReparentNotify: - { - jlong parentResult; // 0 if root, otherwise proper value - Window winRoot, winTopParent; - #ifdef VERBOSE_ON - Window oldParentRoot, oldParentTopParent; - Window parentRoot, parentTopParent; - if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.event, &oldParentRoot, &oldParentTopParent) ) { - oldParentRoot=0; oldParentTopParent = 0; - } - if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.parent, &parentRoot, &parentTopParent) ) { - parentRoot=0; parentTopParent = 0; - } - #endif - if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.window, &winRoot, &winTopParent) ) { - winRoot=0; winTopParent = 0; - } - if(evt.xreparent.parent == winRoot) { - parentResult = 0; // our java indicator for root window - } else { - parentResult = (jlong) (intptr_t) evt.xreparent.parent; - } - #ifdef VERBOSE_ON - DBG_PRINT( "X11: event . ReparentNotify: call OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n", - (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent, - (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent, - (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent); - #endif - - (*env)->CallVoidMethod(env, jwindow, windowReparentedID, parentResult); - } - break; - - // unhandled events .. yet .. - - default: - DBG_PRINT("X11: event . unhandled %d 0x%X call %p\n", (int)evt.type, (unsigned int)evt.type, (void*)evt.xunmap.window); - } - } + // X11WindowX11EventPoll(env, obj, dpy, javaObjectAtom, wmDeleteAtom); + X11WindowXCBEventPoll(env, obj, dpy, javaObjectAtom, wmDeleteAtom); } @@ -1297,6 +1032,8 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0 NewtCommon_FatalError(env, "invalid display connection.."); } + X11WindowXCBSetEventQueueOwner(dpy); + if(visualID<0) { NewtCommon_throwNewRuntimeException(env, "invalid VisualID .."); return 0; @@ -1406,7 +1143,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_CloseWindow0 DBG_PRINT( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w); - jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom, True); + jwindow = X11WindowGetJavaWindowProperty(env, dpy, w, javaObjectAtom, True); if(NULL==jwindow) { NewtCommon_throwNewRuntimeException(env, "could not fetch Java Window object, bail out!"); return; @@ -1492,7 +1229,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0 Window topParentWindow; Bool moveIntoParent = False; - displayDispatchErrorHandlerEnable(1, env); + X11WindowDisplayErrorHandlerEnable(1, env); topParentParent = NewtWindows_getParent (dpy, parent); topParentWindow = NewtWindows_getParent (dpy, w); @@ -1538,7 +1275,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0 XSync(dpy, False); } - displayDispatchErrorHandlerEnable(0, env); + X11WindowDisplayErrorHandlerEnable(0, env); DBG_PRINT( "X11: reconfigureWindow0 X\n"); } diff --git a/src/newt/native/X11Window.h b/src/newt/native/X11Window.h new file mode 100644 index 000000000..052f8ae48 --- /dev/null +++ b/src/newt/native/X11Window.h @@ -0,0 +1,54 @@ + +#ifndef _X11Window_h +#define _X11Window_h + +#include <jni.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#include <gluegen_stdint.h> + +#include <unistd.h> +#include <errno.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <X11/Xatom.h> + +#ifdef VERBOSE_ON + + #define VERBOSE_BOOL True + #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) + +#else + + #define VERBOSE_BOOL False + #define DBG_PRINT(...) + +#endif + +extern jmethodID sizeChangedID; +extern jmethodID positionChangedID; +extern jmethodID focusChangedID; +extern jmethodID visibleChangedID; +extern jmethodID windowDestroyNotifyID; +extern jmethodID windowRepaintID; +extern jmethodID windowReparentedID; +extern jmethodID enqueueMouseEventID; +extern jmethodID sendMouseEventID; +extern jmethodID enqueueKeyEventID; +extern jmethodID sendKeyEventID; +extern jmethodID focusActionID; +extern jmethodID enqueueRequestFocusID; +extern jmethodID displayCompletedID; + +extern jint X11InputState2NewtModifiers(unsigned int xstate); +extern jint X11KeySym2NewtVKey(KeySym keySym); + +extern void X11WindowDisplayErrorHandlerEnable(int onoff, JNIEnv * env); + +extern jobject X11WindowGetJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning); + +#endif /* _X11Window_h */ diff --git a/src/newt/native/X11WindowX11Event.c b/src/newt/native/X11WindowX11Event.c new file mode 100644 index 000000000..272cb0bd8 --- /dev/null +++ b/src/newt/native/X11WindowX11Event.c @@ -0,0 +1,273 @@ + +#include "X11Window.h" +#include "X11WindowX11Event.h" + +#include "MouseEvent.h" +#include "InputEvent.h" +#include "KeyEvent.h" +#include "WindowEvent.h" +#include "ScreenMode.h" + +#include "NewtCommon.h" + + +void X11WindowX11EventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong wmDeleteAtom) { + int num_events = 100; + + if ( NULL == dpy ) { + return; + } + + // Periodically take a break + while( num_events > 0 ) { + jobject jwindow = NULL; + XEvent evt; + KeySym keySym = 0; + jint modifiers = 0; + char keyChar = 0; + char text[255]; + + // XEventsQueued(dpy, X): + // QueuedAlready : No I/O Flush or system call doesn't work on some cards (eg ATI) ?) + // QueuedAfterFlush == XPending(): I/O Flush only if no already queued events are available + // QueuedAfterReading : QueuedAlready + if queue==0, attempt to read more .. + if ( 0 >= XPending(dpy) ) { + // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy); + return; + } + + XNextEvent(dpy, &evt); + num_events--; + + if( 0==evt.xany.window ) { + NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!"); + return ; + } + + if(dpy!=evt.xany.display) { + NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!"); + return ; + } + + // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type); + + X11WindowDisplayErrorHandlerEnable(1, env); + + jwindow = X11WindowGetJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom, + #ifdef VERBOSE_ON + True + #else + False + #endif + ); + + X11WindowDisplayErrorHandlerEnable(0, env); + + if(NULL==jwindow) { + fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", + (void*)dpy, evt.type, (void*)evt.xany.window); + continue; + } + + switch(evt.type) { + case KeyRelease: + case KeyPress: + if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) { + KeySym lower_return = 0, upper_return = 0; + keyChar=text[0]; + XConvertCase(keySym, &lower_return, &upper_return); + // always return upper case, set modifier masks (SHIFT, ..) + keySym = upper_return; + modifiers = X11InputState2NewtModifiers(evt.xkey.state); + } else { + keyChar=0; + } + break; + + case ButtonPress: + case ButtonRelease: + case MotionNotify: + modifiers = X11InputState2NewtModifiers(evt.xbutton.state); + break; + + default: + break; + } + + switch(evt.type) { + case ButtonPress: + (*env)->CallVoidMethod(env, jwindow, enqueueRequestFocusID, JNI_FALSE); + #ifdef USE_SENDIO_DIRECT + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, + modifiers, + (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); + #else + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_PRESSED, + modifiers, + (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); + #endif + break; + case ButtonRelease: + #ifdef USE_SENDIO_DIRECT + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, + modifiers, + (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); + #else + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_RELEASED, + modifiers, + (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); + #endif + break; + case MotionNotify: + #ifdef USE_SENDIO_DIRECT + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, + modifiers, + (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/); + #else + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_MOVED, + modifiers, + (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/); + #endif + break; + case KeyPress: + #ifdef USE_SENDIO_DIRECT + (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED, + modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar); + #else + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED, + modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar); + #endif + + break; + case KeyRelease: + #ifdef USE_SENDIO_DIRECT + (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED, + modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar); + + (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED, + modifiers, (jint) -1, (jchar) keyChar); + #else + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED, + modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar); + + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED, + modifiers, (jint) -1, (jchar) keyChar); + #endif + + break; + case DestroyNotify: + DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n", + (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event); + if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) { + // ignore child destroy notification + } + break; + case CreateNotify: + DBG_PRINT( "X11: event . CreateNotify call %p, parent %p, child-event: 1\n", + (void*)evt.xcreatewindow.window, (void*) evt.xcreatewindow.parent); + break; + case ConfigureNotify: + DBG_PRINT( "X11: event . ConfigureNotify call %p (parent %p, above %p) %d/%d %dx%d %d, child-event: %d\n", + (void*)evt.xconfigure.window, (void*)evt.xconfigure.event, (void*)evt.xconfigure.above, + evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height, + evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event); + if ( evt.xconfigure.window == evt.xconfigure.event ) { + // ignore child window change notification + (*env)->CallVoidMethod(env, jwindow, sizeChangedID, + (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE); + (*env)->CallVoidMethod(env, jwindow, positionChangedID, + (jint) evt.xconfigure.x, (jint) evt.xconfigure.y); + } + break; + case ClientMessage: + if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) { + DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X !!!\n", + (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type); + (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID); + // Called by Window.java: CloseWindow(); + num_events = 0; // end loop in case of destroyed display + } + break; + + case FocusIn: + DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window); + (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_TRUE); + break; + + case FocusOut: + DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window); + (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE); + break; + + case Expose: + DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)evt.xexpose.window, + evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height, evt.xexpose.count); + + if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) { + (*env)->CallVoidMethod(env, jwindow, windowRepaintID, + evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height); + } + break; + + case MapNotify: + DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n", + (void*)evt.xmap.event, (void*)evt.xmap.window, (int)evt.xmap.override_redirect, + evt.xmap.event!=evt.xmap.window); + if( evt.xmap.event == evt.xmap.window ) { + // ignore child window notification + (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE); + } + break; + + case UnmapNotify: + DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, from_configure %d, child-event: %d\n", + (void*)evt.xunmap.event, (void*)evt.xunmap.window, (int)evt.xunmap.from_configure, + evt.xunmap.event!=evt.xunmap.window); + if( evt.xunmap.event == evt.xunmap.window ) { + // ignore child window notification + (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE); + } + break; + + case ReparentNotify: + { + jlong parentResult; // 0 if root, otherwise proper value + Window winRoot, winTopParent; + #ifdef VERBOSE_ON + Window oldParentRoot, oldParentTopParent; + Window parentRoot, parentTopParent; + if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.event, &oldParentRoot, &oldParentTopParent) ) { + oldParentRoot=0; oldParentTopParent = 0; + } + if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.parent, &parentRoot, &parentTopParent) ) { + parentRoot=0; parentTopParent = 0; + } + #endif + if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.window, &winRoot, &winTopParent) ) { + winRoot=0; winTopParent = 0; + } + if(evt.xreparent.parent == winRoot) { + parentResult = 0; // our java indicator for root window + } else { + parentResult = (jlong) (intptr_t) evt.xreparent.parent; + } + #ifdef VERBOSE_ON + DBG_PRINT( "X11: event . ReparentNotify: call OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n", + (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent, + (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent, + (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent); + #endif + + (*env)->CallVoidMethod(env, jwindow, windowReparentedID, parentResult); + } + break; + + // unhandled events .. yet .. + + default: + DBG_PRINT("X11: event . unhandled %d 0x%X call %p\n", (int)evt.type, (unsigned int)evt.type, (void*)evt.xunmap.window); + } + } +} + + diff --git a/src/newt/native/X11WindowX11Event.h b/src/newt/native/X11WindowX11Event.h new file mode 100644 index 000000000..47c0dc9a1 --- /dev/null +++ b/src/newt/native/X11WindowX11Event.h @@ -0,0 +1,9 @@ + +#ifndef _X11WindowX11Event_h +#define _X11WindowX11Event_h + +#include "X11Window.h" + +extern void X11WindowX11EventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong wmDeleteAtom); + +#endif /* _X11WindowX11Event_h */ diff --git a/src/newt/native/X11WindowXCBEvent.c b/src/newt/native/X11WindowXCBEvent.c new file mode 100644 index 000000000..0b0748631 --- /dev/null +++ b/src/newt/native/X11WindowXCBEvent.c @@ -0,0 +1,317 @@ + +#define VERBOSE_ON 1 + +#include "X11Window.h" +#include "X11WindowXCBEvent.h" + +#include <xcb/xcb.h> +#include <xcb/xcb_event.h> +#include <xcb/xproto.h> +#include <xcb/xcb_keysyms.h> +#include <X11/Xlib-xcb.h> + +#include "MouseEvent.h" +#include "InputEvent.h" +#include "KeyEvent.h" +#include "WindowEvent.h" +#include "ScreenMode.h" + +#include "NewtCommon.h" + +void X11WindowXCBSetEventQueueOwner(Display *dpy) { + XSetEventQueueOwner(dpy, XCBOwnsEventQueue); +} + +void X11WindowXCBEventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong wmDeleteAtom) { + int num_events = 100; + xcb_connection_t *conn = NULL; + + if ( NULL == dpy ) { + return; + } + conn = XGetXCBConnection(dpy); + + // Periodically take a break + while( num_events > 0 ) { + jobject jwindow = NULL; + xcb_generic_event_t *evt; + // KeySym keySym = 0; + jint modifiers = 0; + char keyChar = 0; + // char text[255]; + + evt = xcb_poll_for_event(conn); + if(NULL == evt) { + // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy); + return; + } + num_events--; + + /*if( 0==evt.xany.window ) { + free(evt); + NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!"); + return ; + } + + if(dpy!=evt.xany.display) { + free(evt); + NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!"); + return ; + }*/ + + // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type); + + // X11WindowDisplayErrorHandlerEnable(1, env); + + // jwindow = X11WindowGetJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom, VERBOSE_BOOL); + + //X11WindowDisplayErrorHandlerEnable(0, env); + + /*if(NULL==jwindow) { + fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", + (void*)dpy, evt.type, (void*)evt.xany.window); + continue; + }*/ + + uint8_t xcb_event_type = evt->response_type & ~0x80; + xcb_window_t event_window = 0; + + switch( xcb_event_type ) { + case XCB_BUTTON_PRESS: + case XCB_BUTTON_RELEASE: + event_window = ((xcb_button_press_event_t *)evt)->event; + modifiers = X11InputState2NewtModifiers(((xcb_button_press_event_t *)evt)->state); + break; + case XCB_MOTION_NOTIFY: + event_window = ((xcb_motion_notify_event_t *)evt)->event; + break; + case XCB_KEY_PRESS: + case XCB_KEY_RELEASE: { + xcb_key_press_event_t *_evt = (xcb_key_press_event_t *)evt; + event_window = _evt->event; + /* + xcb_keycode_t detail = _evt->detail; + if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) { + KeySym lower_return = 0, upper_return = 0; + keyChar=text[0]; + XConvertCase(keySym, &lower_return, &upper_return); + // always return upper case, set modifier masks (SHIFT, ..) + keySym = upper_return; + modifiers = X11InputState2NewtModifiers(evt.xkey.state); + } else { + keyChar=0; + }*/ + } + break; + case XCB_EXPOSE: + event_window = ((xcb_expose_event_t *)evt)->window; + break; + case XCB_MAP_NOTIFY: + event_window = ((xcb_map_notify_event_t *)evt)->window; + break; + case XCB_UNMAP_NOTIFY: + event_window = ((xcb_unmap_notify_event_t *)evt)->window; + break; + } + if(0==event_window) { + fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d, no X11 window associated\n", + (void*)dpy, xcb_event_type); + continue; + } + jwindow = X11WindowGetJavaWindowProperty(env, dpy, event_window, javaObjectAtom, VERBOSE_BOOL); + if(NULL==jwindow) { + fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", + (void*)(intptr_t)dpy, xcb_event_type, (void*)(intptr_t)event_window); + continue; + } + + switch( xcb_event_type ) { + case XCB_BUTTON_PRESS: { + xcb_button_press_event_t *_evt = (xcb_button_press_event_t *)evt; + (*env)->CallVoidMethod(env, jwindow, enqueueRequestFocusID, JNI_FALSE); + #ifdef USE_SENDIO_DIRECT + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, + modifiers, + (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/); + #else + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_PRESSED, + modifiers, + (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/); + #endif + } break; + case XCB_BUTTON_RELEASE: { + xcb_button_release_event_t *_evt = (xcb_button_release_event_t *)evt; + #ifdef USE_SENDIO_DIRECT + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, + modifiers, + (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/); + #else + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_RELEASED, + modifiers, + (jint) _evt->event_x, (jint) _evt->event_y, (jint) _evt->state, 0 /*rotation*/); + #endif + } break; + case XCB_MOTION_NOTIFY: { + xcb_motion_notify_event_t *_evt = (xcb_motion_notify_event_t *)evt; + #ifdef USE_SENDIO_DIRECT + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, + modifiers, + (jint) _evt->event_x, (jint) _evt->event_y, (jint)0, 0 /*rotation*/); + #else + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_MOVED, + modifiers, + (jint) _evt->event_x, (jint) _evt->event_y, (jint)0, 0 /*rotation*/); + #endif + } break; + case XCB_KEY_PRESS: { + xcb_key_press_event_t *_evt = (xcb_key_press_event_t *)evt; + #ifdef USE_SENDIO_DIRECT + (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED, + modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar); + #else + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED, + modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar); + #endif + } break; + case XCB_KEY_RELEASE: { + xcb_key_release_event_t *_evt = (xcb_key_release_event_t *)evt; + event_window = ((xcb_key_release_event_t *)evt)->event; + #ifdef USE_SENDIO_DIRECT + (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED, + modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar); + + (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED, + modifiers, (jint) -1, (jchar) keyChar); + #else + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED, + modifiers, X11KeySym2NewtVKey(_evt->state), (jchar) keyChar); + + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED, + modifiers, (jint) -1, (jchar) keyChar); + #endif + + } break; + /* + case DestroyNotify: + DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n", + (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event); + if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) { + // ignore child destroy notification + } + break; + case CreateNotify: + DBG_PRINT( "X11: event . CreateNotify call %p, parent %p, child-event: 1\n", + (void*)evt.xcreatewindow.window, (void*) evt.xcreatewindow.parent); + break; + case ConfigureNotify: + DBG_PRINT( "X11: event . ConfigureNotify call %p (parent %p, above %p) %d/%d %dx%d %d, child-event: %d\n", + (void*)evt.xconfigure.window, (void*)evt.xconfigure.event, (void*)evt.xconfigure.above, + evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height, + evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event); + if ( evt.xconfigure.window == evt.xconfigure.event ) { + // ignore child window change notification + (*env)->CallVoidMethod(env, jwindow, sizeChangedID, + (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE); + (*env)->CallVoidMethod(env, jwindow, positionChangedID, + (jint) evt.xconfigure.x, (jint) evt.xconfigure.y); + } + break; + case ClientMessage: + if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) { + DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X !!!\n", + (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type); + (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID); + // Called by Window.java: CloseWindow(); + num_events = 0; // end loop in case of destroyed display + } + break; + + case FocusIn: + DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window); + (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_TRUE); + break; + + case FocusOut: + DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window); + (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE); + break; + */ + + case XCB_EXPOSE: { + xcb_expose_event_t *_evt = (xcb_expose_event_t *)evt; + DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)(intptr_t)_evt->window, + _evt->x, _evt->y, _evt->width, _evt->height, _evt->count); + + if (_evt->count == 0 && _evt->width > 0 && _evt->height > 0) { + (*env)->CallVoidMethod(env, jwindow, windowRepaintID, + _evt->x, _evt->y, _evt->width, _evt->height); + } + } break; + + case XCB_MAP_NOTIFY: { + xcb_map_notify_event_t *_evt = (xcb_map_notify_event_t *)evt; + DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n", + (void*)(intptr_t)_evt->event, (void*)(intptr_t)_evt->window, (int)_evt->override_redirect, + _evt->event!=_evt->window); + if( _evt->event == _evt->window ) { + // ignore child window notification + (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE); + } + } break; + + case XCB_UNMAP_NOTIFY: { + xcb_unmap_notify_event_t *_evt = (xcb_unmap_notify_event_t *)evt; + DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, child-event: %d\n", + (void*)(intptr_t)_evt->event, (void*)(intptr_t)_evt->window, + _evt->event!=_evt->window); + if( _evt->event == _evt->window ) { + // ignore child window notification + (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE); + } + } break; + /* + + case ReparentNotify: + { + jlong parentResult; // 0 if root, otherwise proper value + Window winRoot, winTopParent; + #ifdef VERBOSE_ON + Window oldParentRoot, oldParentTopParent; + Window parentRoot, parentTopParent; + if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.event, &oldParentRoot, &oldParentTopParent) ) { + oldParentRoot=0; oldParentTopParent = 0; + } + if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.parent, &parentRoot, &parentTopParent) ) { + parentRoot=0; parentTopParent = 0; + } + #endif + if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.window, &winRoot, &winTopParent) ) { + winRoot=0; winTopParent = 0; + } + if(evt.xreparent.parent == winRoot) { + parentResult = 0; // our java indicator for root window + } else { + parentResult = (jlong) (intptr_t) evt.xreparent.parent; + } + #ifdef VERBOSE_ON + DBG_PRINT( "X11: event . ReparentNotify: call OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n", + (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent, + (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent, + (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent); + #endif + + (*env)->CallVoidMethod(env, jwindow, windowReparentedID, parentResult); + } + break; + */ + + // unhandled events .. yet .. + + default: + DBG_PRINT("XCB: event . unhandled %d 0x%X call %p\n", (int)xcb_event_type, (unsigned int)xcb_event_type, (void*)(intptr_t)event_window); + } + free(evt); + } +} + + diff --git a/src/newt/native/X11WindowXCBEvent.h b/src/newt/native/X11WindowXCBEvent.h new file mode 100644 index 000000000..51256b807 --- /dev/null +++ b/src/newt/native/X11WindowXCBEvent.h @@ -0,0 +1,10 @@ + +#ifndef _X11WindowXCBEvent_h +#define _X11WindowXCBEvent_h + +#include "X11Window.h" + +extern void X11WindowXCBSetEventQueueOwner(Display *dpy); +extern void X11WindowXCBEventPoll(JNIEnv *env, jobject obj, Display *dpy, jlong javaObjectAtom, jlong wmDeleteAtom); + +#endif /* _XCBWindowXCBEvent_h */ |