diff options
author | Sven Gothel <[email protected]> | 2009-06-17 13:26:29 +0000 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2009-06-17 13:26:29 +0000 |
commit | a92906bcb4ce4746f291d40a736949ec8476de61 (patch) | |
tree | 49708922895aa07bdc72b0513bb5e90f63ecedb2 /src/newt/native | |
parent | 802288f8964affbda3460eea52df3d241ae3036a (diff) |
- Add: GLProfile.get(name) return default if name=="GL" as well (or if null)
- Add: NEWT pumpMessages/dispatchMessages
- Handled by the Display implementation for all windows
- Windows .. OK
- MacOSX .. OK
- X11 .. OK
- Added Atom Property handling to attach java window object to window
- Removed the eventMask for dispatching messages,
since dispatching is for all windows now.
(Wasn't impl. for all platforms anyways)
- All init static code will funnel in the Display.initSingletion(),
to ensure a proper init order for all platforms.
- Display creation is unique for (name,thread).
Handling a TLS mapping of display-names to Displays.
- GLWindow: autoSwapBufferMode and eventHandlerMode are static members
- Tested with experimental tagged
GLWindow.setRunPumpMessages()/runCurrentThreadPumpMessage(),
1 thread - 4 windows, etc ..
java demos.es2.RedSquare -1thread -onepump -GL2 -GL2 -GL2 -GL2
No benefit ..
However .. the implementation is more correct now,
due to the display/current-thread message pumping.
- Fix: Window.sendMouseEvent() bounds check
- Fix: MacWindow has proper nsView locking now,
local to the window instance. locked in lockSurface
besides general window manipulation.
- Fix: JAWT utilized JAWTUtil.init() to
init libraries - NativeLibLoaderBase.loadNativeWindow("awt")
call was missing. (Visible on MacOSX + AWT)
- Fix: GLXUtil proper locking
- Fix: X11Util proper locking
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@1976 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/newt/native')
-rwxr-xr-x | src/newt/native/KDWindow.c | 252 | ||||
-rw-r--r-- | src/newt/native/MacWindow.m | 195 | ||||
-rwxr-xr-x | src/newt/native/WindowsWindow.c | 210 | ||||
-rwxr-xr-x | src/newt/native/X11Window.c | 530 |
4 files changed, 647 insertions, 540 deletions
diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c index d08d5411c..682edff24 100755 --- a/src/newt/native/KDWindow.c +++ b/src/newt/native/KDWindow.c @@ -81,16 +81,121 @@ #endif #endif -/** - * Window - */ - +#define JOGL_KD_USERDATA_MAGIC 0xDEADBEEF +typedef struct { + long magic; + KDWindow * kdWindow; + jobject javaWindow; +} JOGLKDUserdata; + +static jmethodID windowCreatedID = NULL; static jmethodID sizeChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowDestroyedID = NULL; static jmethodID sendMouseEventID = NULL; static jmethodID sendKeyEventID = NULL; +/** + * Display + */ + +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDDisplay_DispatchMessages + (JNIEnv *env, jobject obj) +{ + const KDEvent * evt; + int numEvents = 0; + + // Periodically take a break + while( numEvents<100 && NULL!=(evt=kdWaitEvent(0)) ) { + KDWindow *kdWindow; + jobject javaWindow; + JOGLKDUserdata * userData = (JOGLKDUserdata *)(intptr_t)evt->userptr; + if(NULL == userData || userData->magic!=JOGL_KD_USERDATA_MAGIC) { + DBG_PRINT( "event unrelated: evt type: 0x%X\n", evt->type); + continue; + } + kdWindow = userData->kdWindow; + javaWindow = userData->javaWindow; + DBG_PRINT( "[DispatchMessages]: userData %p, evt type: 0x%X\n", userData, evt->type); + + numEvents++; + + // FIXME: support resize and window re-positioning events + + switch(evt->type) { + case KD_EVENT_WINDOW_FOCUS: + { + KDboolean hasFocus; + kdGetWindowPropertybv(kdWindow, KD_WINDOWPROPERTY_FOCUS, &hasFocus); + DBG_PRINT( "event window focus : src: %p\n", userData); + } + break; + case KD_EVENT_WINDOW_CLOSE: + { + DBG_PRINT( "event window close : src: %p\n", userData); + (*env)->CallVoidMethod(env, javaWindow, windowDestroyNotifyID); + // Called by Window.java: DestroyWindow(wnd); + // (*env)->CallVoidMethod(env, javaWindow, windowDestroyedID); + } + break; + case KD_EVENT_WINDOWPROPERTY_CHANGE: + { + const KDEventWindowProperty* prop = &evt->data.windowproperty; + switch (prop->pname) { + case KD_WINDOWPROPERTY_SIZE: + { + KDint32 v[2]; + if(!kdGetWindowPropertyiv(kdWindow, KD_WINDOWPROPERTY_SIZE, v)) { + DBG_PRINT( "event window size change : src: %p %dx%d\n", userData, v[0], v[1]); + (*env)->CallVoidMethod(env, javaWindow, sizeChangedID, (jint) v[0], (jint) v[1]); + } else { + DBG_PRINT( "event window size change error: src: %p %dx%d\n", userData, v[0], v[1]); + } + } + break; + case KD_WINDOWPROPERTY_FOCUS: + DBG_PRINT( "event window focus: src: %p\n", userData); + break; + case KD_WINDOWPROPERTY_VISIBILITY: + { + KDboolean visible; + kdGetWindowPropertybv(kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visible); + DBG_PRINT( "event window visibility: src: %p, v:%d\n", userData, visible); + } + break; + default: + break; + } + } + break; + case KD_EVENT_INPUT_POINTER: + { + const KDEventInputPointer* ptr = &(evt->data.inputpointer); + // button idx: evt->data.input.index + // pressed = ev->data.input.value.i + // time = ev->timestamp + if(KD_INPUT_POINTER_SELECT==ptr->index) { + DBG_PRINT( "event mouse click: src: %p, s:%d, (%d,%d)\n", userData, ptr->select, ptr->x, ptr->y); + (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID, + (ptr->select==0) ? (jint) EVENT_MOUSE_RELEASED : (jint) EVENT_MOUSE_PRESSED, + (jint) 0, + (jint) ptr->x, (jint) ptr->y, 1, 0); + } else { + DBG_PRINT( "event mouse: src: %d, s:%p, i:0x%X (%d,%d)\n", userData, ptr->select, ptr->index, ptr->x, ptr->y); + (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, + 0, + (jint) ptr->x, (jint) ptr->y, 0, 0); + } + } + break; + } + } +} + +/** + * Window + */ + JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_kd_KDWindow_initIDs (JNIEnv *env, jclass clazz) { @@ -100,12 +205,14 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_kd_KDWindow_initIDs _wfreopen(TEXT(STDERR_FILE),L"w",stderr); #endif #endif + windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V"); sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); - if (sizeChangedID == NULL || + if (windowCreatedID == NULL || + sizeChangedID == NULL || windowDestroyNotifyID == NULL || windowDestroyedID == NULL || sendMouseEventID == NULL || @@ -118,15 +225,13 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_kd_KDWindow_initIDs } JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_kd_KDWindow_CreateWindow - (JNIEnv *env, jobject obj, jint owner, jlong display, jintArray jAttrs) + (JNIEnv *env, jobject obj, jlong display, jintArray jAttrs) { jint * attrs = NULL; jsize attrsLen; EGLDisplay dpy = (EGLDisplay)(intptr_t)display; KDWindow *window = 0; - DBG_PRINT( "[CreateWindow]: owner %d\n", owner); - if(dpy==NULL) { fprintf(stderr, "[CreateWindow] invalid display connection..\n"); return 0; @@ -143,15 +248,21 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_kd_KDWindow_CreateWindow return 0; } - /* passing the KDWindow instance for the eventuserptr */ - window = kdCreateWindow(dpy, attrs, (void *)(intptr_t)owner); + JOGLKDUserdata * userData = kdMalloc(sizeof(JOGLKDUserdata)); + userData->magic = JOGL_KD_USERDATA_MAGIC; + window = kdCreateWindow(dpy, attrs, (void *)userData); (*env)->ReleaseIntArrayElements(env, jAttrs, attrs, 0); if(NULL==window) { + kdFree(userData); fprintf(stderr, "[CreateWindow] failed: 0x%X\n", kdGetError()); + } else { + userData->javaWindow = (*env)->NewGlobalRef(env, obj); + userData->kdWindow = window; + (*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) (intptr_t) userData); + DBG_PRINT( "[CreateWindow] ok: %p, userdata %p\n", window, userData); } - DBG_PRINT( "[CreateWindow] ok: %p, owner %d\n", window, (void *)(intptr_t)owner); return (jlong) (intptr_t) window; } @@ -171,10 +282,13 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_kd_KDWindow_RealizeWindow } JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_kd_KDWindow_CloseWindow - (JNIEnv *env, jobject obj, jlong window) + (JNIEnv *env, jobject obj, jlong window, jlong juserData) { KDWindow *w = (KDWindow*) (intptr_t) window; + JOGLKDUserdata * userData = (JOGLKDUserdata*) (intptr_t) juserData; int res = kdDestroyWindow(w); + (*env)->DeleteGlobalRef(env, userData->javaWindow); + kdFree(userData); DBG_PRINT( "[CloseWindow] res: %d\n", res); return res; @@ -194,120 +308,6 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_setVisible0 DBG_PRINT( "[setVisible] v=%d\n", visible); } -JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_DispatchMessages - (JNIEnv *env, jobject obj, jint owner, jlong window, jint eventMask) -{ - KDWindow *w = (KDWindow*) (intptr_t) window; - const KDEvent * evt; - - // Periodically take a break - while( NULL!=(evt=kdWaitEvent(0)) ) { - jint src_owner = (jint)(intptr_t)evt->userptr; - if(src_owner != owner) { - DBG_PRINT( "event unrelated: src: %d, caller: %d, evt type: 0x%X\n", src_owner, owner, evt->type); - continue; - } - DBG_PRINT( "[DispatchMessages]: caller %d, evt type: 0x%X\n", owner, evt->type); - - switch(evt->type) { - case KD_EVENT_INPUT_POINTER: - if( ! ( eventMask & EVENT_MOUSE ) ) { - DBG_PRINT( "event mouse ignored: src: %d\n", owner); - continue; - } - break; - /* - case KeyPress: - case KeyRelease: - if( ! ( eventMask & EVENT_KEY ) ) { - DBG_PRINT( "event key ignored: src: %d\n", owner); - continue; - } - break; - */ - case KD_EVENT_WINDOW_FOCUS: - case KD_EVENT_WINDOW_CLOSE: - case KD_EVENT_WINDOWPROPERTY_CHANGE: - case KD_EVENT_WINDOW_REDRAW: - if( ! ( eventMask & EVENT_WINDOW ) ) { - DBG_PRINT( "event window ignored: src: %d\n", owner); - continue; - } - break; - } - - // FIXME: support resize and window re-positioning events - - switch(evt->type) { - case KD_EVENT_WINDOW_FOCUS: - { - KDboolean hasFocus; - kdGetWindowPropertybv(w, KD_WINDOWPROPERTY_FOCUS, &hasFocus); - DBG_PRINT( "event window focus : src: %d\n", owner); - } - break; - case KD_EVENT_WINDOW_CLOSE: - { - DBG_PRINT( "event window close : src: %d\n", owner); - (*env)->CallVoidMethod(env, obj, windowDestroyNotifyID); - // Called by Window.java: DestroyWindow(wnd); - // (*env)->CallVoidMethod(env, obj, windowDestroyedID); - } - break; - case KD_EVENT_WINDOWPROPERTY_CHANGE: - { - const KDEventWindowProperty* prop = &evt->data.windowproperty; - switch (prop->pname) { - case KD_WINDOWPROPERTY_SIZE: - { - KDint32 v[2]; - if(!kdGetWindowPropertyiv(w, KD_WINDOWPROPERTY_SIZE, v)) { - DBG_PRINT( "event window size change : src: %d %dx%d\n", owner, v[0], v[1]); - (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) v[0], (jint) v[1]); - } else { - DBG_PRINT( "event window size change error: src: %d %dx%d\n", owner, v[0], v[1]); - } - } - break; - case KD_WINDOWPROPERTY_FOCUS: - DBG_PRINT( "event window focus: src: %d\n", owner); - break; - case KD_WINDOWPROPERTY_VISIBILITY: - { - KDboolean visible; - kdGetWindowPropertybv(w, KD_WINDOWPROPERTY_VISIBILITY, &visible); - DBG_PRINT( "event window visibility: src: %d, v:%d\n", owner, visible); - } - break; - default: - break; - } - } - break; - case KD_EVENT_INPUT_POINTER: - { - const KDEventInputPointer* ptr = &(evt->data.inputpointer); - // button idx: evt->data.input.index - // pressed = ev->data.input.value.i - // time = ev->timestamp - if(KD_INPUT_POINTER_SELECT==ptr->index) { - DBG_PRINT( "event mouse click: src: %d, s:%d, (%d,%d)\n", owner, ptr->select, ptr->x, ptr->y); - (*env)->CallVoidMethod(env, obj, sendMouseEventID, - (ptr->select==0) ? (jint) EVENT_MOUSE_RELEASED : (jint) EVENT_MOUSE_PRESSED, - (jint) 0, - (jint) ptr->x, (jint) ptr->y, 1, 0); - } else { - DBG_PRINT( "event mouse: src: %d, s:%d, i:0x%X (%d,%d)\n", owner, ptr->select, ptr->index, ptr->x, ptr->y); - (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, - 0, - (jint) ptr->x, (jint) ptr->y, 0, 0); - } - } - break; - } - } -} - JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_setFullScreen0 (JNIEnv *env, jobject obj, jlong window, jboolean fullscreen) { diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index f39a9f401..008a2417c 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -85,6 +85,7 @@ NS_ENDHANDLER if(NULL!=newView) { jobject globJavaWindowObject = (*env)->NewGlobalRef(env, javaWindowObject); [newView setJavaWindowObject: globJavaWindowObject]; + [newView setJNIEnv: env]; } [win setContentView: newView]; @@ -92,11 +93,11 @@ NS_ENDHANDLER } /* - * Class: com_sun_javafx_newt_macosx_MacWindow + * Class: com_sun_javafx_newt_macosx_MacDisplay * Method: initIDs * Signature: ()Z */ -JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_initIDs +JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_macosx_MacDisplay_initNSApplication (JNIEnv *env, jclass clazz) { static int initialized = 0; @@ -122,6 +123,109 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_initIDs // printf("Going to sleep for 10 seconds\n"); // sleep(10); + return (jboolean) JNI_TRUE; +} + +/* + * Class: com_sun_javafx_newt_macosx_MacDisplay + * Method: dispatchMessages0 + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacDisplay_dispatchMessages0 + (JNIEnv *env, jobject unused, jlong window, jint eventMask) +{ + NSEvent* event = NULL; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + +NS_DURING + + NSWindow* win = NULL; + NewtView* view = NULL; + int num_events = 0; + + // Periodically take a break + do { + // FIXME: ignoring event mask for the time being + event = [NSApp nextEventMatchingMask: NSAnyEventMask + untilDate: [NSDate distantPast] + inMode: NSDefaultRunLoopMode + dequeue: YES]; + if (event != NULL) { + [NSApp sendEvent: event]; + + num_events++; + } + } while (num_events<100 && event != NULL); + +NS_HANDLER + + // just ignore it .. + +NS_ENDHANDLER + + [pool release]; +} + +/* + * Class: com_sun_javafx_newt_macosx_MacScreen + * Method: getWidthImpl + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_macosx_MacScreen_getWidthImpl + (JNIEnv *env, jclass clazz, jint screen_idx) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + NSArray *screens = [NSScreen screens]; + if(screen_idx<0) screen_idx=0; + if(screen_idx>=[screens count]) screen_idx=0; + NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx]; + NSRect rect = [screen frame]; + + [pool release]; + + return (jint) (rect.size.width); +} + +/* + * Class: com_sun_javafx_newt_macosx_MacScreen + * Method: getHeightImpl + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_macosx_MacScreen_getHeightImpl + (JNIEnv *env, jclass clazz, jint screen_idx) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + NSArray *screens = [NSScreen screens]; + if(screen_idx<0) screen_idx=0; + if(screen_idx>=[screens count]) screen_idx=0; + NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx]; + NSRect rect = [screen frame]; + + [pool release]; + + return (jint) (rect.size.height); +} + +/* + * Class: com_sun_javafx_newt_macosx_MacWindow + * Method: initIDs + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_initIDs + (JNIEnv *env, jclass clazz) +{ + static int initialized = 0; + + if(initialized) return JNI_TRUE; + initialized = 1; + + // Need this when debugging, as it is necessary to attach gdb to + // the running java process -- "gdb java" doesn't work + // printf("Going to sleep for 10 seconds\n"); + // sleep(10); + return (jboolean) [NewtMacWindow initNatives: env forClass: clazz]; } @@ -280,51 +384,6 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_setTitle0 /* * Class: com_sun_javafx_newt_macosx_MacWindow - * Method: dispatchMessages0 - * Signature: (JI)V - */ -JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_dispatchMessages0 - (JNIEnv *env, jobject unused, jlong window, jint eventMask) -{ - NSEvent* event = NULL; - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - -NS_DURING - - NSWindow* win = (NSWindow *) ((intptr_t) window); - - if(NULL != win) { - NewtView* view = (NewtView *) [win contentView]; - [view setJNIEnv: env]; - - do { - // FIXME: ignoring event mask for the time being - event = [NSApp nextEventMatchingMask: NSAnyEventMask - untilDate: [NSDate distantPast] - inMode: NSDefaultRunLoopMode - dequeue: YES]; - if (event != NULL) { - win = (NSWindow*) [event window]; - view = (NewtView *) [win contentView]; - [view setJNIEnv: env]; - - [NSApp sendEvent: event]; - } - } while (event != NULL); - } - -NS_HANDLER - - // just ignore it .. - -NS_ENDHANDLER - - - [pool release]; -} - -/* - * Class: com_sun_javafx_newt_macosx_MacWindow * Method: contentView * Signature: (J)J */ @@ -386,45 +445,3 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_setFrameTopLeft [pool release]; } -/* - * Class: com_sun_javafx_newt_macosx_MacWindow - * Method: getScreenWidth - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_getScreenWidth - (JNIEnv *env, jclass clazz, jint screen_idx) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - NSArray *screens = [NSScreen screens]; - if(screen_idx<0) screen_idx=0; - if(screen_idx>=[screens count]) screen_idx=0; - NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx]; - NSRect rect = [screen frame]; - - [pool release]; - - return (jint) (rect.size.width); -} - -/* - * Class: com_sun_javafx_newt_macosx_MacWindow - * Method: getScreenHeight - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_getScreenHeight - (JNIEnv *env, jclass clazz, jint screen_idx) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - NSArray *screens = [NSScreen screens]; - if(screen_idx<0) screen_idx=0; - if(screen_idx>=[screens count]) screen_idx=0; - NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx]; - NSRect rect = [screen frame]; - - [pool release]; - - return (jint) (rect.size.height); -} - diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 908eb2ac0..67fbd3f07 100755 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -778,61 +778,34 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, } /* - * Class: com_sun_javafx_newt_windows_WindowsScreen - * Method: getScreenWidth - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsScreen_getScreenWidth - (JNIEnv *env, jobject obj, jint scrn_idx) -{ - return (jint)GetSystemMetrics(SM_CXSCREEN); -} - -/* - * Class: com_sun_javafx_newt_windows_WindowsScreen - * Method: getScreenWidth - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsScreen_getScreenHeight - (JNIEnv *env, jobject obj, jint scrn_idx) -{ - return (jint)GetSystemMetrics(SM_CYSCREEN); -} - -/* - * Class: com_sun_javafx_newt_windows_WindowsWindow - * Method: initIDs - * Signature: ()Z + * Class: com_sun_javafx_newt_windows_WindowsDisplay + * Method: DispatchMessages + * Signature: ()V */ -JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_initIDs +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsDisplay_DispatchMessages (JNIEnv *env, jclass clazz) { - sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); - positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); - focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(JZ)V"); - windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); - windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); - sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); - sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); - if (sizeChangedID == NULL || - positionChangedID == NULL || - focusChangedID == NULL || - windowDestroyNotifyID == NULL || - windowDestroyedID == NULL || - sendMouseEventID == NULL || - sendKeyEventID == NULL) { - return JNI_FALSE; - } - BuildDynamicKeyMapTable(); - return JNI_TRUE; + int i = 0; + MSG msg; + BOOL gotOne; + + // Periodically take a break + do { + gotOne = PeekMessage(&msg, (HWND) NULL, 0, 0, PM_REMOVE); + if (gotOne) { + ++i; + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } while (gotOne && i < 100); } /* - * Class: com_sun_javafx_newt_windows_WindowsWindow + * Class: com_sun_javafx_newt_windows_WindowsDisplay * Method: LoadLibraryW * Signature: (Ljava/lang/String;)J */ -JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_LoadLibraryW +JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_windows_WindowsDisplay_LoadLibraryW (JNIEnv *env, jclass clazz, jstring dllName) { jchar* _dllName = GetNullTerminatedStringChars(env, dllName); @@ -842,11 +815,11 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_LoadLibra } /* - * Class: com_sun_javafx_newt_windows_WindowsWindow + * Class: com_sun_javafx_newt_windows_WindowsDisplay * Method: RegisterWindowClass * Signature: (Ljava/lang/String;J)I */ -JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_RegisterWindowClass +JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsDisplay_RegisterWindowClass (JNIEnv *env, jclass clazz, jstring wndClassName, jlong hInstance) { ATOM res; @@ -882,17 +855,67 @@ JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_RegisterWi } /* - * Class: com_sun_javafx_newt_windows_WindowsWindow + * Class: com_sun_javafx_newt_windows_WindowsDisplay * Method: CleanupWindowResources * Signature: (java/lang/String;J)V */ -JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_CleanupWindowResources - (JNIEnv *env, jobject obj, jint wndClassAtom, jlong hInstance) +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsDisplay_UnregisterWindowClass + (JNIEnv *env, jclass clazz, jint wndClassAtom, jlong hInstance) { UnregisterClass(MAKEINTATOM(wndClassAtom), (HINSTANCE) hInstance); } /* + * Class: com_sun_javafx_newt_windows_WindowsScreen + * Method: getWidthImpl + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsScreen_getWidthImpl + (JNIEnv *env, jobject obj, jint scrn_idx) +{ + return (jint)GetSystemMetrics(SM_CXSCREEN); +} + +/* + * Class: com_sun_javafx_newt_windows_WindowsScreen + * Method: getWidthImpl + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsScreen_getHeightImpl + (JNIEnv *env, jobject obj, jint scrn_idx) +{ + return (jint)GetSystemMetrics(SM_CYSCREEN); +} + +/* + * Class: com_sun_javafx_newt_windows_WindowsWindow + * Method: initIDs + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_initIDs + (JNIEnv *env, jclass clazz) +{ + sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); + positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); + focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(JZ)V"); + windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); + windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); + sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); + sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + if (sizeChangedID == NULL || + positionChangedID == NULL || + focusChangedID == NULL || + windowDestroyNotifyID == NULL || + windowDestroyedID == NULL || + sendMouseEventID == NULL || + sendKeyEventID == NULL) { + return JNI_FALSE; + } + BuildDynamicKeyMapTable(); + return JNI_TRUE; +} + +/* * Class: com_sun_javafx_newt_windows_WindowsWindow * Method: CreateWindow * Signature: (ILjava/lang/String;JJZIIII)J @@ -1017,91 +1040,6 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_setVisible /* * Class: com_sun_javafx_newt_windows_WindowsWindow - * Method: DispatchMessages - * Signature: (JI)V - */ -JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_DispatchMessages - (JNIEnv *env, jclass clazz, jlong window, jint eventMask) -{ - int i = 0; - MSG msg; - BOOL gotOne; - WindowUserData * wud; - -#if defined(UNDER_CE) || _MSC_VER <= 1200 - wud = (WindowUserData *) GetWindowLong((HWND)window, GWL_USERDATA); -#else - wud = (WindowUserData *) GetWindowLongPtr((HWND)window, GWLP_USERDATA); -#endif - if(NULL==wud) { - fprintf(stderr, "INTERNAL ERROR in WindowsWindow::DispatchMessages window userdata NULL\n"); - exit(1); - } - - wud->jenv = env; - - if(eventMask<0) { - eventMask *= -1; - /* FIXME: re-select input mask - long xevent_mask_key = 0; - long xevent_mask_ptr = 0; - long xevent_mask_win = 0; - if( 0 != ( eventMask & EVENT_MOUSE ) ) { - xevent_mask_ptr |= ButtonPressMask|ButtonReleaseMask|PointerMotionMask; - } - if( 0 != ( eventMask & EVENT_KEY ) ) { - xevent_mask_key |= KeyPressMask|KeyReleaseMask; - } - if( 0 != ( eventMask & EVENT_WINDOW ) ) { - xevent_mask_win |= ExposureMask; - } - - XSelectInput(dpy, w, xevent_mask_win|xevent_mask_key|xevent_mask_ptr); - */ - } - - // Periodically take a break - do { - gotOne = PeekMessage(&msg, (HWND) window, 0, 0, PM_REMOVE); - if (gotOne) { - ++i; - switch (msg.message) { - case WM_CLOSE: - case WM_DESTROY: - case WM_SIZE: - if( ! ( eventMask & EVENT_WINDOW ) ) { - continue; - } - break; - - case WM_CHAR: - case WM_KEYDOWN: - case WM_KEYUP: - if( ! ( eventMask & EVENT_KEY ) ) { - continue; - } - break; - - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_MOUSEMOVE: - if( ! ( eventMask & EVENT_MOUSE ) ) { - continue; - } - break; - } - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } while (gotOne && i < 100); -} - -/* - * Class: com_sun_javafx_newt_windows_WindowsWindow * Method: setSize0 * Signature: (JII)V */ diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index c3d446f09..7ca3afe72 100755 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -34,6 +34,8 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <stdarg.h> +#include <stdint.h> #include <unistd.h> #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -48,7 +50,7 @@ // #define VERBOSE_ON 1 #ifdef VERBOSE_ON - #define DBG_PRINT(args...) fprintf(stderr, args) + #define DBG_PRINT(args...) fprintf(stderr, args); fflush(stderr); #define DUMP_VISUAL_INFO(a,b) _dumpVisualInfo((a),(b)) @@ -121,12 +123,89 @@ static jint X11KeySym2NewtVKey(KeySym keySym) { return keySym; } +static const char * const ClazzNameRuntimeException = + "java/lang/RuntimeException"; +static jclass runtimeExceptionClz=NULL; + +static const char * const ClazzNameNewtWindow = + "com/sun/javafx/newt/Window"; +static jclass newtWindowClz=NULL; + +static jmethodID sizeChangedID = NULL; +static jmethodID positionChangedID = NULL; +static jmethodID windowDestroyNotifyID = NULL; +static jmethodID windowDestroyedID = NULL; +static jmethodID windowCreatedID = NULL; +static jmethodID sendMouseEventID = NULL; +static jmethodID sendKeyEventID = NULL; + +static jmethodID displayCreatedID = NULL; + +static void _throwNewRuntimeException(JNIEnv *env, const char* msg, ...) +{ + char buffer[512]; + va_list ap; + + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); + + (*env)->ThrowNew(env, runtimeExceptionClz, buffer); +} + /** * Display */ /* * Class: com_sun_javafx_newt_x11_X11Display + * Method: initIDs + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Display_initIDs + (JNIEnv *env, jclass clazz) +{ + jclass c; + + displayCreatedID = (*env)->GetMethodID(env, clazz, "displayCreated", "(JJ)V"); + if (displayCreatedID == NULL) { + return JNI_FALSE; + } + + if(NULL==newtWindowClz) { + c = (*env)->FindClass(env, ClazzNameNewtWindow); + if(NULL==c) { + fprintf(stderr, "FatalError: NEWT X11Window: can't find %s\n", ClazzNameNewtWindow); + return JNI_FALSE; + } + newtWindowClz = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==newtWindowClz) { + fprintf(stderr, "FatalError: NEWT X11Window: can't use %s\n", ClazzNameNewtWindow); + return JNI_FALSE; + } + } + + if(NULL==runtimeExceptionClz) { + c = (*env)->FindClass(env, ClazzNameRuntimeException); + if(NULL==c) { + fprintf(stderr, "FatalError: NEWT X11Window: can't find %s\n", ClazzNameRuntimeException); + return JNI_FALSE; + } + runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==runtimeExceptionClz) { + fprintf(stderr, "FatalError: NEWT X11Window: can't use %s\n", ClazzNameRuntimeException); + return JNI_FALSE; + } + } + + return JNI_TRUE; +} + + +/* + * Class: com_sun_javafx_newt_x11_X11Display * Method: CreateDisplay * Signature: (Ljava/lang/String;)J */ @@ -138,16 +217,229 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Display_CreateDisplay if(displayName!=0) { _displayName = (*env)->GetStringUTFChars(env, displayName, 0); } + DBG_PRINT("open display connection for %s ..\n", ((NULL==_displayName)?"NULL":_displayName)); dpy = XOpenDisplay(_displayName); + if(dpy==NULL) { + _throwNewRuntimeException(env, "couldn't open display connection for %s\n", ((NULL==_displayName)?"NULL":_displayName)); + } if(_displayName!=0) { (*env)->ReleaseStringChars(env, displayName, (const jchar *)_displayName); } - if(dpy==NULL) { - fprintf(stderr, "couldn't open display connection..\n"); + + jlong javaObjectAtom = (jlong) XInternAtom(dpy, "JOGL_JAVA_OBJECT", False); + if(None==javaObjectAtom) { + XCloseDisplay(dpy); + _throwNewRuntimeException(env, "could not create Atom JOGL_JAVA_OBJECT, bail out!\n"); + return 0; } + + jlong windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False); + if(None==windowDeleteAtom) { + XCloseDisplay(dpy); + _throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!\n"); + return 0; + } + + DBG_PRINT("X11Display_CreateDisplay dpy %p\n", dpy); + + (*env)->CallVoidMethod(env, obj, displayCreatedID, javaObjectAtom, windowDeleteAtom); + return (jlong) (intptr_t) dpy; } +/* + * Class: com_sun_javafx_newt_x11_X11Display + * Method: DestroyDisplay + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_DestroyDisplay + (JNIEnv *env, jobject obj, jlong display) +{ + Display * dpy = (Display *)(intptr_t)display; + DBG_PRINT("X11Display_DestroyDisplay dpy %p\n", dpy); + XCloseDisplay(dpy); +} + +static int putPtrIn32Long(unsigned long * dst, uintptr_t src) { + int i=0; + dst[i++] = (unsigned long) ( ( src >> 0 ) & 0xFFFFFFFF ) ; + if(sizeof(uintptr_t) == 8) { + dst[i++] = (unsigned long) ( ( src >> 32 ) & 0xFFFFFFFF ) ; + } + return i; +} + +static uintptr_t getPtrOut32Long(unsigned long * src) { + uintptr_t res = ( (uintptr_t) ( src[0] & 0xFFFFFFFF ) ) << 0 ; + if(sizeof(uintptr_t) == 8) { + res |= ( (uintptr_t) ( src[1] & 0xFFFFFFFF ) ) << 32 ; + } + return res; +} + +static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, jobject jwindow) { + unsigned long jogl_java_object_data[2]; + int nitems_32 = putPtrIn32Long( jogl_java_object_data, (uintptr_t) jwindow); + + { + 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); + } + } + + XChangeProperty( dpy, window, (Atom)javaObjectAtom, (Atom)javaObjectAtom, 32, PropModeReplace, + (unsigned char *)&jogl_java_object_data, nitems_32); +} + +static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom) { + Atom actual_type_return; + int actual_format_return; + int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ; + unsigned char * jogl_java_object_data_pp = NULL; + jobject jwindow; + + { + unsigned long nitems_return = 0; + unsigned long bytes_after_return = 0; + jobject jwindow = NULL; + int res; + + res = XGetWindowProperty(dpy, window, (Atom)javaObjectAtom, 0, nitems_32, False, + (Atom)javaObjectAtom, &actual_type_return, &actual_format_return, + &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", + 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", + 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); + } +#endif + return jwindow; +} + +/* + * Class: com_sun_javafx_newt_x11_X11Display + * Method: DispatchMessages + * Signature: (JIJJ)V + */ +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; + + // Periodically take a break + while( num_events<100 && XPending(dpy)>0 ) { + jobject jwindow = NULL; + XEvent evt; + KeySym keySym; + char keyChar; + char text[255]; + + XNextEvent(dpy, &evt); + num_events++; + + if( 0==evt.xany.window ) { + _throwNewRuntimeException(env, "event window NULL, bail out!\n"); + } + + if(dpy!=evt.xany.display) { + _throwNewRuntimeException(env, "wrong display"); + continue; + } + jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom); + if(NULL==jwindow) { + // just leave .. _throwNewRuntimeException(env, "could not fetch Java Window object, bail out!\n"); + return; + } + + // FIXME: support resize and window re-positioning events + + switch(evt.type) { + case ButtonPress: + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, + (jint) evt.xbutton.state, + (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); + break; + case ButtonRelease: + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, + (jint) evt.xbutton.state, + (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); + break; + case MotionNotify: + (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, + (jint) evt.xmotion.state, + (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); + break; + case FocusIn: + case FocusOut: + break; + case DestroyNotify: + DBG_PRINT( "event . DestroyNotify call 0x%X\n", evt.xdestroywindow.window); + (*env)->CallVoidMethod(env, jwindow, windowDestroyedID); + break; + case CreateNotify: + DBG_PRINT( "event . CreateNotify call 0x%X\n", evt.xcreatewindow.window); + (*env)->CallVoidMethod(env, jwindow, windowCreatedID); + break; + case VisibilityNotify: + DBG_PRINT( "event . VisibilityNotify call 0x%X\n", evt.xvisibility.window); + break; + case Expose: + DBG_PRINT( "event . Expose call 0x%X\n", evt.xexpose.window); + /* FIXME: Might want to send a repaint event .. */ + break; + case UnmapNotify: + DBG_PRINT( "event . UnmapNotify call 0x%X\n", evt.xunmap.window); + break; + case ClientMessage: + if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) { + DBG_PRINT( "event . ClientMessage call 0x%X type 0x%X !!!\n", evt.xclient.window, evt.xclient.message_type); + (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID); + // Called by Window.java: CloseWindow(); + } + break; + } + } +} + + /** * Screen */ @@ -195,14 +487,6 @@ JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_x11_X11Screen_getHeight0 * Window */ -static jmethodID sizeChangedID = NULL; -static jmethodID positionChangedID = NULL; -static jmethodID windowDestroyNotifyID = NULL; -static jmethodID windowDestroyedID = NULL; -static jmethodID windowCreatedID = NULL; -static jmethodID sendMouseEventID = NULL; -static jmethodID sendKeyEventID = NULL; - /* * Class: com_sun_javafx_newt_x11_X11Window * Method: initIDs @@ -215,9 +499,10 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Window_initIDs positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); - windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(JJ)V"); + windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V"); sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + if (sizeChangedID == NULL || positionChangedID == NULL || windowDestroyNotifyID == NULL || @@ -237,7 +522,8 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Window_initIDs */ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow (JNIEnv *env, jobject obj, jlong display, jint screen_index, - jlong visualID, + jlong visualID, + jlong javaObjectAtom, jlong windowDeleteAtom, jint x, jint y, jint width, jint height) { Display * dpy = (Display *)(intptr_t)display; @@ -283,11 +569,11 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow XFree(pVisualQuery); pVisualQuery=NULL; } - DBG_PRINT( "trying given (screen %d, visualID: %d) found: %p\n", scrn_idx, (int)visualID, visual); + DBG_PRINT( "[CreateWindow] trying given (dpy %p, screen %d, visualID: %d) found: %p\n", dpy, scrn_idx, (int)visualID, visual); if (visual==NULL) { - fprintf(stderr, "could not query Visual by given VisualID, bail out!\n"); + _throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!\n"); return 0; } @@ -320,12 +606,31 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow visual, attrMask, &xswa); - Atom wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - XSetWMProtocols(dpy, window, &wm_delete_window, 1); + + Atom wm_delete_atom = (Atom)windowDeleteAtom; + XSetWMProtocols(dpy, window, &wm_delete_atom, 1); + + setJavaWindowProperty(env, dpy, window, javaObjectAtom, (*env)->NewGlobalRef(env, obj)); + XClearWindow(dpy, window); XSync(dpy, False); - (*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) window, (jlong)wm_delete_window); + { + long xevent_mask = 0; + xevent_mask |= ButtonPressMask|ButtonReleaseMask|PointerMotionMask; + xevent_mask |= KeyPressMask|KeyReleaseMask; + xevent_mask |= ExposureMask | StructureNotifyMask | SubstructureNotifyMask | VisibilityNotify ; + XSelectInput(dpy, window, xevent_mask); + + /** + XGrabPointer(dpy, window, True, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, + GrabModeAsync, GrabModeAsync, window, None, CurrentTime); + XGrabKeyboard(dpy, window, True, GrabModeAsync, GrabModeAsync, CurrentTime); + */ + } + + DBG_PRINT( "[CreateWindow] created window %p on display %p\n", window, dpy); + (*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) window); return (jlong) window; } @@ -336,10 +641,21 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_CloseWindow - (JNIEnv *env, jobject obj, jlong display, jlong window) + (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; + jobject jwindow; + + jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom); + if(NULL==jwindow) { + _throwNewRuntimeException(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"); + } + (*env)->DeleteGlobalRef(env, jwindow); XSync(dpy, False); /** @@ -383,176 +699,6 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setVisible0 } } -/* - * Class: com_sun_javafx_newt_x11_X11Window - * Method: DispatchMessages - * Signature: (JJI)V - */ -JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_DispatchMessages - (JNIEnv *env, jobject obj, jlong display, jlong window, jint eventMask, jlong wmDeleteAtom) -{ - Display * dpy = (Display *) (intptr_t) display; - Window w = (Window)window; - Atom wm_delete_window = (Atom)wmDeleteAtom; - - if(eventMask<0) { - long xevent_mask_key = 0; - long xevent_mask_ptr = 0; - long xevent_mask_win = 0; - eventMask *= -1; - if( 0 != ( eventMask & EVENT_MOUSE ) ) { - xevent_mask_ptr |= ButtonPressMask|ButtonReleaseMask|PointerMotionMask; - } - if( 0 != ( eventMask & EVENT_KEY ) ) { - xevent_mask_key |= KeyPressMask|KeyReleaseMask; - } - if( 0 != ( eventMask & EVENT_WINDOW ) ) { - xevent_mask_win |= ExposureMask | StructureNotifyMask | SubstructureNotifyMask | VisibilityNotify ; - } - - XSelectInput(dpy, w, xevent_mask_win|xevent_mask_key|xevent_mask_ptr); - - /** - if(0!=xevent_mask_ptr) { - XGrabPointer(dpy, w, True, xevent_mask_ptr, - GrabModeAsync, GrabModeAsync, w, None, CurrentTime); - } - if(0!=xevent_mask_key) { - XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime); - } */ - - } - - // Periodically take a break - while( XPending(dpy)>0 ) { - XEvent evt; - KeySym keySym; - char keyChar; - char text[255]; - - XNextEvent(dpy, &evt); - - switch(evt.type) { - case ButtonPress: - case ButtonRelease: - case MotionNotify: - if( ! ( eventMask & EVENT_MOUSE ) ) { - continue; - } - break; - case KeyPress: - case KeyRelease: - if( ! ( eventMask & EVENT_KEY ) ) { - continue; - } - break; - case FocusIn: - case FocusOut: - break; - case DestroyNotify: - case CreateNotify: - case VisibilityNotify: - case Expose: - case UnmapNotify: - if( ! ( eventMask & EVENT_WINDOW ) ) { - continue; - } - break; - } - - // FIXME: support resize and window re-positioning events - - switch(evt.type) { - case ButtonPress: - if(evt.xbutton.window==w) { - (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, - (jint) evt.xbutton.state, - (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); - } - break; - case ButtonRelease: - if(evt.xbutton.window==w) { - (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED, - (jint) evt.xbutton.state, - (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/); - } - break; - case MotionNotify: - if(evt.xmotion.window==w) { - (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, - (jint) evt.xmotion.state, - (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/); - } - break; - case KeyPress: - if(evt.xkey.window==w) { - if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) { - keyChar=text[0]; - } else { - keyChar=0; - } - (*env)->CallVoidMethod(env, obj, sendKeyEventID, (jint) EVENT_KEY_PRESSED, - (jint) evt.xkey.state, - X11KeySym2NewtVKey(keySym), (jchar) keyChar); - } - break; - case KeyRelease: - if(evt.xkey.window==w) { - if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) { - keyChar=text[0]; - } else { - keyChar=0; - } - (*env)->CallVoidMethod(env, obj, sendKeyEventID, (jint) EVENT_KEY_RELEASED, - (jint) evt.xkey.state, - X11KeySym2NewtVKey(keySym), (jchar) keyChar); - } - break; - case FocusIn: - case FocusOut: - if(evt.xfocus.window==w) { - } - break; - case DestroyNotify: - if(evt.xdestroywindow.window==w) { - DBG_PRINT( "event . DestroyNotify call 0x%X\n", evt.xdestroywindow.window); - (*env)->CallVoidMethod(env, obj, windowDestroyedID); - } - break; - case CreateNotify: - if(evt.xcreatewindow.window==w) { - DBG_PRINT( "event . DestroyNotify call 0x%X\n", evt.xcreatewindow.window); - (*env)->CallVoidMethod(env, obj, windowCreatedID); - } - break; - case VisibilityNotify: - if(evt.xvisibility.window==w) { - DBG_PRINT( "event . VisibilityNotify call 0x%X\n", evt.xvisibility.window); - } - break; - case Expose: - if(evt.xexpose.window==w) { - DBG_PRINT( "event . Expose call 0x%X\n", evt.xexpose.window); - /* FIXME: Might want to send a repaint event .. */ - } - break; - case UnmapNotify: - if(evt.xunmap.window==w) { - DBG_PRINT( "event . UnmapNotify call 0x%X\n", evt.xunmap.window); - } - break; - case ClientMessage: - if (evt.xclient.window==w && evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_window) { - DBG_PRINT( "event . ClientMessage call 0x%X type 0x%X !!!\n", evt.xclient.window, evt.xclient.message_type); - (*env)->CallVoidMethod(env, obj, windowDestroyNotifyID); - // Called by Window.java: CloseWindow(); - } - break; - - } - } -} - #define MWM_FULLSCREEN 1 #ifdef MWM_FULLSCREEN @@ -612,7 +758,13 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setSize0 XSync(dpy, False); /** if(isVisible==JNI_TRUE) { + // this .. XSetInputFocus(dpy, w, RevertToNone, CurrentTime); + + // or this .. + unsigned long wmleader[1] = { (unsigned long) w}; + Atom prop = XInternAtom( dpy, "WM_CLIENT_LEADER", False ); + XChangeProperty( dpy, w, prop, prop, 32, PropModeReplace, (unsigned char *)&wmleader, 1); } */ DBG_PRINT( "setSize0 . sizeChangedID call\n"); |